aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2021-01-13 23:50:35 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2021-01-13 23:50:35 +0000
commitd236ac0c894116ee49e75a866fffddbdd08e3618 (patch)
tree31e2d4ecf7e1a9f628b4c06a9636f55b8b489e5b
parent912d7566fbedac9941027018108144b9de12c2b3 (diff)
parent4ae7c6ee6aa6ded74f79633e3de2577e3f913ee7 (diff)
downloadflatbuffers-android11-mainline-conscrypt-release.tar.gz
Snap for 7080740 from 4ae7c6ee6aa6ded74f79633e3de2577e3f913ee7 to mainline-conscrypt-releaseandroid-mainline-11.0.0_r31android-mainline-11.0.0_r20android11-mainline-conscrypt-release
Change-Id: I7f4ade9580cee2d75def2ecd2224491049e975f8
-rw-r--r--.appveyor/check-generate-code.bat1
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md6
-rw-r--r--.github/stale.yml18
-rw-r--r--.gitignore9
-rw-r--r--.travis.yml47
-rwxr-xr-x.travis/build-and-run-docker-test-containers.sh13
-rwxr-xr-x.travis/check-generate-code.sh2
-rw-r--r--Android.bp92
-rw-r--r--BUILD148
-rw-r--r--CMakeLists.txt254
-rw-r--r--LICENSE.txt2
-rw-r--r--METADATA9
-rw-r--r--TEST_MAPPING10
-rw-r--r--WORKSPACE9
-rw-r--r--android/jni/Android.mk7
-rw-r--r--android/jni/main.cpp5
-rw-r--r--appveyor.yml36
-rw-r--r--build_defs.bzl46
-rw-r--r--dart/lib/flat_buffers.dart6
-rw-r--r--dart/pubspec.yaml2
-rw-r--r--dart/test/monster_test_my_game.example_generated.dart92
-rw-r--r--docs/source/Building.md13
-rw-r--r--docs/source/Compiler.md25
-rw-r--r--docs/source/CppUsage.md64
-rw-r--r--docs/source/CsharpUsage.md175
-rw-r--r--docs/source/FlatBuffers.md18
-rw-r--r--docs/source/FlexBuffers.md52
-rw-r--r--docs/source/Internals.md6
-rw-r--r--docs/source/JavaUsage.md (renamed from docs/source/JavaCsharpUsage.md)86
-rw-r--r--docs/source/KotlinUsage.md84
-rw-r--r--docs/source/Schemas.md37
-rw-r--r--docs/source/Support.md36
-rw-r--r--docs/source/SwiftUsage.md91
-rw-r--r--docs/source/Tutorial.md497
-rw-r--r--docs/source/TypeScriptUsage.md2
-rw-r--r--docs/source/doxyfile2
-rw-r--r--docs/source/doxygen_layout.xml8
-rw-r--r--go/BUILD.bazel6
-rw-r--r--go/builder.go17
-rw-r--r--go/grpc.go15
-rwxr-xr-xgrpc/build_grpc.sh2
-rw-r--r--grpc/flatbuffers-java-grpc/pom.xml4
-rw-r--r--grpc/pom.xml2
-rw-r--r--grpc/samples/greeter/server.cpp3
-rw-r--r--grpc/src/compiler/BUILD107
-rw-r--r--grpc/src/compiler/java_generator.cc2
-rw-r--r--grpc/src/compiler/python_generator.cc624
-rw-r--r--grpc/src/compiler/python_generator.h40
-rw-r--r--grpc/src/compiler/python_private_generator.h72
-rw-r--r--grpc/src/compiler/schema_interface.h42
-rw-r--r--grpc/src/compiler/swift_generator.cc308
-rw-r--r--grpc/src/compiler/swift_generator.h55
-rw-r--r--grpc/tests/JavaGrpcTest.java6
-rw-r--r--grpc/tests/grpctest.cpp16
-rw-r--r--grpc/tests/grpctest.py174
-rw-r--r--grpc/tests/message_builder_test.cpp211
-rw-r--r--grpc/tests/pom.xml4
-rw-r--r--include/flatbuffers/base.h43
-rw-r--r--include/flatbuffers/code_generators.h42
-rw-r--r--include/flatbuffers/flatbuffers.h392
-rw-r--r--include/flatbuffers/flatc.h12
-rw-r--r--include/flatbuffers/flexbuffers.h145
-rw-r--r--include/flatbuffers/grpc.h44
-rw-r--r--include/flatbuffers/hash.h8
-rw-r--r--include/flatbuffers/idl.h450
-rw-r--r--include/flatbuffers/minireflect.h3
-rw-r--r--include/flatbuffers/reflection.h2
-rw-r--r--include/flatbuffers/reflection_generated.h272
-rw-r--r--include/flatbuffers/stl_emulation.h36
-rw-r--r--include/flatbuffers/util.h39
-rw-r--r--java/com/google/flatbuffers/ArrayReadWriteBuf.java241
-rw-r--r--java/com/google/flatbuffers/BaseVector.java96
-rw-r--r--java/com/google/flatbuffers/BooleanVector.java49
-rw-r--r--java/com/google/flatbuffers/ByteBufferReadWriteBuf.java165
-rw-r--r--java/com/google/flatbuffers/ByteVector.java60
-rw-r--r--java/com/google/flatbuffers/Constants.java8
-rw-r--r--java/com/google/flatbuffers/DoubleVector.java49
-rw-r--r--java/com/google/flatbuffers/FlatBufferBuilder.java54
-rw-r--r--java/com/google/flatbuffers/FlexBuffers.java1102
-rw-r--r--java/com/google/flatbuffers/FlexBuffersBuilder.java770
-rw-r--r--java/com/google/flatbuffers/FloatVector.java49
-rw-r--r--java/com/google/flatbuffers/IntVector.java60
-rw-r--r--java/com/google/flatbuffers/LongVector.java49
-rw-r--r--java/com/google/flatbuffers/ReadBuf.java81
-rw-r--r--java/com/google/flatbuffers/ReadWriteBuf.java135
-rw-r--r--java/com/google/flatbuffers/ShortVector.java60
-rw-r--r--java/com/google/flatbuffers/StringVector.java52
-rw-r--r--java/com/google/flatbuffers/Struct.java18
-rw-r--r--java/com/google/flatbuffers/Table.java77
-rw-r--r--java/com/google/flatbuffers/UnionVector.java52
-rw-r--r--java/com/google/flatbuffers/Utf8.java8
-rw-r--r--java/com/google/flatbuffers/Utf8Old.java2
-rw-r--r--java/com/google/flatbuffers/Utf8Safe.java4
-rw-r--r--js/flatbuffers.js47
-rw-r--r--lobster/flatbuffers.lobster98
-rw-r--r--lua/flatbuffers/builder.lua59
-rw-r--r--lua/flatbuffers/numTypes.lua27
-rw-r--r--lua/flatbuffers/view.lua65
-rw-r--r--net/FlatBuffers/FlatBufferBuilder.cs44
-rw-r--r--net/FlatBuffers/FlatBufferConstants.cs8
-rw-r--r--net/FlatBuffers/Struct.cs11
-rw-r--r--net/FlatBuffers/Table.cs27
-rw-r--r--package.json2
-rw-r--r--pom.xml7
-rw-r--r--python/flatbuffers/__init__.py1
-rw-r--r--python/flatbuffers/builder.py118
-rw-r--r--python/flatbuffers/encode.py2
-rw-r--r--python/flatbuffers/util.py15
-rw-r--r--python/setup.py20
-rw-r--r--readme.md6
-rw-r--r--reflection/generate_code.bat2
-rwxr-xr-xreflection/generate_code.sh15
-rw-r--r--reflection/reflection.fbs7
-rw-r--r--rust/flatbuffers/Cargo.toml4
-rw-r--r--rust/flatbuffers/src/builder.rs156
-rw-r--r--rust/flatbuffers/src/endian_scalar.rs9
-rw-r--r--rust/flatbuffers/src/lib.rs8
-rw-r--r--rust/flatbuffers/src/primitives.rs49
-rw-r--r--rust/flatbuffers/src/push.rs5
-rw-r--r--rust/flatbuffers/src/table.rs4
-rw-r--r--rust/flatbuffers/src/vector.rs155
-rw-r--r--rust/flatbuffers/src/vtable.rs6
-rw-r--r--rust/flatbuffers/src/vtable_writer.rs7
-rw-r--r--samples/SampleBinary.java6
-rw-r--r--samples/SampleBinary.kt108
-rw-r--r--samples/android/jni/main.cpp4
-rwxr-xr-xsamples/kotlin_sample.sh60
-rw-r--r--samples/monster_generated.h197
-rw-r--r--samples/monster_generated.lobster166
-rw-r--r--samples/sample_bfbs.cpp7
-rw-r--r--samples/sample_binary.cpp2
-rw-r--r--samples/sample_binary.lobster36
-rw-r--r--samples/sample_binary.swift68
-rw-r--r--samples/sample_text.cpp3
-rw-r--r--samples/sample_text.lobster12
-rw-r--r--snap/snapcraft.yaml5
-rw-r--r--src/BUILD75
-rw-r--r--src/clang-format-all.sh6
-rw-r--r--src/clang-format-git.sh6
-rw-r--r--src/clang-format.sh2
-rw-r--r--src/code_generators.cpp107
-rw-r--r--src/flatc.cpp268
-rw-r--r--src/flatc_main.cpp67
-rw-r--r--src/flathash.cpp4
-rw-r--r--src/idl_gen_cpp.cpp772
-rw-r--r--src/idl_gen_csharp.cpp2021
-rw-r--r--src/idl_gen_dart.cpp265
-rw-r--r--src/idl_gen_fbs.cpp26
-rw-r--r--src/idl_gen_general.cpp1592
-rw-r--r--src/idl_gen_go.cpp628
-rw-r--r--src/idl_gen_grpc.cpp120
-rw-r--r--src/idl_gen_java.cpp1237
-rw-r--r--src/idl_gen_js_ts.cpp227
-rw-r--r--src/idl_gen_json_schema.cpp40
-rw-r--r--src/idl_gen_kotlin.cpp1442
-rw-r--r--src/idl_gen_lobster.cpp154
-rw-r--r--src/idl_gen_lua.cpp1265
-rw-r--r--src/idl_gen_php.cpp30
-rw-r--r--src/idl_gen_python.cpp1221
-rw-r--r--src/idl_gen_rust.cpp741
-rw-r--r--src/idl_gen_swift.cpp902
-rw-r--r--src/idl_gen_text.cpp515
-rw-r--r--src/idl_parser.cpp1076
-rw-r--r--src/reflection.cpp114
-rw-r--r--src/util.cpp39
-rw-r--r--swift/FlatBuffers.podspec21
-rw-r--r--swift/LICENSE (renamed from NOTICE)4
-rw-r--r--swift/Package.swift22
-rw-r--r--swift/README.md10
-rw-r--r--swift/Sources/FlatBuffers/ByteBuffer.swift273
-rw-r--r--swift/Sources/FlatBuffers/Constants.swift91
-rw-r--r--swift/Sources/FlatBuffers/FlatBufferBuilder.swift492
-rw-r--r--swift/Sources/FlatBuffers/FlatBufferObject.swift88
-rw-r--r--swift/Sources/FlatBuffers/FlatBuffersUtils.swift16
-rw-r--r--swift/Sources/FlatBuffers/Int+extension.swift31
-rw-r--r--swift/Sources/FlatBuffers/Message.swift41
-rw-r--r--swift/Sources/FlatBuffers/Offset.swift12
-rw-r--r--swift/Sources/FlatBuffers/Struct.swift16
-rw-r--r--swift/Sources/FlatBuffers/Table.swift144
-rw-r--r--tests/BUILD110
-rw-r--r--tests/FlatBuffers.Benchmarks.swift/Package.swift19
-rw-r--r--tests/FlatBuffers.Benchmarks.swift/Sources/FlatBuffers.Benchmarks.swift/main.swift75
-rw-r--r--tests/FlatBuffers.GRPC.Swift/Package.swift49
-rw-r--r--tests/FlatBuffers.GRPC.Swift/README.md3
-rw-r--r--tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.fbs17
-rw-r--r--tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.grpc.swift73
-rw-r--r--tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter_generated.swift80
-rw-r--r--tests/FlatBuffers.GRPC.Swift/Sources/client/main.swift101
-rw-r--r--tests/FlatBuffers.GRPC.Swift/Sources/server/main.swift93
-rw-r--r--tests/FlatBuffers.Test.Swift/Package.swift20
-rw-r--r--tests/FlatBuffers.Test.Swift/SwiftTest.sh10
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift190
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersStructsTests.swift187
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersTests.swift120
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersUnionTests.swift228
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift116
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersDoubleTests.swift76
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/XCTestManifests.swift95
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test_generated.swift718
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift126
-rw-r--r--tests/FlatBuffers.Test.Swift/Tests/LinuxMain.swift8
-rw-r--r--tests/FlatBuffers.Test.Swift/monsterdata_test.monbin0 -> 440 bytes
-rw-r--r--tests/FlatBuffers.Test/FlatBufferBuilderTests.cs2
-rw-r--r--tests/FlatBuffers.Test/FlatBuffers.Test.csproj53
-rw-r--r--tests/FlatBuffers.Test/FlatBuffersExampleTests.cs520
-rw-r--r--tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs83
-rw-r--r--tests/FlatBuffers.Test/NetTest.sh40
-rw-r--r--tests/FlatBuffers.Test/Resources/.gitkeep0
-rw-r--r--tests/FlatBuffers.Test/Resources/monsterdata_test.monbin448 -> 0 bytes
-rw-r--r--tests/FlatBuffers.Test/TestTable.cs3
-rw-r--r--tests/FlatBuffers.Test/packages.config4
-rwxr-xr-xtests/GoTest.sh6
-rw-r--r--tests/JavaScriptTest.js6
-rw-r--r--tests/JavaTest.java751
-rwxr-xr-xtests/JavaTest.sh2
-rw-r--r--tests/KotlinTest.kt460
-rwxr-xr-xtests/KotlinTest.sh46
-rwxr-xr-xtests/LuaTest.sh22
-rw-r--r--tests/MyGame/Example/Ability.cs36
-rw-r--r--tests/MyGame/Example/Ability.go21
-rw-r--r--tests/MyGame/Example/Ability.java9
-rw-r--r--tests/MyGame/Example/Ability.kt32
-rw-r--r--tests/MyGame/Example/Ability.py33
-rw-r--r--tests/MyGame/Example/Any.cs76
-rw-r--r--tests/MyGame/Example/Any.go71
-rw-r--r--tests/MyGame/Example/Any.kt16
-rw-r--r--tests/MyGame/Example/Any.py15
-rw-r--r--tests/MyGame/Example/AnyAmbiguousAliases.cs76
-rw-r--r--tests/MyGame/Example/AnyAmbiguousAliases.go71
-rw-r--r--tests/MyGame/Example/AnyAmbiguousAliases.kt16
-rw-r--r--tests/MyGame/Example/AnyAmbiguousAliases.py15
-rw-r--r--tests/MyGame/Example/AnyUniqueAliases.cs76
-rw-r--r--tests/MyGame/Example/AnyUniqueAliases.go73
-rw-r--r--tests/MyGame/Example/AnyUniqueAliases.java4
-rw-r--r--tests/MyGame/Example/AnyUniqueAliases.kt16
-rw-r--r--tests/MyGame/Example/AnyUniqueAliases.lua2
-rw-r--r--tests/MyGame/Example/AnyUniqueAliases.php4
-rw-r--r--tests/MyGame/Example/AnyUniqueAliases.py17
-rw-r--r--tests/MyGame/Example/ArrayStruct.cs128
-rw-r--r--tests/MyGame/Example/ArrayStruct.java64
-rw-r--r--tests/MyGame/Example/ArrayStruct.py148
-rw-r--r--tests/MyGame/Example/ArrayTable.cs75
-rw-r--r--tests/MyGame/Example/ArrayTable.java38
-rw-r--r--tests/MyGame/Example/ArrayTable.py80
-rw-r--r--tests/MyGame/Example/Color.cs14
-rw-r--r--tests/MyGame/Example/Color.go31
-rw-r--r--tests/MyGame/Example/Color.java10
-rw-r--r--tests/MyGame/Example/Color.kt25
-rw-r--r--tests/MyGame/Example/Color.lua4
-rw-r--r--tests/MyGame/Example/Color.php4
-rw-r--r--tests/MyGame/Example/Color.py4
-rw-r--r--tests/MyGame/Example/Monster.cs598
-rw-r--r--tests/MyGame/Example/Monster.go497
-rw-r--r--tests/MyGame/Example/Monster.java142
-rw-r--r--tests/MyGame/Example/Monster.kt989
-rw-r--r--tests/MyGame/Example/Monster.lua22
-rw-r--r--tests/MyGame/Example/Monster.php54
-rw-r--r--tests/MyGame/Example/Monster.py616
-rw-r--r--tests/MyGame/Example/MonsterStorageGrpc.java2
-rw-r--r--tests/MyGame/Example/NestedStruct.cs91
-rw-r--r--tests/MyGame/Example/NestedStruct.java47
-rw-r--r--tests/MyGame/Example/NestedStruct.py128
-rw-r--r--tests/MyGame/Example/Race.cs18
-rw-r--r--tests/MyGame/Example/Race.go35
-rw-r--r--tests/MyGame/Example/Race.java16
-rw-r--r--tests/MyGame/Example/Race.kt16
-rw-r--r--tests/MyGame/Example/Race.lua12
-rw-r--r--tests/MyGame/Example/Race.php27
-rw-r--r--tests/MyGame/Example/Race.py10
-rw-r--r--tests/MyGame/Example/Referrable.cs41
-rw-r--r--tests/MyGame/Example/Referrable.go22
-rw-r--r--tests/MyGame/Example/Referrable.java18
-rw-r--r--tests/MyGame/Example/Referrable.kt80
-rw-r--r--tests/MyGame/Example/Referrable.py38
-rw-r--r--tests/MyGame/Example/Stat.cs53
-rw-r--r--tests/MyGame/Example/Stat.go29
-rw-r--r--tests/MyGame/Example/Stat.java16
-rw-r--r--tests/MyGame/Example/Stat.kt78
-rw-r--r--tests/MyGame/Example/Stat.py47
-rw-r--r--tests/MyGame/Example/Test.cs36
-rw-r--r--tests/MyGame/Example/Test.go21
-rw-r--r--tests/MyGame/Example/Test.java9
-rw-r--r--tests/MyGame/Example/Test.kt33
-rw-r--r--tests/MyGame/Example/Test.py33
-rw-r--r--tests/MyGame/Example/TestEnum.cs17
-rw-r--r--tests/MyGame/Example/TestEnum.java15
-rw-r--r--tests/MyGame/Example/TestEnum.kt14
-rw-r--r--tests/MyGame/Example/TestEnum.py9
-rw-r--r--tests/MyGame/Example/TestSimpleTableWithEnum.cs48
-rw-r--r--tests/MyGame/Example/TestSimpleTableWithEnum.go30
-rw-r--r--tests/MyGame/Example/TestSimpleTableWithEnum.java24
-rw-r--r--tests/MyGame/Example/TestSimpleTableWithEnum.kt53
-rw-r--r--tests/MyGame/Example/TestSimpleTableWithEnum.lua4
-rw-r--r--tests/MyGame/Example/TestSimpleTableWithEnum.php8
-rw-r--r--tests/MyGame/Example/TestSimpleTableWithEnum.py42
-rw-r--r--tests/MyGame/Example/TypeAliases.cs111
-rw-r--r--tests/MyGame/Example/TypeAliases.go81
-rw-r--r--tests/MyGame/Example/TypeAliases.java23
-rw-r--r--tests/MyGame/Example/TypeAliases.kt263
-rw-r--r--tests/MyGame/Example/TypeAliases.py115
-rw-r--r--tests/MyGame/Example/Vec3.cs65
-rw-r--r--tests/MyGame/Example/Vec3.go37
-rw-r--r--tests/MyGame/Example/Vec3.java21
-rw-r--r--tests/MyGame/Example/Vec3.kt50
-rw-r--r--tests/MyGame/Example/Vec3.lua4
-rw-r--r--tests/MyGame/Example/Vec3.php6
-rw-r--r--tests/MyGame/Example/Vec3.py51
-rw-r--r--tests/MyGame/Example/monster_test_grpc_fb.py241
-rw-r--r--tests/MyGame/Example2/Monster.cs31
-rw-r--r--tests/MyGame/Example2/Monster.go19
-rw-r--r--tests/MyGame/Example2/Monster.java14
-rw-r--r--tests/MyGame/Example2/Monster.kt33
-rw-r--r--tests/MyGame/Example2/Monster.py36
-rw-r--r--tests/MyGame/InParentNamespace.cs31
-rw-r--r--tests/MyGame/InParentNamespace.go19
-rw-r--r--tests/MyGame/InParentNamespace.java14
-rw-r--r--tests/MyGame/InParentNamespace.kt33
-rw-r--r--tests/MyGame/InParentNamespace.py36
-rw-r--r--tests/MyGame/MonsterExtra.cs215
-rw-r--r--tests/MyGame/MonsterExtra.java113
-rw-r--r--tests/MyGame/MonsterExtra.kt234
-rw-r--r--tests/MyGame/MonsterExtra.py217
-rwxr-xr-xtests/PythonTest.sh2
-rw-r--r--tests/TestAll.sh8
-rw-r--r--tests/arrays_test.bfbsbin0 -> 1184 bytes
-rw-r--r--tests/arrays_test.fbs27
-rw-r--r--tests/arrays_test.golden23
-rw-r--r--tests/arrays_test.schema.json73
-rw-r--r--tests/arrays_test_generated.h459
-rw-r--r--tests/cpp17/generated_cpp17/monster_test_generated.h3359
-rw-r--r--tests/cpp17/test_cpp17.cpp78
-rw-r--r--tests/docker/Dockerfile.testing.cpp.debian_buster10
-rwxr-xr-xtests/docker/build_flatc.run.sh15
-rwxr-xr-xtests/docker/cpp_test.run.sh20
-rw-r--r--tests/docker/languages/Dockerfile.testing.python.numpy.cpython_2_7_159
-rw-r--r--tests/docker/languages/Dockerfile.testing.python.numpy.cpython_3_7_19
-rw-r--r--tests/docker/languages/Dockerfile.testing.rust.1_37_0 (renamed from tests/docker/languages/Dockerfile.testing.rust.1_30_1)2
-rw-r--r--tests/docker/languages/Dockerfile.testing.rust.big_endian.1_37_0 (renamed from tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1)2
-rw-r--r--tests/docker/languages/Dockerfile.testing.swift_5_18
-rw-r--r--tests/evolution_test/evolution_v1.fbs39
-rw-r--r--tests/evolution_test/evolution_v1.json26
-rw-r--r--tests/evolution_test/evolution_v1_generated.h453
-rw-r--r--tests/evolution_test/evolution_v2.fbs50
-rw-r--r--tests/evolution_test/evolution_v2.json34
-rw-r--r--tests/evolution_test/evolution_v2_generated.h578
-rw-r--r--tests/fuzzer/CMakeLists.txt2
-rw-r--r--tests/fuzzer/test_init.h6
-rw-r--r--tests/generate_code.bat55
-rwxr-xr-xtests/generate_code.sh58
-rw-r--r--tests/go_test.go125
-rw-r--r--tests/include_test/include_test1_generated.rs87
-rw-r--r--tests/include_test/sub/include_test2_generated.rs222
-rw-r--r--tests/lobstertest.lobster45
-rw-r--r--tests/luatest.lua85
-rw-r--r--tests/monster_extra.fbs24
-rw-r--r--tests/monster_extra_generated.h394
-rw-r--r--tests/monster_extra_my_game_generated.dart176
-rw-r--r--tests/monster_test.bfbsbin11624 -> 12176 bytes
-rw-r--r--tests/monster_test.fbs22
-rw-r--r--tests/monster_test.schema.json323
-rw-r--r--tests/monster_test_bfbs_generated.h640
-rw-r--r--tests/monster_test_generated.h917
-rw-r--r--tests/monster_test_generated.js254
-rw-r--r--tests/monster_test_generated.lobster809
-rw-r--r--tests/monster_test_generated.rs186
-rw-r--r--tests/monster_test_generated.ts241
-rw-r--r--tests/monster_test_my_game.example_generated.dart94
-rw-r--r--tests/monsterdata_extra.json15
-rw-r--r--tests/monsterdata_python_wire.monbin344 -> 344 bytes
-rw-r--r--tests/monsterdata_test.golden3
-rw-r--r--tests/monsterdata_test.json4
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs7
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go23
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt15
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs36
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go21
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java9
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt32
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py33
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs40
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go22
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java16
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt53
-rw-r--r--tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py34
-rw-r--r--tests/namespace_test/NamespaceA/SecondTableInA.cs41
-rw-r--r--tests/namespace_test/NamespaceA/SecondTableInA.go23
-rw-r--r--tests/namespace_test/NamespaceA/SecondTableInA.java16
-rw-r--r--tests/namespace_test/NamespaceA/SecondTableInA.kt48
-rw-r--r--tests/namespace_test/NamespaceA/SecondTableInA.py43
-rw-r--r--tests/namespace_test/NamespaceA/TableInFirstNS.cs47
-rw-r--r--tests/namespace_test/NamespaceA/TableInFirstNS.go42
-rw-r--r--tests/namespace_test/NamespaceA/TableInFirstNS.java14
-rw-r--r--tests/namespace_test/NamespaceA/TableInFirstNS.kt68
-rw-r--r--tests/namespace_test/NamespaceA/TableInFirstNS.py53
-rw-r--r--tests/namespace_test/NamespaceC/TableInC.cs47
-rw-r--r--tests/namespace_test/NamespaceC/TableInC.go27
-rw-r--r--tests/namespace_test/NamespaceC/TableInC.java16
-rw-r--r--tests/namespace_test/NamespaceC/TableInC.kt59
-rw-r--r--tests/namespace_test/NamespaceC/TableInC.py51
-rw-r--r--tests/namespace_test/namespace_test1_generated.h76
-rw-r--r--tests/namespace_test/namespace_test1_generated.js16
-rw-r--r--tests/namespace_test/namespace_test1_generated.lobster47
-rw-r--r--tests/namespace_test/namespace_test1_generated.rs8
-rw-r--r--tests/namespace_test/namespace_test1_generated.ts12
-rw-r--r--tests/namespace_test/namespace_test2_generated.h192
-rw-r--r--tests/namespace_test/namespace_test2_generated.js30
-rw-r--r--tests/namespace_test/namespace_test2_generated.lobster118
-rw-r--r--tests/namespace_test/namespace_test2_generated.rs3
-rw-r--r--tests/namespace_test/namespace_test2_generated.ts46
-rw-r--r--tests/namespace_test/namespace_test2_namespace_a_generated.dart1
-rw-r--r--tests/namespace_test/namespace_test2_namespace_c_generated.dart1
-rw-r--r--tests/native_type_test.fbs15
-rw-r--r--tests/native_type_test_generated.h241
-rw-r--r--tests/native_type_test_impl.cpp13
-rw-r--r--tests/native_type_test_impl.h32
-rw-r--r--tests/prototest/test_include.golden57
-rw-r--r--tests/prototest/test_suffix.golden59
-rw-r--r--tests/prototest/test_union_include.golden61
-rw-r--r--tests/prototest/test_union_suffix.golden63
-rw-r--r--tests/py_test.py736
-rw-r--r--tests/rust_usage_test/Cargo.toml1
-rw-r--r--tests/rust_usage_test/benches/flatbuffers_benchmarks.rs8
-rw-r--r--tests/rust_usage_test/bin/alloc_check.rs23
-rw-r--r--tests/rust_usage_test/bin/monster_example.rs9
-rw-r--r--tests/rust_usage_test/tests/integration_test.rs201
-rw-r--r--tests/test.cpp972
-rw-r--r--tests/test_assert.cpp43
-rw-r--r--tests/test_assert.h69
-rw-r--r--tests/test_builder.cpp98
-rw-r--r--tests/test_builder.h126
-rw-r--r--tests/unicode_test.json4
-rw-r--r--tests/union_vector/Attacker.cs34
-rw-r--r--tests/union_vector/Attacker.java16
-rw-r--r--tests/union_vector/Attacker.kt51
-rw-r--r--tests/union_vector/BookReader.cs27
-rw-r--r--tests/union_vector/BookReader.java9
-rw-r--r--tests/union_vector/BookReader.kt27
-rw-r--r--tests/union_vector/Character.cs91
-rw-r--r--tests/union_vector/Character.kt17
-rw-r--r--tests/union_vector/Movie.cs159
-rw-r--r--tests/union_vector/Movie.java26
-rw-r--r--tests/union_vector/Movie.kt114
-rw-r--r--tests/union_vector/Rapunzel.cs27
-rw-r--r--tests/union_vector/Rapunzel.java9
-rw-r--r--tests/union_vector/Rapunzel.kt27
-rw-r--r--tests/union_vector/union_vector_generated.h49
-rw-r--r--tests/union_vector/union_vector_generated.js57
-rw-r--r--tests/union_vector/union_vector_generated.ts47
448 files changed, 45586 insertions, 7986 deletions
diff --git a/.appveyor/check-generate-code.bat b/.appveyor/check-generate-code.bat
index 053c8b12..ba7398a2 100644
--- a/.appveyor/check-generate-code.bat
+++ b/.appveyor/check-generate-code.bat
@@ -19,6 +19,7 @@ call generate_code.bat -b %buildtype% || goto FAIL
:: TODO: Release and Debug builds produce differences here for some reason.
git checkout HEAD -- monster_test.bfbs
+git checkout HEAD -- arrays_test.bfbs
git -c core.autocrlf=true diff --exit-code --quiet || goto :DIFFFOUND
goto SUCCESS
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 81994653..4cbb292f 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,8 @@
Thank you for submitting a PR!
-Please make sure you include the names of the affected language(s) in your PR title.
+Please delete this standard text once you've created your own description.
+
+Make sure you include the names of the affected language(s) in your PR title.
This helps us get the correct maintainers to look at your issue.
If you make changes to any of the code generators, be sure to run
@@ -11,6 +13,8 @@ If your PR includes C++ code, please adhere to the Google C++ Style Guide,
and don't forget we try to support older compilers (e.g. VS2010, GCC 4.6.3),
so only some C++11 support is available.
+For any C++ changes, please make sure to run `sh src/clang-format-git.sh`
+
Include other details as appropriate.
Thanks!
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 00000000..84ff87b5
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,18 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 365
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 14
+# Issues with these labels will never be considered stale
+exemptLabels:
+ - pinned
+ - security
+# Label to use when marking an issue as stale
+staleLabel: stale
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ activity for 1 year. It will be automatically closed if no further activity occurs.
+ To keep it open, simply post a new comment. Maintainers will re-open on
+ new activity. Thank you for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
diff --git a/.gitignore b/.gitignore
index b7b41acb..c08d5539 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,12 @@
*_wire.txt
*_wire.bin
.DS_Store
+**/.build
+**/Packages
+/*.xcodeproj
+**/xcuserdata/
+**/xcshareddata/
+**/.swiftpm/
*.o
*.o.d
*.class
@@ -116,3 +122,6 @@ dart/doc/api/
Cargo.lock
.corpus**
.seed**
+grpc/google/
+**/Package.resolved
+.clangd/**
diff --git a/.travis.yml b/.travis.yml
index 04616f7f..e1825fad 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -22,6 +22,21 @@ conan-linux: &conan-linux
- ./conan/travis/build.sh
if: tag IS present
+conan-linux-master: &conan-linux-master
+ os: linux
+ dist: xenial
+ language: python
+ python: "3.7"
+ services:
+ - docker
+ install:
+ - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/install.sh; fi'
+ script:
+ - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/build.sh; fi'
+ branches:
+ only:
+ - master
+
conan-osx: &conan-osx
os: osx
language: generic
@@ -78,7 +93,7 @@ matrix:
env:
matrix:
- BUILD_TYPE=Debug
- - BUILD_TYPE=Release CONAN=true
+ - BUILD_TYPE=Release
before_install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
@@ -97,10 +112,9 @@ matrix:
-DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install
-DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf
-DFLATBUFFERS_CODE_SANITIZE=ON
- - cmake --build . -- -j${JOBS}
+ - cmake --build . --target all --clean-first -- -j${JOBS}
- LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
- bash .travis/check-generate-code.sh
- - if [ "$CONAN" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo pip install conan && conan create . flatbuffers/${TRAVIS_BRANCH}@google/testing -s build_type=$BUILD_TYPE -tf conan/test_package; fi
- language: cpp
os: osx
@@ -122,6 +136,8 @@ matrix:
- DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
- bash .travis/check-generate-code.sh
+ - <<: *conan-linux-master
+ env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
- <<: *conan-linux
env: CONAN_GCC_VERSIONS=4.9 CONAN_DOCKER_IMAGE=conanio/gcc49
- <<: *conan-linux
@@ -133,6 +149,8 @@ matrix:
- <<: *conan-linux
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
- <<: *conan-linux
+ env: CONAN_GCC_VERSIONS=9 CONAN_DOCKER_IMAGE=conanio/gcc9
+ - <<: *conan-linux
env: CONAN_CLANG_VERSIONS=3.9 CONAN_DOCKER_IMAGE=conanio/clang39
- <<: *conan-linux
env: CONAN_CLANG_VERSIONS=4.0 CONAN_DOCKER_IMAGE=conanio/clang40
@@ -140,6 +158,10 @@ matrix:
env: CONAN_CLANG_VERSIONS=5.0 CONAN_DOCKER_IMAGE=conanio/clang50
- <<: *conan-linux
env: CONAN_CLANG_VERSIONS=6.0 CONAN_DOCKER_IMAGE=conanio/clang60
+ - <<: *conan-linux
+ env: CONAN_CLANG_VERSIONS=7.0 CONAN_DOCKER_IMAGE=conanio/clang7
+ - <<: *conan-linux
+ env: CONAN_CLANG_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/clang8
- <<: *conan-osx
osx_image: xcode7.3
env: CONAN_APPLE_CLANG_VERSIONS=7.3
@@ -153,11 +175,12 @@ matrix:
osx_image: xcode9.4
env: CONAN_APPLE_CLANG_VERSIONS=9.1
- <<: *conan-osx
- osx_image: xcode10
+ osx_image: xcode10.2
env: CONAN_APPLE_CLANG_VERSIONS=10.0
- language: android
sudo: true
+ dist: trusty
android:
components:
- tools
@@ -171,8 +194,20 @@ matrix:
before_install:
# Output something every 10 minutes or Travis kills the job
- while sleep 540; do echo "=====[ $SECONDS seconds still running ]====="; done &
- - git clone https://github.com/urho3d/android-ndk.git $HOME/android-ndk-root
- - export ANDROID_NDK_HOME=$HOME/android-ndk-root
+ # Install the r17c version of the NDK that still so that we can continue to test with gnustl
+ # and stlport.
+ - export ANDROID_NDK_HOME=$HOME/android-ndk
+ - NDK_ZIP=$ANDROID_NDK_HOME/ndk.zip
+ - mkdir -p $ANDROID_NDK_HOME
+ - curl -o $NDK_ZIP https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
+ - unzip -q -d $ANDROID_NDK_HOME $NDK_ZIP
+ - rm $NDK_ZIP
+ - mv $ANDROID_NDK_HOME/android-ndk-*/* $ANDROID_NDK_HOME
+ - rmdir $ANDROID_NDK_HOME/android-ndk-*
+ - export CMAKE=$(which cmake)
+ # libc required for prebuilt llvm toolchain the NDK r17c.
+ - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
+ - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq libc6; fi
# Setup environment for Linux build which is required to build the sample.
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
diff --git a/.travis/build-and-run-docker-test-containers.sh b/.travis/build-and-run-docker-test-containers.sh
index e6039bf6..d377ba8d 100755
--- a/.travis/build-and-run-docker-test-containers.sh
+++ b/.travis/build-and-run-docker-test-containers.sh
@@ -15,10 +15,15 @@
# limitations under the License.
set -e
-# build flatc on debian once to speed up the test loop below
-docker build -t build_flatc_debian_stretch -f tests/docker/Dockerfile.testing.build_flatc_debian_stretch .
-BUILD_CONTAINER_ID=$(docker create --read-only build_flatc_debian_stretch)
-docker cp ${BUILD_CONTAINER_ID}:/code/flatc flatc_debian_stretch
+docker build -t build_cpp_image -f tests/docker/Dockerfile.testing.cpp.debian_buster .
+# Run tests with sanitizers (--cap-add SYS_PTRACE), both GCC and Clang.
+cpp_test_args="--cap-add SYS_PTRACE build_cpp_image sh ./tests/docker/cpp_test.run.sh Debug"
+docker run --rm $cpp_test_args
+docker run --rm --env CC=/usr/bin/clang --env CXX=/usr/bin/clang++ $cpp_test_args
+# Build flatc on debian once to speed up the test loop below.
+docker run --name flatc_container build_cpp_image sh ./tests/docker/build_flatc.run.sh Debug
+# All dependent dockers refer to 'flatc_debian_stretch'.
+docker cp flatc_container:/flatbuffers/flatc flatc_debian_stretch
for f in $(ls tests/docker/languages | sort)
do
diff --git a/.travis/check-generate-code.sh b/.travis/check-generate-code.sh
index 88024914..1f2d84d4 100755
--- a/.travis/check-generate-code.sh
+++ b/.travis/check-generate-code.sh
@@ -21,6 +21,8 @@ cd ..
# TODO: Linux and macos builds produce differences here for some reason.
git checkout HEAD -- tests/monster_test.bfbs
+git checkout HEAD -- tests/arrays_test.bfbs
+git checkout HEAD -- samples/monster.bfbs
if ! git diff --quiet; then
echo >&2
diff --git a/Android.bp b/Android.bp
index 90bda4c6..6ebce887 100644
--- a/Android.bp
+++ b/Android.bp
@@ -35,7 +35,7 @@ cc_binary_host {
"-Werror",
"-Wextra",
"-Werror=shadow",
- "-Wno-implicit-fallthrough", // in idl_gen_general.cpp and reflection.cpp
+ "-Wno-implicit-fallthrough", // in reflection.cpp
],
local_include_dirs: [
@@ -44,36 +44,82 @@ cc_binary_host {
],
srcs: [
+ "src/*.cpp",
+ "grpc/src/compiler/*.cc",
+ ],
+ exclude_srcs: [
+ "src/flathash.cpp",
+ ],
+}
+
+java_library {
+ name: "flatbuffers-java",
+ srcs: ["java/**/*.java"],
+ sdk_version: "current",
+
+ java_version: "1.8",
+}
+
+cc_library {
+ name: "libflatbuffers-cpp",
+ export_include_dirs: ["include"],
+ cpp_std: "c++17",
+ host_supported: true,
+ local_include_dirs: [
+ "include",
+ ],
+ srcs: [
"src/code_generators.cpp",
- "src/flatc.cpp",
- "src/flatc_main.cpp",
- "src/idl_gen_cpp.cpp",
- "src/idl_gen_dart.cpp",
"src/idl_gen_fbs.cpp",
- "src/idl_gen_general.cpp",
- "src/idl_gen_go.cpp",
- "src/idl_gen_grpc.cpp",
- "src/idl_gen_js_ts.cpp",
- "src/idl_gen_json_schema.cpp",
- "src/idl_gen_lua.cpp",
- "src/idl_gen_lobster.cpp",
- "src/idl_gen_php.cpp",
- "src/idl_gen_python.cpp",
- "src/idl_gen_rust.cpp",
"src/idl_gen_text.cpp",
"src/idl_parser.cpp",
"src/reflection.cpp",
"src/util.cpp",
- "grpc/src/compiler/cpp_generator.cc",
- "grpc/src/compiler/go_generator.cc",
- "grpc/src/compiler/java_generator.cc",
+ ],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.bluetooth.updatable",
],
}
-java_library {
- name: "flatbuffers-java",
- srcs: ["java/**/*.java"],
- sdk_version: "current",
+cc_defaults {
+ name: "flatbuffers_fuzzer_defaults",
+ srcs: [
+ "tests/test_assert.cpp",
+ ],
+ shared_libs: [
+ "liblog",
+ "libflatbuffers-cpp"
+ ],
+ local_include_dirs: [
+ "tests",
+ "tests/fuzzer",
+ ],
+ fuzz_config: {
+ componentid: 87896
+ }
+}
- java_version: "1.8",
+cc_fuzz {
+ name: "flatbuffers_parser_fuzzer",
+ defaults: ["flatbuffers_fuzzer_defaults"],
+ srcs: [
+ "tests/fuzzer/flatbuffers_parser_fuzzer.cc"
+ ],
+}
+
+cc_fuzz {
+ name: "flatbuffers_scalar_fuzzer",
+ defaults: ["flatbuffers_fuzzer_defaults"],
+ srcs: [
+ "tests/fuzzer/flatbuffers_scalar_fuzzer.cc"
+ ],
+}
+
+cc_fuzz {
+ name: "flatbuffers_verifier_fuzzer",
+ defaults: ["flatbuffers_fuzzer_defaults"],
+ srcs: [
+ "tests/fuzzer/flatbuffers_verifier_fuzzer.cc"
+ ],
}
diff --git a/BUILD b/BUILD
index 78e07d2f..4f8107b2 100644
--- a/BUILD
+++ b/BUILD
@@ -1,34 +1,22 @@
licenses(["notice"])
+load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
+
package(
default_visibility = ["//visibility:public"],
- features = [
- "-layering_check",
- "-parse_headers",
- ],
)
exports_files([
"LICENSE",
])
-load(":build_defs.bzl", "flatbuffer_cc_library")
-
# Public flatc library to compile flatbuffer files at runtime.
cc_library(
name = "flatbuffers",
- srcs = [
- "src/code_generators.cpp",
- "src/idl_gen_fbs.cpp",
- "src/idl_gen_general.cpp",
- "src/idl_gen_text.cpp",
- "src/idl_parser.cpp",
- "src/reflection.cpp",
- "src/util.cpp",
- ],
- hdrs = [":public_headers"],
- includes = ["include/"],
+ hdrs = ["//:public_headers"],
linkstatic = 1,
+ strip_include_prefix = "/include",
+ deps = ["//src:flatbuffers"],
)
# Public C++ headers for the Flatbuffers library.
@@ -44,6 +32,7 @@ filegroup(
"include/flatbuffers/minireflect.h",
"include/flatbuffers/reflection.h",
"include/flatbuffers/reflection_generated.h",
+ "include/flatbuffers/registry.h",
"include/flatbuffers/stl_emulation.h",
"include/flatbuffers/util.h",
],
@@ -52,60 +41,29 @@ filegroup(
# Public flatc compiler library.
cc_library(
name = "flatc_library",
- srcs = [
- "src/code_generators.cpp",
- "src/flatc.cpp",
- "src/idl_gen_fbs.cpp",
- "src/idl_parser.cpp",
- "src/reflection.cpp",
- "src/util.cpp",
- ],
- hdrs = [
- "include/flatbuffers/flatc.h",
- ":public_headers",
- ],
- includes = [
- "grpc/",
- "include/",
+ linkstatic = 1,
+ deps = [
+ "//src:flatc_library",
],
)
# Public flatc compiler.
cc_binary(
name = "flatc",
- srcs = [
- "grpc/src/compiler/config.h",
- "grpc/src/compiler/cpp_generator.cc",
- "grpc/src/compiler/cpp_generator.h",
- "grpc/src/compiler/go_generator.cc",
- "grpc/src/compiler/go_generator.h",
- "grpc/src/compiler/java_generator.cc",
- "grpc/src/compiler/java_generator.h",
- "grpc/src/compiler/schema_interface.h",
- "src/flatc_main.cpp",
- "src/idl_gen_cpp.cpp",
- "src/idl_gen_dart.cpp",
- "src/idl_gen_general.cpp",
- "src/idl_gen_go.cpp",
- "src/idl_gen_grpc.cpp",
- "src/idl_gen_js_ts.cpp",
- "src/idl_gen_json_schema.cpp",
- "src/idl_gen_lobster.cpp",
- "src/idl_gen_lua.cpp",
- "src/idl_gen_php.cpp",
- "src/idl_gen_python.cpp",
- "src/idl_gen_rust.cpp",
- "src/idl_gen_text.cpp",
- ],
- includes = [
- "grpc/",
- "include/",
- ],
deps = [
- ":flatc_library",
+ "//src:flatc",
+ ],
+)
+
+filegroup(
+ name = "flatc_headers",
+ srcs = [
+ "include/flatbuffers/flatc.h",
],
+ visibility = ["//:__subpackages__"],
)
+# Library used by flatbuffer_cc_library rules.
cc_library(
name = "runtime_cc",
hdrs = [
@@ -115,72 +73,6 @@ cc_library(
"include/flatbuffers/stl_emulation.h",
"include/flatbuffers/util.h",
],
- includes = ["include/"],
linkstatic = 1,
-)
-
-# Test binary.
-cc_test(
- name = "flatbuffers_test",
- testonly = 1,
- srcs = [
- "include/flatbuffers/minireflect.h",
- "include/flatbuffers/registry.h",
- "src/code_generators.cpp",
- "src/idl_gen_fbs.cpp",
- "src/idl_gen_general.cpp",
- "src/idl_gen_text.cpp",
- "src/idl_parser.cpp",
- "src/reflection.cpp",
- "src/util.cpp",
- "tests/namespace_test/namespace_test1_generated.h",
- "tests/namespace_test/namespace_test2_generated.h",
- "tests/test.cpp",
- "tests/test_assert.cpp",
- "tests/test_assert.h",
- "tests/test_builder.cpp",
- "tests/test_builder.h",
- "tests/union_vector/union_vector_generated.h",
- ":public_headers",
- ],
- copts = [
- "-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE",
- "-DBAZEL_TEST_DATA_PATH",
- ],
- data = [
- ":tests/include_test/include_test1.fbs",
- ":tests/include_test/sub/include_test2.fbs",
- ":tests/monster_test.bfbs",
- ":tests/monster_test.fbs",
- ":tests/monsterdata_test.golden",
- ":tests/prototest/imported.proto",
- ":tests/prototest/test.golden",
- ":tests/prototest/test.proto",
- ":tests/prototest/test_union.golden",
- ":tests/unicode_test.json",
- ":tests/union_vector/union_vector.fbs",
- ":tests/union_vector/union_vector.json",
- ],
- includes = ["include/"],
- deps = [
- ":monster_extra_cc_fbs",
- ":monster_test_cc_fbs",
- ],
-)
-
-# Test bzl rules
-
-flatbuffer_cc_library(
- name = "monster_test_cc_fbs",
- srcs = ["tests/monster_test.fbs"],
- include_paths = ["tests/include_test"],
- includes = [
- "tests/include_test/include_test1.fbs",
- "tests/include_test/sub/include_test2.fbs",
- ],
-)
-
-flatbuffer_cc_library(
- name = "monster_extra_cc_fbs",
- srcs = ["tests/monster_extra.fbs"],
+ strip_include_prefix = "/include",
)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 119855a9..3987eac9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 2.8.12)
# generate compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXSymbolExists)
@@ -13,6 +13,8 @@ option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library"
ON)
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
ON)
+option(FLATBUFFERS_STATIC_FLATC "Build flatbuffers compiler with -static flag"
+ OFF)
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
option(FLATBUFFERS_BUILD_SHAREDLIB
@@ -29,6 +31,13 @@ option(FLATBUFFERS_PACKAGE_REDHAT
option(FLATBUFFERS_PACKAGE_DEBIAN
"Build an deb using the 'package' target."
OFF)
+option(FLATBUFFERS_BUILD_CPP17
+ "Enable the build of c++17 test target. \"
+ Requirements: Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher."
+ OFF)
+option(FLATBUFFERS_BUILD_LEGACY
+ "Run C++ code generator with '--cpp-std c++0x' switch."
+ OFF)
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
message(WARNING
@@ -42,18 +51,23 @@ if(DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
endif()
-# Auto-detect locale-narrow 'strtod_l' function.
+# Auto-detect locale-narrow 'strtod_l' and 'strtoull_l' functions.
if(NOT DEFINED FLATBUFFERS_LOCALE_INDEPENDENT)
+ set(FLATBUFFERS_LOCALE_INDEPENDENT 0)
if(MSVC)
- check_cxx_symbol_exists(_strtof_l stdlib.h FLATBUFFERS_LOCALE_INDEPENDENT)
+ check_cxx_symbol_exists(_strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
+ check_cxx_symbol_exists(_strtoui64_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
else()
- check_cxx_symbol_exists(strtof_l stdlib.h FLATBUFFERS_LOCALE_INDEPENDENT)
+ check_cxx_symbol_exists(strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
+ check_cxx_symbol_exists(strtoull_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
+ endif()
+ if(FLATBUFFERS_HAS_STRTOF_L AND FLATBUFFERS_HAS_STRTOULL_L)
+ set(FLATBUFFERS_LOCALE_INDEPENDENT 1)
endif()
endif()
add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=$<BOOL:${FLATBUFFERS_LOCALE_INDEPENDENT}>)
set(FlatBuffers_Library_SRCS
- include/flatbuffers/code_generators.h
include/flatbuffers/base.h
include/flatbuffers/flatbuffers.h
include/flatbuffers/hash.h
@@ -65,7 +79,6 @@ set(FlatBuffers_Library_SRCS
include/flatbuffers/flexbuffers.h
include/flatbuffers/registry.h
include/flatbuffers/minireflect.h
- src/code_generators.cpp
src/idl_parser.cpp
src/idl_gen_text.cpp
src/reflection.cpp
@@ -75,9 +88,11 @@ set(FlatBuffers_Library_SRCS
set(FlatBuffers_Compiler_SRCS
${FlatBuffers_Library_SRCS}
src/idl_gen_cpp.cpp
+ src/idl_gen_csharp.cpp
src/idl_gen_dart.cpp
- src/idl_gen_general.cpp
+ src/idl_gen_kotlin.cpp
src/idl_gen_go.cpp
+ src/idl_gen_java.cpp
src/idl_gen_js_ts.cpp
src/idl_gen_php.cpp
src/idl_gen_python.cpp
@@ -87,8 +102,11 @@ set(FlatBuffers_Compiler_SRCS
src/idl_gen_fbs.cpp
src/idl_gen_grpc.cpp
src/idl_gen_json_schema.cpp
+ src/idl_gen_swift.cpp
src/flatc.cpp
src/flatc_main.cpp
+ include/flatbuffers/code_generators.h
+ src/code_generators.cpp
grpc/src/compiler/schema_interface.h
grpc/src/compiler/cpp_generator.h
grpc/src/compiler/cpp_generator.cc
@@ -96,6 +114,11 @@ set(FlatBuffers_Compiler_SRCS
grpc/src/compiler/go_generator.cc
grpc/src/compiler/java_generator.h
grpc/src/compiler/java_generator.cc
+ grpc/src/compiler/python_generator.h
+ grpc/src/compiler/python_private_generator.h
+ grpc/src/compiler/python_generator.cc
+ grpc/src/compiler/swift_generator.h
+ grpc/src/compiler/swift_generator.cc
)
set(FlatHash_SRCS
@@ -111,7 +134,34 @@ set(FlatBuffers_Tests_SRCS
tests/test_assert.cpp
tests/test_builder.h
tests/test_builder.cpp
+ tests/native_type_test_impl.h
+ tests/native_type_test_impl.cpp
+ include/flatbuffers/code_generators.h
+ src/code_generators.cpp
+ # file generate by running compiler on tests/monster_test.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
+ # file generate by running compiler on namespace_test/namespace_test1.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test1_generated.h
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test2_generated.h
+ # file generate by running compiler on union_vector/union_vector.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/union_vector/union_vector_generated.h
+ # file generate by running compiler on tests/arrays_test.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/arrays_test_generated.h
+ # file generate by running compiler on tests/native_type_test.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/native_type_test_generated.h
+ # file generate by running compiler on tests/monster_extra.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/monster_extra_generated.h
+ # file generate by running compiler on tests/monster_test.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_bfbs_generated.h
+)
+
+set(FlatBuffers_Tests_CPP17_SRCS
+ ${FlatBuffers_Library_SRCS}
+ tests/test_assert.h
+ tests/test_assert.cpp
+ tests/cpp17/test_cpp17.cpp
# file generate by running compiler on tests/monster_test.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/cpp17/generated_cpp17/monster_test_generated.h
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
)
@@ -131,7 +181,6 @@ set(FlatBuffers_Sample_Text_SRCS
set(FlatBuffers_Sample_BFBS_SRCS
${FlatBuffers_Library_SRCS}
- src/idl_gen_general.cpp
samples/sample_bfbs.cpp
# file generated by running compiler on samples/monster.fbs
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
@@ -140,6 +189,8 @@ set(FlatBuffers_Sample_BFBS_SRCS
set(FlatBuffers_GRPCTest_SRCS
include/flatbuffers/flatbuffers.h
include/flatbuffers/grpc.h
+ include/flatbuffers/util.h
+ src/util.cpp
tests/monster_test.grpc.fb.h
tests/test_assert.h
tests/test_builder.h
@@ -148,8 +199,8 @@ set(FlatBuffers_GRPCTest_SRCS
tests/test_builder.cpp
grpc/tests/grpctest.cpp
grpc/tests/message_builder_test.cpp
- # file generated by running compiler on samples/monster.fbs
- ${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
+ # file generate by running compiler on tests/monster_test.fbs
+ ${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
)
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
@@ -226,23 +277,28 @@ if(FLATBUFFERS_CODE_COVERAGE)
endif()
function(add_fsanitize_to_target _target _sanitizer)
- # FLATBUFFERS_CODE_SANITIZE: boolean {ON,OFF,YES,NO} or string with list of sanitizer.
- # List of sanitizer is string starts with '=': "=address,undefined,thread,memory".
- if((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") OR
- ((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
- )
- set(_sanitizer_flags "=address,undefined")
- if(_sanitizer MATCHES "=.*")
- # override default by user-defined sanitizer list
- set(_sanitizer_flags ${_sanitizer})
+ if(WIN32)
+ target_compile_definitions(${_target} PRIVATE FLATBUFFERS_MEMORY_LEAK_TRACKING)
+ message(STATUS "Sanitizer MSVC::_CrtDumpMemoryLeaks added to ${_target}")
+ else()
+ # FLATBUFFERS_CODE_SANITIZE: boolean {ON,OFF,YES,NO} or string with list of sanitizer.
+ # List of sanitizer is string starts with '=': "=address,undefined,thread,memory".
+ if((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") OR
+ ((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
+ )
+ set(_sanitizer_flags "=address,undefined")
+ if(_sanitizer MATCHES "=.*")
+ # override default by user-defined sanitizer list
+ set(_sanitizer_flags ${_sanitizer})
+ endif()
+ target_compile_options(${_target} PRIVATE
+ -g -fsigned-char -fno-omit-frame-pointer
+ "-fsanitize${_sanitizer_flags}")
+ target_link_libraries(${_target} PRIVATE
+ "-fsanitize${_sanitizer_flags}")
+ set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ON)
+ message(STATUS "Sanitizer ${_sanitizer_flags} added to ${_target}")
endif()
- target_compile_options(${_target} PRIVATE
- -g -fsigned-char -fno-omit-frame-pointer
- "-fsanitize${_sanitizer_flags}")
- target_link_libraries(${_target} PRIVATE
- "-fsanitize${_sanitizer_flags}")
- set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ON)
- message(STATUS "Sanitizer ${_sanitizer_flags} added to ${_target}")
endif()
endfunction()
@@ -256,7 +312,7 @@ include_directories(grpc)
if(FLATBUFFERS_BUILD_FLATLIB)
add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
- # CMake > 2.8.11: Attach header directory for when build via add_subdirectory().
+ # Attach header directory for when build via add_subdirectory().
target_include_directories(flatbuffers INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_compile_options(flatbuffers PRIVATE "${FLATBUFFERS_PRIVATE_CXX_FLAGS}")
@@ -275,6 +331,9 @@ if(FLATBUFFERS_BUILD_FLATC)
# Make flatc.exe not depend on runtime dlls for easy distribution.
target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>)
endif()
+ if(FLATBUFFERS_STATIC_FLATC AND NOT MSVC)
+ target_link_libraries(flatc PRIVATE -static)
+ endif()
endif()
if(FLATBUFFERS_BUILD_FLATHASH)
@@ -289,57 +348,148 @@ if(FLATBUFFERS_BUILD_SHAREDLIB)
# - minor updated when there are additions in API/ABI
# - major (ABI number) updated when there are changes in ABI (or removals)
set(FlatBuffers_Library_SONAME_MAJOR "1")
- set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.11.0")
+ set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.12.0")
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers
SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}"
VERSION "${FlatBuffers_Library_SONAME_FULL}")
endif()
-function(compile_flatbuffers_schema_to_cpp SRC_FBS)
+# Global list of generated files.
+# Use the global property to be independent of PARENT_SCOPE.
+set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
+
+function(get_generated_output generated_files)
+ get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
+ set(${generated_files} ${tmp} PARENT_SCOPE)
+endfunction(get_generated_output)
+
+function(register_generated_output file_name)
+ get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
+ list(APPEND tmp ${file_name})
+ set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS ${tmp})
+endfunction(register_generated_output)
+
+function(compile_flatbuffers_schema_to_cpp_opt SRC_FBS OPT)
+ if(FLATBUFFERS_BUILD_LEGACY)
+ set(OPT ${OPT};--cpp-std c++0x)
+ else()
+ # --cpp-std is defined by flatc default settings.
+ endif()
+ message(STATUS "`${SRC_FBS}`: add generation of C++ code with '${OPT}'")
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
add_custom_command(
OUTPUT ${GEN_HEADER}
- COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
- --gen-object-api --gen-compare -o "${SRC_FBS_DIR}"
+ COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
+ --cpp --gen-mutable --gen-object-api --reflect-names
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
- --reflect-names
+ ${OPT}
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
+ -o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
- DEPENDS flatc)
+ DEPENDS flatc
+ COMMENT "Run generation: '${GEN_HEADER}'")
+ register_generated_output(${GEN_HEADER})
+endfunction()
+
+function(compile_flatbuffers_schema_to_cpp SRC_FBS)
+ compile_flatbuffers_schema_to_cpp_opt(${SRC_FBS} "--no-includes;--gen-compare")
endfunction()
function(compile_flatbuffers_schema_to_binary SRC_FBS)
+ message(STATUS "`${SRC_FBS}`: add generation of binary (.bfbs) schema")
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
+ # For details about flags see generate_code.bat(sh)
add_custom_command(
OUTPUT ${GEN_BINARY_SCHEMA}
- COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -b --schema -o "${SRC_FBS_DIR}"
+ COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
+ -b --schema --bfbs-comments --bfbs-builtins
+ -I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
+ -o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
- DEPENDS flatc)
+ DEPENDS flatc
+ COMMENT "Run generation: '${GEN_BINARY_SCHEMA}'")
+ register_generated_output(${GEN_BINARY_SCHEMA})
+endfunction()
+
+function(compile_flatbuffers_schema_to_embedded_binary SRC_FBS OPT)
+ if(FLATBUFFERS_BUILD_LEGACY)
+ set(OPT ${OPT};--cpp-std c++0x)
+ else()
+ # --cpp-std is defined by flatc default settings.
+ endif()
+ message(STATUS "`${SRC_FBS}`: add generation of C++ embedded binary schema code with '${OPT}'")
+ get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
+ string(REGEX REPLACE "\\.fbs$" "_bfbs_generated.h" GEN_BFBS_HEADER ${SRC_FBS})
+ # For details about flags see generate_code.bat(sh)
+ add_custom_command(
+ OUTPUT ${GEN_BFBS_HEADER}
+ COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
+ --cpp --gen-mutable --gen-object-api --reflect-names
+ --cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
+ ${OPT}
+ --bfbs-comments --bfbs-builtins --bfbs-gen-embed
+ -I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
+ -o "${SRC_FBS_DIR}"
+ "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
+ DEPENDS flatc
+ COMMENT "Run generation: '${GEN_BFBS_HEADER}'")
+ register_generated_output(${GEN_BFBS_HEADER})
endfunction()
if(FLATBUFFERS_BUILD_TESTS)
+ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
+ file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/samples" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
+
+ # TODO Add (monster_test.fbs monsterdata_test.json)->monsterdata_test.mon
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
+ compile_flatbuffers_schema_to_binary(tests/monster_test.fbs)
+ compile_flatbuffers_schema_to_cpp(tests/namespace_test/namespace_test1.fbs)
+ compile_flatbuffers_schema_to_cpp(tests/namespace_test/namespace_test2.fbs)
+ compile_flatbuffers_schema_to_cpp(tests/union_vector/union_vector.fbs)
+ compile_flatbuffers_schema_to_cpp_opt(tests/native_type_test.fbs "")
+ compile_flatbuffers_schema_to_cpp_opt(tests/arrays_test.fbs "--scoped-enums;--gen-compare")
+ compile_flatbuffers_schema_to_binary(tests/arrays_test.fbs)
+ compile_flatbuffers_schema_to_embedded_binary(tests/monster_test.fbs "--no-includes;--gen-compare")
+ if(NOT (MSVC AND (MSVC_VERSION LESS 1900)))
+ compile_flatbuffers_schema_to_cpp(tests/monster_extra.fbs) # Test floating-point NAN/INF.
+ endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
add_executable(flattests ${FlatBuffers_Tests_SRCS})
+ add_dependencies(flattests generated_code)
set_property(TARGET flattests
PROPERTY COMPILE_DEFINITIONS FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1)
if(FLATBUFFERS_CODE_SANITIZE)
- if(WIN32)
- target_compile_definitions(flattests PRIVATE FLATBUFFERS_MEMORY_LEAK_TRACKING)
- message(STATUS "Sanitizer MSVC::_CrtDumpMemoryLeaks added to flattests")
- else()
- add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
- endif()
+ add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
endif()
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
+ compile_flatbuffers_schema_to_binary(samples/monster.fbs)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
add_executable(flatsamplebinary ${FlatBuffers_Sample_Binary_SRCS})
+ add_dependencies(flatsamplebinary generated_code)
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
+ add_dependencies(flatsampletext generated_code)
add_executable(flatsamplebfbs ${FlatBuffers_Sample_BFBS_SRCS})
+ add_dependencies(flatsamplebfbs generated_code)
+
+ if(FLATBUFFERS_BUILD_CPP17)
+ # Don't generate header for flattests_cpp17 target.
+ # This target uses "generated_cpp17/monster_test_generated.h"
+ # produced by direct call of generate_code.bat(sh) script.
+ add_executable(flattests_cpp17 ${FlatBuffers_Tests_CPP17_SRCS})
+ add_dependencies(flattests_cpp17 generated_code)
+ target_compile_features(flattests_cpp17 PRIVATE cxx_std_17)
+ target_compile_definitions(flattests_cpp17 PRIVATE
+ FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+ FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1
+ )
+ if(FLATBUFFERS_CODE_SANITIZE)
+ add_fsanitize_to_target(flattests_cpp17 ${FLATBUFFERS_CODE_SANITIZE})
+ endif()
+ endif(FLATBUFFERS_BUILD_CPP17)
endif()
if(FLATBUFFERS_BUILD_GRPCTEST)
@@ -356,7 +506,12 @@ if(FLATBUFFERS_BUILD_GRPCTEST)
INCLUDE_DIRECTORIES(${PROTOBUF_DOWNLOAD_PATH}/src)
LINK_DIRECTORIES(${GRPC_INSTALL_PATH}/lib)
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
- target_link_libraries(grpctest grpc++_unsecure grpc_unsecure gpr pthread dl)
+ add_dependencies(grpctest generated_code)
+ target_link_libraries(grpctest PRIVATE grpc++_unsecure grpc_unsecure gpr pthread dl)
+ if(FLATBUFFERS_CODE_SANITIZE AND NOT WIN32)
+ # GRPC test has problems with alignment and will fail under ASAN/UBSAN.
+ # add_fsanitize_to_target(grpctest ${FLATBUFFERS_CODE_SANITIZE})
+ endif()
endif()
include(CMake/Version.cmake)
@@ -439,14 +594,25 @@ endif()
if(FLATBUFFERS_BUILD_TESTS)
enable_testing()
- file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION
- "${CMAKE_CURRENT_BINARY_DIR}")
add_test(NAME flattests COMMAND flattests)
+ if(FLATBUFFERS_BUILD_CPP17)
+ add_test(NAME flattests_cpp17 COMMAND flattests_cpp17)
+ endif()
if(FLATBUFFERS_BUILD_GRPCTEST)
add_test(NAME grpctest COMMAND grpctest)
endif()
endif()
+# This target is sync-barrier.
+# Other generate-dependent targets can depend on 'generated_code' only.
+get_generated_output(fbs_generated)
+if(fbs_generated)
+ # message(STATUS "Add generated_code target with files:${fbs_generated}")
+ add_custom_target(generated_code
+ DEPENDS ${fbs_generated}
+ COMMENT "All generated files were updated.")
+endif()
+
include(CMake/BuildFlatBuffers.cmake)
if(UNIX)
diff --git a/LICENSE.txt b/LICENSE.txt
index a4c5efd8..d6456956 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright 2014 Google Inc.
+ Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/METADATA b/METADATA
index 81e6cdc3..14dbcd41 100644
--- a/METADATA
+++ b/METADATA
@@ -9,10 +9,11 @@ third_party {
type: GIT
value: "https://github.com/google/flatbuffers.git"
}
- version: "v1.11.0"
+ version: "v1.12.0"
+ license_type: NOTICE
last_upgrade_date {
- year: 2019
- month: 7
- day: 9
+ year: 2020
+ month: 3
+ day: 12
}
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 2b026106..35e7be0c 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -7,6 +7,12 @@
"exclude-annotation": "androidx.test.filters.FlakyTest"
}
]
+ },
+ {
+ "name": "bluetooth_flatbuffer_tests"
+ },
+ {
+ "name": "CtsTfliteNnapiDelegateTestCases"
}
- ]
-} \ No newline at end of file
+ ]
+}
diff --git a/WORKSPACE b/WORKSPACE
index be4a402e..0ab09dbd 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -4,11 +4,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "io_bazel_rules_go",
- sha256 = "492c3ac68ed9dcf527a07e6a1b2dcbf199c6bf8b35517951467ac32e421c06c1",
- urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.17.0/rules_go-0.17.0.tar.gz"],
+ urls = [
+ "https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/v0.20.3/rules_go-v0.20.3.tar.gz",
+ "https://github.com/bazelbuild/rules_go/releases/download/v0.20.3/rules_go-v0.20.3.tar.gz",
+ ],
+ sha256 = "e88471aea3a3a4f19ec1310a55ba94772d087e9ce46e41ae38ecebe17935de7b",
)
-load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
+load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index b2203326..78614fb0 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -36,8 +36,7 @@ LOCAL_MODULE := flatbuffers_extra
LOCAL_SRC_FILES := src/idl_parser.cpp \
src/idl_gen_text.cpp \
src/reflection.cpp \
- src/util.cpp \
- src/code_generators.cpp
+ src/util.cpp
LOCAL_STATIC_LIBRARIES := flatbuffers
LOCAL_ARM_MODE := arm
include $(BUILD_STATIC_LIBRARY)
@@ -51,8 +50,10 @@ LOCAL_SRC_FILES := android/jni/main.cpp \
tests/test_builder.h \
tests/test_assert.cpp \
tests/test_builder.cpp \
+ tests/native_type_test_impl.h \
+ tests/native_type_test_impl.cpp \
src/idl_gen_fbs.cpp \
- src/idl_gen_general.cpp
+ src/code_generators.cpp
LOCAL_LDLIBS := -llog -landroid -latomic
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra
LOCAL_ARM_MODE := arm
diff --git a/android/jni/main.cpp b/android/jni/main.cpp
index 0d643495..182b346b 100644
--- a/android/jni/main.cpp
+++ b/android/jni/main.cpp
@@ -18,9 +18,6 @@
extern int main(int argc, char **argv);
-void android_main(android_app *app) {
- // Make sure glue isn't stripped.
- app_dummy();
-
+void android_main(android_app *) {
main(0, NULL);
}
diff --git a/appveyor.yml b/appveyor.yml
index 75a63c87..e42feceb 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -2,23 +2,36 @@ branches:
only:
- master
-os: Visual Studio 2015
-
environment:
global:
# Workaround for https://github.com/conda/conda-build/issues/636
PYTHONIOENCODING: UTF-8
CONDA_INSTALL_LOCN: "C:\\Miniconda35-x64"
+ CMAKE_OPTIONS: ""
+ CPP_TEST_OPTIONS: ""
matrix:
- - CMAKE_VS_VERSION: "10 2010"
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ CMAKE_VS_VERSION: "10 2010"
+ CMAKE_OPTIONS: "-DFLATBUFFERS_BUILD_LEGACY=1"
+ CPP_TEST_OPTIONS: "--std-cpp c++0x"
MONSTER_EXTRA: "skip"
- - CMAKE_VS_VERSION: "12 2013"
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ CMAKE_VS_VERSION: "12 2013"
MONSTER_EXTRA: "skip"
- - CMAKE_VS_VERSION: "14 2015"
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
+ CMAKE_VS_VERSION: "14 2015"
+ MONSTER_EXTRA: ""
+
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+ CMAKE_VS_VERSION: "15 2017"
+ MONSTER_EXTRA: ""
+
+ - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+ CMAKE_VS_VERSION: "16 2019"
MONSTER_EXTRA: ""
platform:
@@ -31,9 +44,11 @@ configuration:
before_build:
- set MONSTER_EXTRA=%MONSTER_EXTRA%
- - cmake -G"Visual Studio %CMAKE_VS_VERSION%" -DFLATBUFFERS_CODE_SANITIZE=1 .
+ - cmake . -G"Visual Studio %CMAKE_VS_VERSION%" -DFLATBUFFERS_CODE_SANITIZE=1 %CMAKE_OPTIONS%
# This cuts down on a lot of noise generated by xamarin warnings.
- - del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
+ - if exist "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
+ - if exist "C:\Program Files (x86)\MSBuild\15.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\15.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
+ - if exist "C:\Program Files (x86)\MSBuild\16.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\16.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
build:
project: ALL_BUILD.vcxproj
@@ -55,7 +70,7 @@ test_script:
- call .appveyor\check-generate-code.bat -b %CONFIGURATION%
- "cd tests"
- rem "Building all code"
- - generate_code.bat -b %CONFIGURATION%
+ - generate_code.bat -b %CONFIGURATION% %CPP_TEST_OPTIONS%
- 7z a GeneratedMyGameCode.zip MyGame\
- rem "---------------- C++ -----------------"
- "cd .."
@@ -90,6 +105,11 @@ test_script:
# Have to compile this here rather than in "build" above because AppVeyor only
# supports building one project??
- "cd FlatBuffers.Test"
+ - "copy ..\\monsterdata_test.mon Resources\\"
+ - "copy ..\\monsterdata_test.json Resources\\"
+ - "dotnet new sln"
+ - "dotnet sln add FlatBuffers.Test.csproj"
+ - "nuget restore"
- "msbuild.exe /property:Configuration=Release;OutputPath=tempcs /verbosity:minimal FlatBuffers.Test.csproj"
- "tempcs\\FlatBuffers.Test.exe"
# Run tests with UNSAFE_BYTEBUFFER
diff --git a/build_defs.bzl b/build_defs.bzl
index af676101..88792be4 100644
--- a/build_defs.bzl
+++ b/build_defs.bzl
@@ -5,6 +5,8 @@
Rules for building C++ flatbuffers with Bazel.
"""
+load("@rules_cc//cc:defs.bzl", "cc_library")
+
flatc_path = "@com_github_google_flatbuffers//:flatc"
DEFAULT_INCLUDE_PATHS = [
@@ -32,7 +34,9 @@ def flatbuffer_library_public(
include_paths = DEFAULT_INCLUDE_PATHS,
flatc_args = DEFAULT_FLATC_ARGS,
reflection_name = "",
- reflection_visiblity = None,
+ reflection_visibility = None,
+ compatible_with = None,
+ restricted_to = None,
output_to_bindir = False):
"""Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
@@ -48,7 +52,12 @@ def flatbuffer_library_public(
flatc_args: Optional, list of additional arguments to pass to flatc.
reflection_name: Optional, if set this will generate the flatbuffer
reflection binaries for the schemas.
- reflection_visiblity: The visibility of the generated reflection Fileset.
+ reflection_visibility: The visibility of the generated reflection Fileset.
+ output_to_bindir: Passed to genrule for output to bin directory.
+ compatible_with: Optional, The list of environments this rule can be
+ built for, in addition to default-supported environments.
+ restricted_to: Optional, The list of environments this rule can be built
+ for, instead of default-supported environments.
output_to_bindir: Passed to genrule for output to bin directory.
@@ -82,6 +91,8 @@ def flatbuffer_library_public(
output_to_bindir = output_to_bindir,
tools = [flatc_path],
cmd = genrule_cmd,
+ compatible_with = compatible_with,
+ restricted_to = restricted_to,
message = "Generating flatbuffer files for %s:" % (name),
)
if reflection_name:
@@ -107,16 +118,17 @@ def flatbuffer_library_public(
outs = reflection_outs,
output_to_bindir = output_to_bindir,
tools = [flatc_path],
+ compatible_with = compatible_with,
+ restricted_to = restricted_to,
cmd = reflection_genrule_cmd,
message = "Generating flatbuffer reflection binary for %s:" % (name),
)
- native.Fileset(
- name = reflection_name,
- out = "%s_out" % reflection_name,
- entries = [
- native.FilesetEntry(files = reflection_outs),
- ],
- visibility = reflection_visiblity,
+ native.filegroup(
+ name = "%s_out" % reflection_name,
+ srcs = reflection_outs,
+ visibility = reflection_visibility,
+ compatible_with = compatible_with,
+ restricted_to = restricted_to,
)
def flatbuffer_cc_library(
@@ -128,6 +140,8 @@ def flatbuffer_cc_library(
include_paths = DEFAULT_INCLUDE_PATHS,
flatc_args = DEFAULT_FLATC_ARGS,
visibility = None,
+ compatible_with = None,
+ restricted_to = None,
srcs_filegroup_visibility = None,
gen_reflections = False):
'''A cc_library with the generated reader/writers for the given flatbuffer definitions.
@@ -151,6 +165,10 @@ def flatbuffer_cc_library(
By default, use the value of the visibility parameter above.
gen_reflections: Optional, if true this will generate the flatbuffer
reflection binaries for the schemas.
+ compatible_with: Optional, The list of environments this rule can be built
+ for, in addition to default-supported environments.
+ restricted_to: Optional, The list of environments this rule can be built
+ for, instead of default-supported environments.
This produces:
filegroup([name]_srcs): all generated .h files.
@@ -206,10 +224,12 @@ def flatbuffer_cc_library(
includes = includes,
include_paths = include_paths,
flatc_args = flatc_args,
+ compatible_with = compatible_with,
+ restricted_to = restricted_to,
reflection_name = reflection_name,
- reflection_visiblity = visibility,
+ reflection_visibility = visibility,
)
- native.cc_library(
+ cc_library(
name = name,
hdrs = [
":" + srcs_lib,
@@ -224,6 +244,8 @@ def flatbuffer_cc_library(
"@com_github_google_flatbuffers//:runtime_cc",
],
includes = [],
+ compatible_with = compatible_with,
+ restricted_to = restricted_to,
linkstatic = 1,
visibility = visibility,
)
@@ -233,5 +255,7 @@ def flatbuffer_cc_library(
native.filegroup(
name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
srcs = srcs,
+ compatible_with = compatible_with,
+ restricted_to = restricted_to,
visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
)
diff --git a/dart/lib/flat_buffers.dart b/dart/lib/flat_buffers.dart
index e2512604..3d4cf81b 100644
--- a/dart/lib/flat_buffers.dart
+++ b/dart/lib/flat_buffers.dart
@@ -492,7 +492,7 @@ class Builder {
/// Write the given list of 64-bit float [values].
int writeListFloat64(List<double> values) {
_ensureNoVTable();
- _prepare(4, 1 + (2 * values.length));
+ _prepare(_sizeofFloat64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
_setUint32AtTail(_buf, tail, values.length);
@@ -522,7 +522,7 @@ class Builder {
/// Write the given list of signed 64-bit integer [values].
int writeListInt64(List<int> values) {
_ensureNoVTable();
- _prepare(_sizeofUint32, 2 * values.length);
+ _prepare(_sizeofInt64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
_setUint32AtTail(_buf, tail, values.length);
@@ -537,7 +537,7 @@ class Builder {
/// Write the given list of signed 64-bit integer [values].
int writeListUint64(List<int> values) {
_ensureNoVTable();
- _prepare(_sizeofUint32, 2 * values.length);
+ _prepare(_sizeofUint64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
_setUint32AtTail(_buf, tail, values.length);
diff --git a/dart/pubspec.yaml b/dart/pubspec.yaml
index 4761ffc2..78a7bf17 100644
--- a/dart/pubspec.yaml
+++ b/dart/pubspec.yaml
@@ -1,5 +1,5 @@
name: flat_buffers
-version: 1.11.0
+version: 1.12.0
description: >
FlatBuffers reading and writing library for Dart. Use the flatc compiler to
generate Dart classes for a FlatBuffers schema, and this library to assist with
diff --git a/dart/test/monster_test_my_game.example_generated.dart b/dart/test/monster_test_my_game.example_generated.dart
index 49e2ec17..4bc9b9c2 100644
--- a/dart/test/monster_test_my_game.example_generated.dart
+++ b/dart/test/monster_test_my_game.example_generated.dart
@@ -11,6 +11,7 @@ import 'include_test2_my_game.example_generated.dart';
import './monster_test_my_game_generated.dart' as my_game;
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+/// Composite components of Monster color.
class Color {
final int value;
const Color._(this.value);
@@ -26,7 +27,12 @@ class Color {
static bool containsValue(int value) => values.containsKey(value);
static const Color Red = const Color._(1);
+
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
static const Color Green = const Color._(2);
+
+ /// \brief color Blue (1u << 3)
static const Color Blue = const Color._(8);
static get values => {1: Red,2: Green,8: Blue,};
@@ -46,7 +52,48 @@ class _ColorReader extends fb.Reader<Color> {
@override
Color read(fb.BufferContext bc, int offset) =>
- new Color.fromValue(const fb.Int8Reader().read(bc, offset));
+ new Color.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class Race {
+ final int value;
+ const Race._(this.value);
+
+ factory Race.fromValue(int value) {
+ if (value == null) value = 0;
+ if (!values.containsKey(value)) {
+ throw new StateError('Invalid value $value for bit flag enum Race');
+ }
+ return values[value];
+ }
+
+ static const int minValue = -1;
+ static const int maxValue = 2;
+ static bool containsValue(int value) => values.containsKey(value);
+
+ static const Race None = const Race._(-1);
+ static const Race Human = const Race._(0);
+ static const Race Dwarf = const Race._(1);
+ static const Race Elf = const Race._(2);
+ static get values => {-1: None,0: Human,1: Dwarf,2: Elf,};
+
+ static const fb.Reader<Race> reader = const _RaceReader();
+
+ @override
+ String toString() {
+ return 'Race{value: $value}';
+ }
+}
+
+class _RaceReader extends fb.Reader<Race> {
+ const _RaceReader();
+
+ @override
+ int get size => 1;
+
+ @override
+ Race read(fb.BufferContext bc, int offset) =>
+ new Race.fromValue(const fb.Int8Reader().read(bc, offset));
}
class AnyTypeId {
@@ -108,9 +155,9 @@ class AnyUniqueAliasesTypeId {
static const AnyUniqueAliasesTypeId NONE = const AnyUniqueAliasesTypeId._(0);
static const AnyUniqueAliasesTypeId M = const AnyUniqueAliasesTypeId._(1);
- static const AnyUniqueAliasesTypeId T = const AnyUniqueAliasesTypeId._(2);
+ static const AnyUniqueAliasesTypeId TS = const AnyUniqueAliasesTypeId._(2);
static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
- static get values => {0: NONE,1: M,2: T,3: M2,};
+ static get values => {0: NONE,1: M,2: TS,3: M2,};
static const fb.Reader<AnyUniqueAliasesTypeId> reader = const _AnyUniqueAliasesTypeIdReader();
@@ -259,7 +306,7 @@ class TestSimpleTableWithEnum {
final fb.BufferContext _bc;
final int _bcOffset;
- Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 2));
+ Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 4, 2));
@override
String toString() {
@@ -287,7 +334,7 @@ class TestSimpleTableWithEnumBuilder {
}
int addColor(Color color) {
- fbBuilder.addInt8(0, color?.value);
+ fbBuilder.addUint8(0, color?.value);
return fbBuilder.offset;
}
@@ -311,7 +358,7 @@ class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder {
assert(fbBuilder != null);
fbBuilder.startTable();
- fbBuilder.addInt8(0, _color?.value);
+ fbBuilder.addUint8(0, _color?.value);
return fbBuilder.endTable();
}
@@ -335,7 +382,7 @@ class Vec3 {
double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
- Color get test2 => new Color.fromValue(const fb.Int8Reader().read(_bc, _bcOffset + 24));
+ Color get test2 => new Color.fromValue(const fb.Uint8Reader().read(_bc, _bcOffset + 24));
Test get test3 => Test.reader.read(_bc, _bcOffset + 26);
@override
@@ -366,7 +413,7 @@ class Vec3Builder {
fbBuilder.pad(2);
test3();
fbBuilder.pad(1);
- fbBuilder.putInt8(test2?.value);
+ fbBuilder.putUint8(test2?.value);
fbBuilder.putFloat64(test1);
fbBuilder.pad(4);
fbBuilder.putFloat32(z);
@@ -409,7 +456,7 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder {
fbBuilder.pad(2);
_test3.finish(fbBuilder);
fbBuilder.pad(1);
- fbBuilder.putInt8(_test2?.value);
+ fbBuilder.putUint8(_test2?.value);
fbBuilder.putFloat64(_test1);
fbBuilder.pad(4);
fbBuilder.putFloat32(_z);
@@ -690,7 +737,7 @@ class Monster {
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
- Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 8));
+ Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 16, 8));
AnyTypeId get testType => new AnyTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 18, 0));
dynamic get test {
switch (testType?.value) {
@@ -702,8 +749,8 @@ class Monster {
}
List<Test> get test4 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 22, null);
List<String> get testarrayofstring => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 24, null);
-/// an example documentation comment: this will end up in the generated code
-/// multiline too
+ /// an example documentation comment: this will end up in the generated code
+ /// multiline too
List<Monster> get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGet(_bc, _bcOffset, 26, null);
Monster get enemy => Monster.reader.vTableGet(_bc, _bcOffset, 28, null);
List<int> get testnestedflatbuffer => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 30, null);
@@ -740,7 +787,7 @@ class Monster {
dynamic get anyUnique {
switch (anyUniqueType?.value) {
case 1: return M.reader.vTableGet(_bc, _bcOffset, 92, null);
- case 2: return T.reader.vTableGet(_bc, _bcOffset, 92, null);
+ case 2: return TS.reader.vTableGet(_bc, _bcOffset, 92, null);
case 3: return M2.reader.vTableGet(_bc, _bcOffset, 92, null);
default: return null;
}
@@ -755,10 +802,11 @@ class Monster {
}
}
List<Color> get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGet(_bc, _bcOffset, 98, null);
+ Race get signedEnum => new Race.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 100, -1));
@override
String toString() {
- return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums}';
+ return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums, signedEnum: $signedEnum}';
}
}
@@ -802,7 +850,7 @@ class MonsterBuilder {
return fbBuilder.offset;
}
int addColor(Color color) {
- fbBuilder.addInt8(6, color?.value);
+ fbBuilder.addUint8(6, color?.value);
return fbBuilder.offset;
}
int addTestType(AnyTypeId testType) {
@@ -969,6 +1017,10 @@ class MonsterBuilder {
fbBuilder.addOffset(47, offset);
return fbBuilder.offset;
}
+ int addSignedEnum(Race signedEnum) {
+ fbBuilder.addInt8(48, signedEnum?.value);
+ return fbBuilder.offset;
+ }
int finish() {
return fbBuilder.endTable();
@@ -1023,6 +1075,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
final AnyAmbiguousAliasesTypeId _anyAmbiguousType;
final dynamic _anyAmbiguous;
final List<Color> _vectorOfEnums;
+ final Race _signedEnum;
MonsterObjectBuilder({
Vec3ObjectBuilder pos,
@@ -1072,6 +1125,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
AnyAmbiguousAliasesTypeId anyAmbiguousType,
dynamic anyAmbiguous,
List<Color> vectorOfEnums,
+ Race signedEnum,
})
: _pos = pos,
_mana = mana,
@@ -1119,7 +1173,8 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
_anyUnique = anyUnique,
_anyAmbiguousType = anyAmbiguousType,
_anyAmbiguous = anyAmbiguous,
- _vectorOfEnums = vectorOfEnums;
+ _vectorOfEnums = vectorOfEnums,
+ _signedEnum = signedEnum;
/// Finish building, and store into the [fbBuilder].
@override
@@ -1185,7 +1240,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
final int anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
final int anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
final int vectorOfEnumsOffset = _vectorOfEnums?.isNotEmpty == true
- ? fbBuilder.writeListInt8(_vectorOfEnums.map((f) => f.value))
+ ? fbBuilder.writeListUint8(_vectorOfEnums.map((f) => f.value))
: null;
fbBuilder.startTable();
@@ -1200,7 +1255,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
if (inventoryOffset != null) {
fbBuilder.addOffset(5, inventoryOffset);
}
- fbBuilder.addInt8(6, _color?.value);
+ fbBuilder.addUint8(6, _color?.value);
fbBuilder.addUint8(7, _testType?.value);
if (testOffset != null) {
fbBuilder.addOffset(8, testOffset);
@@ -1288,6 +1343,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
if (vectorOfEnumsOffset != null) {
fbBuilder.addOffset(47, vectorOfEnumsOffset);
}
+ fbBuilder.addInt8(48, _signedEnum?.value);
return fbBuilder.endTable();
}
diff --git a/docs/source/Building.md b/docs/source/Building.md
index a8967110..ad9e972b 100644
--- a/docs/source/Building.md
+++ b/docs/source/Building.md
@@ -29,6 +29,19 @@ Building should also produce two sample executables, `flatsamplebinary` and
*Note that you MUST be in the root of the FlatBuffers distribution when you
run 'flattests' or `flatsampletext`, or it will fail to load its files.*
+## Building with VCPKG
+
+You can download and install flatbuffers using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
+
+ git clone https://github.com/Microsoft/vcpkg.git
+ cd vcpkg
+ ./bootstrap-vcpkg.sh
+ ./vcpkg integrate install
+ ./vcpkg install flatbuffers
+
+The flatbuffers port in vcpkg is kept up to date by Microsoft team members and community contributors.
+If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
+
## Building for Android
There is a `flatbuffers/android` directory that contains all you need to build
diff --git a/docs/source/Compiler.md b/docs/source/Compiler.md
index 90f8d8b4..aed579ca 100644
--- a/docs/source/Compiler.md
+++ b/docs/source/Compiler.md
@@ -3,7 +3,7 @@ Using the schema compiler {#flatbuffers_guide_using_schema_compiler}
Usage:
- flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] [ -S ] FILES...
+ flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] FILES...
[ -- FILES...]
The files are read and parsed in order, and can contain either schemas
@@ -23,6 +23,8 @@ For any schema input files, one or more generators can be specified:
- `--java`, `-j` : Generate Java code.
+- `--kotlin`, `-k` : Generate Kotlin code.
+
- `--csharp`, `-n` : Generate C# code.
- `--go`, `-g` : Generate Go code.
@@ -45,6 +47,8 @@ For any schema input files, one or more generators can be specified:
- `--rust`, `-r` : Generate Rust code.
+- `--swift`: Generate Swift code.
+
For any data input files:
- `--binary`, `-b` : If data is contained in this file, generate a
@@ -92,7 +96,7 @@ Additional options:
statements) use `--no-includes.`
- `--no-includes` : Don't generate include statements for included schemas the
- generated file depends on (C++).
+ generated file depends on (C++ / Python).
- `--gen-mutable` : Generate additional non-const accessors for mutating
FlatBuffers in-place.
@@ -117,6 +121,8 @@ Additional options:
output (by default the case for C++ and JS), all code will end up in
this one file.
+- `--cpp-include` : Adds an #include in generated file
+
- `--cpp-ptr-type T` : Set object API pointer type (default std::unique_ptr)
- `--cpp-str-type T` : Set object API string type (default std::string)
@@ -128,6 +134,11 @@ Additional options:
std::string from Flatbuffers, but (char* + length). This allows efficient
construction of custom string types, including zero-copy construction.
+- `--cpp-std CPP_STD` : Generate a C++ code using features of selected C++ standard.
+ Supported `CPP_STD` values:
+ * `c++0x` - generate code compatible with old compilers (VS2010).
+ * `c++11` - use C++11 code generator (default);
+
- `--object-prefix` : Customise class prefix for C++ object-based API.
- `--object-suffix` : Customise class suffix for C++ object-based API.
@@ -177,6 +188,13 @@ Additional options:
- `--conform-includes PATH` : Include path for the schema given with
`--conform PATH`.
+- `--filename-suffix SUFFIX` : The suffix appended to the generated
+ file names. Default is '_generated'.
+
+- `--filename-ext EXTENSION` : The extension appended to the generated
+ file names. Default is language-specific (e.g. "h" for C++). This
+ should not be used when multiple languages are specified.
+
- `--include-prefix PATH` : Prefix this path to any generated include
statements.
@@ -199,5 +217,8 @@ Additional options:
- `--force-empty` : When serializing from object API representation, force
strings and vectors to empty rather than null.
+- `--force-empty-vectors` : When serializing from object API representation, force
+ vectors to empty rather than null.
+
NOTE: short-form options for generators are deprecated, use the long form
whenever possible.
diff --git a/docs/source/CppUsage.md b/docs/source/CppUsage.md
index 6cf36d1f..6fec30c7 100644
--- a/docs/source/CppUsage.md
+++ b/docs/source/CppUsage.md
@@ -35,7 +35,7 @@ The test code itself is located in
[test.cpp](https://github.com/google/flatbuffers/blob/master/tests/test.cpp).
This test file is built alongside `flatc`. To review how to build the project,
-please read the [Building](@ref flatbuffers_guide_building) documenation.
+please read the [Building](@ref flatbuffers_guide_building) documentation.
To run the tests, execute `flattests` from the root `flatbuffers/` directory.
For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply
@@ -114,7 +114,7 @@ To use:
MonsterT monsterobj;
// Deserialize from buffer into object.
- UnPackTo(&monsterobj, flatbuffer);
+ GetMonster(flatbuffer)->UnPackTo(&monsterobj);
// Update object directly like a C++ class instance.
cout << monsterobj->name; // This is now a std::string!
@@ -122,7 +122,7 @@ To use:
// Serialize into new flatbuffer.
FlatBufferBuilder fbb;
- Pack(fbb, &monsterobj);
+ fbb.Finish(Monster::Pack(fbb, &monsterobj));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following attributes are specific to the object-based API code generation:
@@ -426,6 +426,8 @@ it, this will provide you an easy way to use that data directly.
(see the schema documentation for some specifics on the JSON format
accepted).
+Schema evolution compatibility for the JSON format follows the same rules as the binary format (JSON formatted data will be forwards/backwards compatible with schemas that evolve in a compatible way).
+
There are two ways to use text formats:
#### Using the compiler as a conversion tool
@@ -477,7 +479,7 @@ include paths. If not specified, any include statements try to resolve from
the current directory.
If there were any parsing errors, `Parse` will return `false`, and
-`Parser::err` contains a human readable error string with a line number
+`Parser::error_` contains a human readable error string with a line number
etc, which you should present to the creator of that file.
After each JSON file, the `Parser::fbb` member variable is the
@@ -546,21 +548,63 @@ locale-independent or locale-narrow functions `strtof_l`, `strtod_l`,
These functions use specified locale rather than the global or per-thread
locale instead. They are part of POSIX-2008 but not part of the C/C++
standard library, therefore, may be missing on some platforms.
-
The Flatbuffers library try to detect these functions at configuration and
compile time:
-- `_MSC_VER >= 1900`: check MSVC2012 or higher for MSVC buid
-- `_XOPEN_SOURCE>=700`: check POSIX-2008 for GCC/Clang build
-- `check_cxx_symbol_exists(strtof_l stdlib.h)`: CMake check of `strtod_f`
+- CMake `"CMakeLists.txt"`:
+ - Check existence of `strtol_l` and `strtod_l` in the `<stdlib.h>`.
+- Compile-time `"/include/base.h"`:
+ - `_MSC_VER >= 1900`: MSVC2012 or higher if build with MSVC.
+ - `_XOPEN_SOURCE>=700`: POSIX-2008 if build with GCC/Clang.
After detection, the definition `FLATBUFFERS_LOCALE_INDEPENDENT` will be
set to `0` or `1`.
+To override or stop this detection use CMake `-DFLATBUFFERS_LOCALE_INDEPENDENT={0|1}`
+or predefine `FLATBUFFERS_LOCALE_INDEPENDENT` symbol.
-It is possible to test the compatibility of the Flatbuffers library with
-a specific locale using the environment variable `FLATBUFFERS_TEST_LOCALE`:
+To test the compatibility of the Flatbuffers library with
+a specific locale use the environment variable `FLATBUFFERS_TEST_LOCALE`:
```sh
>FLATBUFFERS_TEST_LOCALE="" ./flattests
>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./flattests
```
+## Support of floating-point numbers
+The Flatbuffers library assumes that a C++ compiler and a CPU are
+compatible with the `IEEE-754` floating-point standard.
+The schema and json parser may fail if `fast-math` or `/fp:fast` mode is active.
+
+### Support of hexadecimal and special floating-point numbers
+According to the [grammar](@ref flatbuffers_grammar) `fbs` and `json` files
+may use hexadecimal and special (`NaN`, `Inf`) floating-point literals.
+The Flatbuffers uses `strtof` and `strtod` functions to parse floating-point
+literals. The Flatbuffers library has a code to detect a compiler compatibility
+with the literals. If necessary conditions are met the preprocessor constant
+`FLATBUFFERS_HAS_NEW_STRTOD` will be set to `1`.
+The support of floating-point literals will be limited at compile time
+if `FLATBUFFERS_HAS_NEW_STRTOD` constant is less than `1`.
+In this case, schemas with hexadecimal or special literals cannot be used.
+
+### Comparison of floating-point NaN values
+The floating-point `NaN` (`not a number`) is special value which
+representing an undefined or unrepresentable value.
+`NaN` may be explicitly assigned to variables, typically as a representation
+for missing values or may be a result of a mathematical operation.
+The `IEEE-754` defines two kind of `NaNs`:
+- Quiet NaNs, or `qNaNs`.
+- Signaling NaNs, or `sNaNs`.
+
+According to the `IEEE-754`, a comparison with `NaN` always returns
+an unordered result even when compared with itself. As a result, a whole
+Flatbuffers object will be not equal to itself if has one or more `NaN`.
+Flatbuffers scalar fields that have the default value are not actually stored
+in the serialized data but are generated in code (see [Writing a schema](@ref flatbuffers_guide_writing_schema)).
+Scalar fields with `NaN` defaults break this behavior.
+If a schema has a lot of `NaN` defaults the Flatbuffers can override
+the unordered comparison by the ordered: `(NaN==NaN)->true`.
+This ordered comparison is enabled when compiling a program with the symbol
+`FLATBUFFERS_NAN_DEFAULTS` defined.
+Additional computations added by `FLATBUFFERS_NAN_DEFAULTS` are very cheap
+if GCC or Clang used. These compilers have a compile-time implementation
+of `isnan` checking which MSVC does not.
+
<br>
diff --git a/docs/source/CsharpUsage.md b/docs/source/CsharpUsage.md
new file mode 100644
index 00000000..f7f585db
--- /dev/null
+++ b/docs/source/CsharpUsage.md
@@ -0,0 +1,175 @@
+Use in C# {#flatbuffers_guide_use_c-sharp}
+==============
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in C#, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
+general FlatBuffers usage in all of the supported languages (including C#).
+This page is designed to cover the nuances of FlatBuffers usage,
+specific to C#.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers C-sharp code location
+
+The code for the FlatBuffers C# library can be found at
+`flatbuffers/net/FlatBuffers`. You can browse the library on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
+FlatBuffers).
+
+## Testing the FlatBuffers C-sharp libraries
+
+The code to test the libraries can be found at `flatbuffers/tests`.
+
+The test code for C# is located in the [FlatBuffers.Test](https://github.com/
+google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
+tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
+https://www.visualstudio.com), and compile/run the project.
+
+Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
+Once you have installed `Mono`, you can run the tests from the command line
+by running the following commands from inside the `FlatBuffers.Test` folder:
+
+~~~{.sh}
+ mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
+ mono Assert.exe
+~~~
+
+## Using the FlatBuffers C# library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in C#.*
+
+FlatBuffers supports reading and writing binary FlatBuffers in C#.
+
+To use FlatBuffers in your own code, first generate C# classes from your
+schema with the `--csharp` option to `flatc`.
+Then you can include both FlatBuffers and the generated code to read
+or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in C#:
+First, import the library and generated code. Then, you read a FlatBuffer binary
+file into a `byte[]`. You then turn the `byte[]` into a `ByteBuffer`, which you
+pass to the `GetRootAsMyRootType` function:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
+ using MyGame.Example;
+ using FlatBuffers;
+
+ // This snippet ignores exceptions for brevity.
+ byte[] data = File.ReadAllBytes("monsterdata_test.mon");
+
+ ByteBuffer bb = new ByteBuffer(data);
+ Monster monster = Monster.GetRootAsMonster(bb);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access the data from the `Monster monster`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
+ short hp = monster.Hp;
+ Vec3 pos = monster.Pos;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+C# code naming follows standard C# style with `PascalCasing` identifiers,
+e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
+available as properties instead of parameterless accessor methods.
+The performance-enhancing methods to which you can pass an already created
+object are prefixed with `Get`, e.g.:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
+ // property
+ var pos = monster.Pos;
+
+ // method filling a preconstructed object
+ var preconstructedPos = new Vec3();
+ monster.GetPos(preconstructedPos);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+## Storing dictionaries in a FlatBuffer
+
+FlatBuffers doesn't support dictionaries natively, but there is support to
+emulate their behavior with vectors and binary search, which means you
+can have fast lookups directly from a FlatBuffer without having to unpack
+your data into a `Dictionary` or similar.
+
+To use it:
+- Designate one of the fields in a table as the "key" field. You do this
+ by setting the `key` attribute on this field, e.g.
+ `name:string (key)`.
+ You may only have one key field, and it must be of string or scalar type.
+- Write out tables of this type as usual, collect their offsets in an
+ array.
+- Instead of calling standard generated method,
+ e.g.: `Monster.createTestarrayoftablesVector`,
+ call `CreateSortedVectorOfMonster` in C#
+ which will first sort all offsets such that the tables they refer to
+ are sorted by the key field, then serialize it.
+- Now when you're accessing the FlatBuffer, you can use
+ the `ByKey` accessor to access elements of the vector, e.g.:
+ `monster.TestarrayoftablesByKey("Frodo")` in C#,
+ which returns an object of the corresponding table type,
+ or `null` if not found.
+ `ByKey` performs a binary search, so should have a similar
+ speed to `Dictionary`, though may be faster because of better caching.
+ `ByKey` only works if the vector has been sorted, it will
+ likely not find elements if it hasn't been sorted.
+
+## Text parsing
+
+There currently is no support for parsing text (Schema's and JSON) directly
+from C#, though you could use the C++ parser through native call
+interfaces available to each language. Please see the
+C++ documentation for more on text parsing.
+
+## Object based API
+
+FlatBuffers is all about memory efficiency, which is why its base API is written
+around using as little as possible of it. This does make the API clumsier
+(requiring pre-order construction of all data, and making mutation harder).
+
+For times when efficiency is less important a more convenient object based API
+can be used (through `--gen-object-api`) that is able to unpack & pack a
+FlatBuffer into objects and standard System.Collections.Generic containers, allowing for convenient
+construction, access and mutation.
+
+To use:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
+ // Deserialize from buffer into object.
+ MonsterT monsterobj = GetMonster(flatbuffer).UnPack();
+
+ // Update object directly like a C# class instance.
+ Console.WriteLine(monsterobj.Name);
+ monsterobj.Name = "Bob"; // Change the name.
+
+ // Serialize into new flatbuffer.
+ FlatBufferBuilder fbb = new FlatBufferBuilder(1);
+ fbb.Finish(Monster.Pack(fbb, monsterobj).Value);
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+### Json Serialization
+
+An additional feature of the object API is the ability to allow you to
+serialize & deserialize a JSON text.
+To use Json Serialization, add `--gen-json-serializer` option to `flatc` and
+add `Newtonsoft.Json` nuget package to csproj.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
+ // Deserialize MonsterT from json
+ string jsonText = File.ReadAllText(@"Resources/monsterdata_test.json");
+ MonsterT mon = MonsterT.DeserializeFromJson(jsonText);
+
+ // Serialize MonsterT to json
+ string jsonText2 = mon.SerializeToJson();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* Limitation
+ * `hash` attribute currentry not supported.
+* NuGet package Dependency
+ * [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)
+
+<br>
diff --git a/docs/source/FlatBuffers.md b/docs/source/FlatBuffers.md
index 7cc93b92..2a2133f7 100644
--- a/docs/source/FlatBuffers.md
+++ b/docs/source/FlatBuffers.md
@@ -4,7 +4,7 @@ FlatBuffers {#flatbuffers_index}
# Overview {#flatbuffers_overview}
[FlatBuffers](@ref flatbuffers_overview) is an efficient cross platform
-serialization library for C++, C#, C, Go, Java, JavaScript, Lobster, Lua, TypeScript, PHP, Python, and Rust.
+serialization library for C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift.
It was originally created at Google for game development and other
performance-critical applications.
@@ -51,7 +51,7 @@ under the Apache license, v2 (see LICENSE.txt).
needed (faster and more memory efficient than other JSON
parsers).
- Java and Go code supports object-reuse. C# has efficient struct based
+ Java, Kotlin and Go code supports object-reuse. C# has efficient struct based
accessors.
- **Cross platform code with no dependencies** - C++ code will work
@@ -108,7 +108,7 @@ sections provide a more in-depth usage guide.
present for every object instance.
- Use `flatc` (the FlatBuffer compiler) to generate a C++ header (or
- Java/C#/Go/Python.. classes) with helper classes to access and construct
+ Java/Kotlin/C#/Go/Python.. classes) with helper classes to access and construct
serialized data. This header (say `mydata_generated.h`) only depends on
`flatbuffers.h`, which defines the core functionality.
@@ -130,8 +130,12 @@ sections provide a more in-depth usage guide.
- How to [write a schema](@ref flatbuffers_guide_writing_schema).
- How to [use the generated C++ code](@ref flatbuffers_guide_use_cpp) in your
own programs.
-- How to [use the generated Java/C# code](@ref flatbuffers_guide_use_java_c-sharp)
+- How to [use the generated Java code](@ref flatbuffers_guide_use_java)
in your own programs.
+- How to [use the generated C# code](@ref flatbuffers_guide_use_c-sharp)
+ in your own programs.
+- How to [use the generated Kotlin code](@ref flatbuffers_guide_use_kotlin)
+ in your own programs.
- How to [use the generated Go code](@ref flatbuffers_guide_use_go) in your
own programs.
- How to [use the generated Lua code](@ref flatbuffers_guide_use_lua) in your
@@ -146,6 +150,8 @@ sections provide a more in-depth usage guide.
own programs.
- How to [use the generated Rust code](@ref flatbuffers_guide_use_rust) in your
own programs.
+- How to [use the generated Swift code](@ref flatbuffers_guide_use_swift) in your
+ own programs.
- [Support matrix](@ref flatbuffers_support) for platforms/languages/features.
- Some [benchmarks](@ref flatbuffers_benchmarks) showing the advantage of
using FlatBuffers.
@@ -161,6 +167,7 @@ sections provide a more in-depth usage guide.
- [GitHub repository](http://github.com/google/flatbuffers)
- [Landing page](http://google.github.io/flatbuffers)
- [FlatBuffers Google Group](https://groups.google.com/forum/#!forum/flatbuffers)
+- [Discord](https://discord.gg/6qgKs3R) and [Gitter](https://gitter.im/lobster_programming_language/community) chat.
- [FlatBuffers Issues Tracker](http://github.com/google/flatbuffers/issues)
- Independent implementations & tools:
- [FlatCC](https://github.com/dvidelabs/flatcc) Alternative FlatBuffers
@@ -176,3 +183,6 @@ sections provide a more in-depth usage guide.
- [FlatBuffers in Android](http://frogermcs.github.io/flatbuffers-in-android-introdution/)
- [Parsing JSON to FlatBuffers in Java](http://frogermcs.github.io/json-parsing-with-flatbuffers-in-android/)
- [FlatBuffers in Unity](http://exiin.com/blog/flatbuffers-for-unity-sample-code/)
+ - [FlexBuffers C#](https://github.com/mzaks/FlexBuffers-CSharp) and
+ [article](https://medium.com/@icex33/flexbuffers-for-unity3d-4d1ab5c53fbe?)
+ on its use.
diff --git a/docs/source/FlexBuffers.md b/docs/source/FlexBuffers.md
index a089df32..974dd693 100644
--- a/docs/source/FlexBuffers.md
+++ b/docs/source/FlexBuffers.md
@@ -29,9 +29,7 @@ FlexBuffers is still slower than regular FlatBuffers though, so we recommend to
only use it if you need it.
-# Usage
-
-This is for C++, other languages may follow.
+# Usage in C++
Include the header `flexbuffers.h`, which in turn depends on `flatbuffers.h`
and `util.h`.
@@ -98,10 +96,10 @@ allows a single type, and uses a bit less memory.
`IndirectFloat` is an interesting feature that allows you to store values
by offset rather than inline. Though that doesn't make any visible change
to the user, the consequence is that large values (especially doubles or
-64 bit ints) that occur more than once can be shared. Another use case is
-inside of vectors, where the largest element makes up the size of all elements
-(e.g. a single double forces all elements to 64bit), so storing a lot of small
-integers together with a double is more efficient if the double is indirect.
+64 bit ints) that occur more than once can be shared (see ReuseValue).
+Another use case is inside of vectors, where the largest element makes
+up the size of all elements (e.g. a single double forces all elements to
+64bit), so storing a lot of small integers together with a double is more efficient if the double is indirect.
Accessing it:
@@ -122,6 +120,46 @@ map["unknown"].IsNull(); // true
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+# Usage in Java
+
+Java implementation follows the C++ one, closely.
+
+For creating the equivalent of the same JSON `{ vec: [ -100, "Fred", 4.0 ], foo: 100 }`,
+one could use the following code:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
+FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
+ FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
+int smap = builder.startMap();
+int svec = builder.startVector();
+builder.putInt(-100);
+builder.putString("Fred");
+builder.putFloat(4.0);
+builder.endVector("vec", svec, false, false);
+builder.putInt("foo", 100);
+builder.endMap(null, smap);
+ByteBuffer bb = builder.finish();
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Similarly, to read the data, just:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
+FlexBuffers.Map map = FlexBuffers.getRoot(bb).asMap();
+map.size(); // 2
+FlexBuffers.Vector vec = map.get("vec").asVector();
+vec.size(); // 3
+vec.get(0).asLong(); // -100;
+vec.get(1).asString(); // "Fred";
+vec.get(1).asLong(); // 0 (Number parsing failed).
+vec.get(2).asFloat(); // 4.0
+vec.get(2).asString().isEmpty(); // true (Wrong Type).
+vec.get(2).asString(); // "" (This still works though).
+vec.get(2).toString(); // "4.0" (Or have it converted).
+map.get("foo").asUInt(); // 100
+map.get("unknown").isNull(); // true
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
# Binary encoding
A description of how FlexBuffers are encoded is in the
diff --git a/docs/source/Internals.md b/docs/source/Internals.md
index e8f453a8..d2064ca6 100644
--- a/docs/source/Internals.md
+++ b/docs/source/Internals.md
@@ -15,6 +15,12 @@ all commonly used CPUs today. FlatBuffers will also work on big-endian
machines, but will be slightly slower because of additional
byte-swap intrinsics.
+It is assumed that the following conditions are met, to ensure
+cross-platform interoperability:
+- The binary `IEEE-754` format is used for floating-point numbers.
+- The `two's complemented` representation is used for signed integers.
+- The endianness is the same for floating-point numbers as for integers.
+
On purpose, the format leaves a lot of details about where exactly
things live in memory undefined, e.g. fields in a table can have any
order, and objects to some extent can be stored in many orders. This is
diff --git a/docs/source/JavaCsharpUsage.md b/docs/source/JavaUsage.md
index 102ce371..30ba0613 100644
--- a/docs/source/JavaCsharpUsage.md
+++ b/docs/source/JavaUsage.md
@@ -1,41 +1,30 @@
-Use in Java/C# {#flatbuffers_guide_use_java_c-sharp}
+Use in Java {#flatbuffers_guide_use_java}
==============
## Before you get started
-Before diving into the FlatBuffers usage in Java or C#, it should be noted that
+Before diving into the FlatBuffers usage in Java, it should be noted that
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
-general FlatBuffers usage in all of the supported languages (including both Java
-and C#). This page is designed to cover the nuances of FlatBuffers usage,
-specific to Java and C#.
+general FlatBuffers usage in all of the supported languages (including Java).
+This page is designed to cover the nuances of FlatBuffers usage,
+specific to Java.
You should also have read the [Building](@ref flatbuffers_guide_building)
documentation to build `flatc` and should be familiar with
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
[Writing a schema](@ref flatbuffers_guide_writing_schema).
-## FlatBuffers Java and C-sharp code location
-
-#### Java
+## FlatBuffers Java code location
The code for the FlatBuffers Java library can be found at
`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
java/com/google/flatbuffers).
-#### C-sharp
-
-The code for the FlatBuffers C# library can be found at
-`flatbuffers/net/FlatBuffers`. You can browse the library on the
-[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
-FlatBuffers).
-
-## Testing the FlatBuffers Java and C-sharp libraries
+## Testing the FlatBuffers Java libraries
The code to test the libraries can be found at `flatbuffers/tests`.
-#### Java
-
The test code for Java is located in [JavaTest.java](https://github.com/google
/flatbuffers/blob/master/tests/JavaTest.java).
@@ -47,31 +36,15 @@ system.
*Note: These scripts require that [Java](https://www.oracle.com/java/index.html)
is installed.*
-#### C-sharp
-
-The test code for C# is located in the [FlatBuffers.Test](https://github.com/
-google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
-tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
-https://www.visualstudio.com), and compile/run the project.
-
-Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
-Once you have installed `Mono`, you can run the tests from the command line
-by running the following commands from inside the `FlatBuffers.Test` folder:
-
-~~~{.sh}
- mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
- mono Assert.exe
-~~~
-
-## Using the FlatBuffers Java (and C#) library
+## Using the FlatBuffers Java library
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
-example of how to use FlatBuffers in Java or C#.*
+example of how to use FlatBuffers in Java.*
-FlatBuffers supports reading and writing binary FlatBuffers in Java and C#.
+FlatBuffers supports reading and writing binary FlatBuffers in Java.
To use FlatBuffers in your own code, first generate Java classes from your
-schema with the `--java` option to `flatc`. (Or for C# with `--csharp`).
+schema with the `--java` option to `flatc`.
Then you can include both FlatBuffers and the generated code to read
or write a FlatBuffer.
@@ -80,11 +53,6 @@ First, import the library and generated code. Then, you read a FlatBuffer binary
file into a `byte[]`. You then turn the `byte[]` into a `ByteBuffer`, which you
pass to the `getRootAsMyRootType` function:
-*Note: The code here is written from the perspective of Java. Code for both
-languages is both generated and used in nearly the exact same way, with only
-minor differences. These differences are
-[explained in a section below](#differences_in_c-sharp).*
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
import MyGame.Example.*;
import com.google.flatbuffers.FlatBufferBuilder;
@@ -107,30 +75,6 @@ Now you can access the data from the `Monster monster`:
Vec3 pos = monster.pos();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-<a name="differences_in_c-sharp">
-#### Differences in C-sharp
-</a>
-
-C# code works almost identically to Java, with only a few minor differences.
-You can see an example of C# code in
-`tests/FlatBuffers.Test/FlatBuffersExampleTests.cs` or
-`samples/SampleBinary.cs`.
-
-First of all, naming follows standard C# style with `PascalCasing` identifiers,
-e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
-available as properties instead of parameterless accessor methods as in Java.
-The performance-enhancing methods to which you can pass an already created
-object are prefixed with `Get`, e.g.:
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
- // property
- var pos = monster.Pos;
-
- // method filling a preconstructed object
- var preconstructedPos = new Vec3();
- monster.GetPos(preconstructedPos);
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
## Storing dictionaries in a FlatBuffer
FlatBuffers doesn't support dictionaries natively, but there is support to
@@ -147,14 +91,12 @@ To use it:
array.
- Instead of calling standard generated method,
e.g.: `Monster.createTestarrayoftablesVector`,
- call `CreateSortedVectorOfMonster` in C# or
- `createSortedVectorOfTables` (from the `FlatBufferBuilder` object) in Java,
+ call `createSortedVectorOfTables` (from the `FlatBufferBuilder` object).
which will first sort all offsets such that the tables they refer to
are sorted by the key field, then serialize it.
- Now when you're accessing the FlatBuffer, you can use
the `ByKey` accessor to access elements of the vector, e.g.:
- `monster.testarrayoftablesByKey("Frodo")` in Java or
- `monster.TestarrayoftablesByKey("Frodo")` in C#,
+ `monster.testarrayoftablesByKey("Frodo")`.
which returns an object of the corresponding table type,
or `null` if not found.
`ByKey` performs a binary search, so should have a similar
@@ -165,7 +107,7 @@ To use it:
## Text parsing
There currently is no support for parsing text (Schema's and JSON) directly
-from Java or C#, though you could use the C++ parser through native call
+from Java, though you could use the C++ parser through native call
interfaces available to each language. Please see the
C++ documentation for more on text parsing.
diff --git a/docs/source/KotlinUsage.md b/docs/source/KotlinUsage.md
new file mode 100644
index 00000000..092fcd7f
--- /dev/null
+++ b/docs/source/KotlinUsage.md
@@ -0,0 +1,84 @@
+Use in Kotlin {#flatbuffers_guide_use_kotlin}
+==============
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Kotlin, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
+general FlatBuffers usage in all of the supported languages (including K).
+
+This page is designed to cover the nuances of FlatBuffers usage, specific to Kotlin.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## Kotlin and FlatBuffers Java code location
+
+Code generated for Kotlin currently uses the flatbuffers java runtime library. That means that Kotlin generated code can only have Java virtual machine as target architecture (which includes Android). Kotlin Native and Kotlin.js are currently not supported.
+
+The code for the FlatBuffers Java library can be found at
+`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
+[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
+java/com/google/flatbuffers).
+
+## Testing FlatBuffers Kotlin
+
+The test code for Java is located in [KotlinTest.java](https://github.com/google
+/flatbuffers/blob/master/tests/KotlinTest.kt).
+
+To run the tests, use [KotlinTest.sh](https://github.com/google/
+flatbuffers/blob/master/tests/KotlinTest.sh) shell script.
+
+*Note: These scripts require that [Kotlin](https://kotlinlang.org/) is installed.*
+
+## Using the FlatBuffers Kotlin library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Kotlin.*
+
+FlatBuffers supports reading and writing binary FlatBuffers in Kotlin.
+
+To use FlatBuffers in your own code, first generate Java classes from your
+schema with the `--kotlin` option to `flatc`.
+Then you can include both FlatBuffers and the generated code to read
+or write a FlatBuffer.
+
+For example, here is how you would read a FlatBuffer binary file in Kotlin:
+First, import the library and generated code. Then, you read a FlatBuffer binary
+file into a `ByteArray`. You then turn the `ByteArray` into a `ByteBuffer`, which you
+pass to the `getRootAsMyRootType` function:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
+ import MyGame.Example.*
+ import com.google.flatbuffers.FlatBufferBuilder
+
+ // This snippet ignores exceptions for brevity.
+ val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
+ val temp = ByteArray(it.length().toInt())
+ it.readFully(temp)
+ temp
+ }
+
+ val bb = ByteBuffer.wrap(data)
+ val monster = Monster.getRootAsMonster(bb)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access the data from the `Monster monster`:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
+ val hp = monster.hp
+ val pos = monster.pos!!;
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+## Differences between Kotlin and Java code
+
+Kotlin generated code was designed to be as close as possible to the java counterpart, as for now, we only support kotlin on java virtual machine. So the differences in implementation and usage are basically the ones introduced by the Kotlin language itself. You can find more in-depth information [here](https://kotlinlang.org/docs/reference/comparison-to-java.html).
+
+The most obvious ones are:
+
+* Fields as accessed as Kotlin [properties](https://kotlinlang.org/docs/reference/properties.html)
+* Static methods are accessed in [companion object](https://kotlinlang.org/docs/reference/classes.html#companion-objects) \ No newline at end of file
diff --git a/docs/source/Schemas.md b/docs/source/Schemas.md
index 4f7bd728..bd119b0b 100644
--- a/docs/source/Schemas.md
+++ b/docs/source/Schemas.md
@@ -114,6 +114,27 @@ of same-size data where a `reinterpret_cast` would give you a desirable result,
e.g. you could change a `uint` to an `int` if no values in current data use the
high bit yet.
+### Arrays
+
+Arrays are a convenience short-hand for a fixed-length collection of elements.
+Arrays can be used to replace the following schema:
+
+ struct Vec3 {
+ x:float;
+ y:float;
+ z:float;
+ }
+
+with the following schema:
+
+ struct Vec3 {
+ v:[float:3];
+ }
+
+Both representations are binary equivalent.
+
+Arrays are currently only supported in a `struct`.
+
### (Default) Values
Values are a sequence of digits. Values may be optionally followed by a decimal
@@ -324,6 +345,9 @@ Current understood attributes:
Note: currently not guaranteed to have an effect when used with
`--object-api`, since that may allocate objects at alignments less than
what you specify with `force_align`.
+- `force_align: size` (on a vector): force the alignment of this vector to be
+ something different than what the element size would normally dictate.
+ Note: Now only work for generated C++ code.
- `bit_flags` (on an unsigned enum): the values of this field indicate bits,
meaning that any unsigned value N specified in the schema will end up
representing 1<<N, or if you don't specify values at all, you'll get
@@ -418,14 +442,19 @@ numerical literals:
For example: `[0x123, +0x45, -0x67]` are equal to `[291, 69, -103]` decimals.
- The format of float-point numbers is fully compatible with C/C++ format.
If a modern C++ compiler is used the parser accepts hexadecimal and special
- float-point literals as well:
+ floating-point literals as well:
`[-1.0, 2., .3e0, 3.e4, 0x21.34p-5, -inf, nan]`.
- The exponent suffix of hexadecimal float-point number is mandatory.
- Extended float-point support was tested with:
+ The following conventions for floating-point numbers are used:
+ - The exponent suffix of hexadecimal floating-point number is mandatory.
+ - Parsed `NaN` converted to unsigned IEEE-754 `quiet-NaN` value.
+
+ Extended floating-point support was tested with:
- x64 Windows: `MSVC2015` and higher.
- x64 Linux: `LLVM 6.0`, `GCC 4.9` and higher.
+ For details, see [Use in C++](@ref flatbuffers_guide_use_cpp) section.
+
- For compatibility with a JSON lint tool all numeric literals of scalar
fields can be wrapped to quoted string:
`"1", "2.0", "0x48A", "0x0C.0Ep-1", "-inf", "true"`.
@@ -537,7 +566,7 @@ with the new schema now cannot read nor write `a` anymore (any existing code
that tries to do so will result in compile errors), but can still read
old data (they will ignore the field).
- table { c:int a:int; b:int; }
+ table { c:int; a:int; b:int; }
This is NOT ok, as this makes the schemas incompatible. Old code reading newer
data will interpret `c` as if it was `a`, and new code reading old data
diff --git a/docs/source/Support.md b/docs/source/Support.md
index c8ac7f7e..1e435a66 100644
--- a/docs/source/Support.md
+++ b/docs/source/Support.md
@@ -18,23 +18,23 @@ In general:
NOTE: this table is a start, it needs to be extended.
-Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Dart | Lobster | Rust
------------------------------- | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ----
-Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes
-JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No
-Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No
-Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No
-Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No
-Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes
-Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes
-Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb
-Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes
-Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes
-Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes
-Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ?
-Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ?
-Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | No | ?
-Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | evanw/ev* | kr* | mik* | ch* | dnfield | aard* | rw
+Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Dart | Lobster | Rust | Swift
+------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ------- | ------
+Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes | Yes
+JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No | No
+Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No | No
+Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No
+Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | No
+Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes
+Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes | No
+Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb | ?
+Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes | No
+Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes
+Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes
+Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ? | No
+Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ? | Yes
+Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | No | ? | No
+Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | evanw/ev* | kr* | mik* | ch* | dnfield | aard* | rw | mi*/mz*
* aard = aardappel (previously: gwvo)
* ev = evolutional
@@ -42,5 +42,7 @@ Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | ev
* mik = mikkelfj
* ch = chobie
* kr = krojew
+ * mi = mustiikhalil
+ * mz = mzaks
<br>
diff --git a/docs/source/SwiftUsage.md b/docs/source/SwiftUsage.md
new file mode 100644
index 00000000..d5640f6c
--- /dev/null
+++ b/docs/source/SwiftUsage.md
@@ -0,0 +1,91 @@
+Use in Swift {#flatbuffers_guide_use_swift}
+=========
+
+## Before you get started
+
+Before diving into the FlatBuffers usage in Swift, it should be noted that
+the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide
+to general FlatBuffers usage in all of the supported languages (including Swift).
+This page is designed to cover the nuances of FlatBuffers usage, specific to
+Swift.
+
+You should also have read the [Building](@ref flatbuffers_guide_building)
+documentation to build `flatc` and should be familiar with
+[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
+[Writing a schema](@ref flatbuffers_guide_writing_schema).
+
+## FlatBuffers Swift library code location
+
+The code for the FlatBuffers Swift library can be found at
+`flatbuffers/swift`. You can browse the library code on the [FlatBuffers
+GitHub page](https://github.com/google/flatbuffers/tree/master/swift).
+
+## Testing the FlatBuffers Swift library
+
+The code to test the Swift library can be found at `flatbuffers/Flatbuffers.Test.Swift`.
+The test code itself is located in [Flatbuffers.Test.Swift](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift).
+
+To run the tests, use the [SwiftTest.sh](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift/SwiftTest.sh) shell script.
+
+*Note: The shell script requires [Swift](https://swift.org) to
+be installed.*
+
+## Using the FlatBuffers Swift library
+
+*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
+example of how to use FlatBuffers in Swift.*
+
+FlatBuffers supports reading and writing binary FlatBuffers in Swift.
+
+To use FlatBuffers in your own code, first generate Swift structs from your
+schema with the `--swift` option to `flatc`. Then include FlatBuffers using `SPM` in
+by adding the path to `FlatBuffers/swift` into it. The generated code should also be
+added to xcode or the path of the package you will be using. Note: sometimes xcode cant
+and wont see the generated files, so it's better that you copy them to xcode.
+
+For example, here is how you would read a FlatBuffer binary file in Swift: First,
+include the library and copy thegenerated code. Then read a FlatBuffer binary file or
+a data object from the server, which you can pass into the `GetRootAsMonster` function.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
+ import FlatBuffers
+
+ typealias Monster1 = MyGame.Sample.Monster
+ typealias Vec3 = MyGame.Sample.Vec3
+
+ let path = FileManager.default.currentDirectoryPath
+ let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon")
+ guard let data = try? Data(contentsOf: url) else { return }
+
+ let monster = Monster.getRootAsMonster(bb: ByteBuffer(data: data))
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now you can access values like this:
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
+ let hp = monster.hp
+ let pos = monster.pos
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+In some cases it's necessary to modify values in an existing FlatBuffer in place (without creating a copy). For this reason, scalar fields of a Flatbuffer table or struct can be mutated.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
+ let monster = Monster.getRootAsMonster(bb: ByteBuffer(data: data))
+
+ if !monster.mutate(hp: 10) {
+ fatalError("couldn't mutate")
+ }
+ // mutate a struct field
+ let vec = monster.pos.mutate(z: 4)
+
+ // This mutation will fail because the mana field is not available in
+ // the buffer. It should be set when creating the buffer.
+ if !monster.mutate(mana: 20) {
+ fatalError("couldn't mutate")
+ }
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The term `mutate` is used instead of `set` to indicate that this is a special use case. All mutate functions return a boolean value which is false if the field we're trying to mutate is not available in the buffer.
+
+<br>
diff --git a/docs/source/Tutorial.md b/docs/source/Tutorial.md
index e23068b6..c0f3b9e7 100644
--- a/docs/source/Tutorial.md
+++ b/docs/source/Tutorial.md
@@ -23,6 +23,7 @@ Please select your desired language for our quest:
<form>
<input type="radio" name="language" value="cpp" checked="checked">C++</input>
<input type="radio" name="language" value="java">Java</input>
+ <input type="radio" name="language" value="kotlin">Kotlin</input>
<input type="radio" name="language" value="csharp">C#</input>
<input type="radio" name="language" value="go">Go</input>
<input type="radio" name="language" value="python">Python</input>
@@ -34,6 +35,7 @@ Please select your desired language for our quest:
<input type="radio" name="language" value="lua">Lua</input>
<input type="radio" name="language" value="lobster">Lobster</input>
<input type="radio" name="language" value="rust">Rust</input>
+ <input type="radio" name="language" value="swift">Swift</input>
</form>
\endhtmlonly
@@ -115,6 +117,9 @@ For your chosen language, please cross-reference with:
<div class="language-java">
[SampleBinary.java](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.java)
</div>
+<div class="language-kotlin">
+[SampleBinary.kt](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.kt)
+</div>
<div class="language-csharp">
[SampleBinary.cs](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.cs)
</div>
@@ -148,6 +153,9 @@ For your chosen language, please cross-reference with:
<div class="language-rust">
[sample_binary.rs](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs)
</div>
+<div class="language-swift">
+[sample_binary.swift](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.swift)
+</div>
## Writing the Monsters' FlatBuffer Schema
@@ -284,6 +292,12 @@ Please be aware of the difference between `flatc` and `flatcc` tools.
./../flatc --java monster.fbs
~~~
</div>
+<div class="language-kotlin">
+~~~{.sh}
+ cd flatbuffers/samples
+ ./../flatc --kotlin monster.fbs
+~~~
+</div>
<div class="language-csharp">
~~~{.sh}
cd flatbuffers/samples
@@ -353,6 +367,12 @@ Please be aware of the difference between `flatc` and `flatcc` tools.
./../flatc --rust monster.fbs
~~~
</div>
+<div class="language-swift">
+~~~{.sh}
+ cd flatbuffers/samples
+ ./../flatc --swift monster.fbs
+~~~
+</div>
For a more complete guide to using the `flatc` compiler, please read the
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
@@ -382,6 +402,13 @@ The first step is to import/include the library, generated files, etc.
import com.google.flatbuffers.FlatBufferBuilder;
~~~
</div>
+<div class="language-kotlin">
+~~~{.kotlin}
+ import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
+
+ import com.google.flatbuffers.FlatBufferBuilder
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
using FlatBuffers;
@@ -424,7 +451,7 @@ The first step is to import/include the library, generated files, etc.
~~~
</div>
<div class="language-typescript">
- // note: import flabuffers with your desired import method
+ // note: import flatbuffers with your desired import method
import { MyGame } from './monster_generated';
</div>
@@ -485,8 +512,8 @@ The first step is to import/include the library, generated files, etc.
</div>
<div class="language-lobster">
~~~{.lobster}
- include from "../lobster/" // Where to find flatbuffers.lobster
- include "monster_generated.lobster"
+ import from "../lobster/" // Where to find flatbuffers.lobster
+ import monster_generated
~~~
</div>
<div class="language-rust">
@@ -506,6 +533,21 @@ The first step is to import/include the library, generated files, etc.
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ /**
+ // make sure that monster_generated.swift is included in your project
+ */
+ import Flatbuffers
+
+ // typealiases for convenience
+ typealias Monster = MyGame1.Sample.Monster
+ typealias Weapon = MyGame1.Sample.Weapon
+ typealias Color = MyGame1.Sample.Color
+ typealias Vec3 = MyGame1.Sample.Vec3
+~~~
+</div>
+
Now we are ready to start building some buffers. In order to start, we need
to create an instance of the `FlatBufferBuilder`, which will contain the buffer
as it grows. You can pass an initial size of the buffer (here 1024 bytes),
@@ -525,6 +567,13 @@ which will grow automatically if needed:
FlatBufferBuilder builder = new FlatBufferBuilder(1024);
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ // Create a `FlatBufferBuilder`, which will be used to create our
+ // monsters' FlatBuffers.
+ val builder = FlatBufferBuilder(1024)
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
// Create a `FlatBufferBuilder`, which will be used to create our
@@ -592,7 +641,7 @@ which will grow automatically if needed:
</div>
<div class="language-lobster">
~~~{.lobster}
- -- get access to the builder
+ // get access to the builder
let builder = flatbuffers_builder {}
~~~
</div>
@@ -603,6 +652,12 @@ which will grow automatically if needed:
let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(1024);
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // create a `FlatBufferBuilder`, which will be used to serialize objects
+ let builder = FlatBufferBuilder(initialSize: 1024)
+~~~
+</div>
After creating the `builder`, we can start serializing our data. Before we make
our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
@@ -633,6 +688,19 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ val weaponOneName = builder.createString("Sword")
+ val weaponOneDamage: Short = 3;
+
+ val weaponTwoName = builder.createString("Axe")
+ val weaponTwoDamage: Short = 5;
+
+ // Use the `createWeapon()` helper function to create the weapons, since we set every field.
+ val sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage)
+ val axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage)
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
var weaponOneName = builder.CreateString("Sword");
@@ -813,12 +881,13 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
let weapon_names = [ "Sword", "Axe" ]
let weapon_damages = [ 3, 5 ]
- weapon_offsets := map(weapon_names) name, i:
+ let weapon_offsets = map(weapon_names) name, i:
let ns = builder.CreateString(name)
- builder.MyGame_Sample_WeaponStart()
- builder.MyGame_Sample_WeaponAddName(ns)
- builder.MyGame_Sample_WeaponAddDamage(weapon_damages[i])
- builder.MyGame_Sample_WeaponEnd()
+ MyGame_Sample_WeaponBuilder { b }
+ .start()
+ .add_name(ns)
+ .add_damage(weapon_damages[i])
+ .end()
~~~
</div>
<div class="language-rust">
@@ -840,6 +909,25 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ let weapon1Name = builder.create(string: "Sword")
+ let weapon2Name = builder.create(string: "Axe")
+
+ // start creating the weapon by calling startWeapon
+ let weapon1Start = Weapon.startWeapon(builder)
+ Weapon.add(name: weapon1Name, builder)
+ Weapon.add(damage: 3, builder)
+ // end the object by passing the start point for the weapon 1
+ let sword = Weapon.endWeapon(builder, start: weapon1Start)
+
+ let weapon2Start = Weapon.startWeapon(builder)
+ Weapon.add(name: weapon2Name, builder)
+ Weapon.add(damage: 5, builder)
+ let axe = Weapon.endWeapon(builder, start: weapon2Start)
+~~~
+</div>
+
Now let's create our monster, the `orc`. For this `orc`, lets make him
`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him
a large pool of hit points with `300`. We can give him a vector of weapons
@@ -874,6 +962,17 @@ traversal. This is generally easy to do on any tree structures.
int inv = Monster.createInventoryVector(builder, treasure);
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ // Serialize a name for our monster, called "Orc".
+ val name = builder.createString("Orc")
+
+ // Create a `vector` representing the inventory of the Orc. Each number
+ // could correspond to an item that can be claimed after he is slain.
+ val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+ val inv = Monster.createInventoryVector(builder, treasure)
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
// Serialize a name for our monster, called "Orc".
@@ -1019,6 +1118,16 @@ traversal. This is generally easy to do on any tree structures.
let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // Name of the Monster.
+ let name = builder.create(string: "Orc")
+
+ // create inventory
+ let inventory: [Byte] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ let inventoryOffset = builder.createVector(inventory)
+~~~
+</div>
We serialized two built-in data types (`string` and `vector`) and captured
their return values. These values are offsets into the serialized data,
@@ -1059,6 +1168,16 @@ offsets.
int weapons = Monster.createWeaponsVector(builder, weaps);
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ // Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
+ // create a FlatBuffer vector.
+ val weaps = intArrayOf(sword, axe)
+
+ // Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
+ val weapons = Monster.createWeaponsVector(builder, weaps)
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
var weaps = new Offset<Weapon>[2];
@@ -1153,6 +1272,13 @@ offsets.
let weapons = builder.create_vector(&[sword, axe]);
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // Create a FlatBuffer `vector` that contains offsets to the sword and axe
+ // we created above.
+ let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
+~~~
+</div>
<br>
Note there's additional convenience overloads of `CreateVector`, allowing you
@@ -1179,6 +1305,14 @@ for the `path` field above:
int path = fbb.endVector();
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ Monster.startPathVector(fbb, 2)
+ Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)
+ Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f)
+ val path = fbb.endVector()
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
Monster.StartPathVector(fbb, 2);
@@ -1281,6 +1415,15 @@ for the `path` field above:
// let path = builder.create_vector(&[&x, &y]);
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ //
+ let points = builder.createVector(structs: [MyGame.Sample.createVec3(x: 1, y: 2, z: 3),
+ MyGame.Sample.createVec3(x: 4, y: 5, z: 6)],
+ type: Vec3.self)
+~~~
+</div>
+
We have now serialized the non-scalar components of the orc, so we
can serialize the monster itself:
@@ -1317,6 +1460,22 @@ can serialize the monster itself:
int orc = Monster.endMonster(builder);
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ // Create our monster using `startMonster()` and `endMonster()`.
+ Monster.startMonster(builder)
+ Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f))
+ Monster.addName(builder, name)
+ Monster.addColor(builder, Color.Red)
+ Monster.addHp(builder, 300.toShort())
+ Monster.addInventory(builder, inv)
+ Monster.addWeapons(builder, weapons)
+ Monster.addEquippedType(builder, Equipment.Weapon)
+ Monster.addEquipped(builder, axe)
+ Monster.addPath(builder, path)
+ val orc = Monster.endMonster(builder)
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
// Create our monster using `StartMonster()` and `EndMonster()`.
@@ -1503,17 +1662,18 @@ can serialize the monster itself:
</div>
<div class="language-lobster">
~~~{.lobster}
- builder.MyGame_Sample_MonsterStart()
- builder.MyGame_Sample_MonsterAddPos(builder.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
- builder.MyGame_Sample_MonsterAddHp(300)
- builder.MyGame_Sample_MonsterAddName(name)
- builder.MyGame_Sample_MonsterAddInventory(inv)
- builder.MyGame_Sample_MonsterAddColor(MyGame_Sample_Color_Red)
- builder.MyGame_Sample_MonsterAddWeapons(weapons)
- builder.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
- builder.MyGame_Sample_MonsterAddEquipped(weapon_offsets[1])
- builder.MyGame_Sample_MonsterAddPath(path)
- let orc = builder.MyGame_Sample_MonsterEnd()
+ let orc = MyGame_Sample_MonsterBuilder { b }
+ .start()
+ .add_pos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
+ .add_hp(300)
+ .add_name(name)
+ .add_inventory(inv)
+ .add_color(MyGame_Sample_Color_Red)
+ .add_weapons(weapons)
+ .add_equipped_type(MyGame_Sample_Equipment_Weapon)
+ .add_equipped(weapon_offsets[1])
+ .add_path(path)
+ .end()
~~~
</div>
<div class="language-rust">
@@ -1537,6 +1697,19 @@ can serialize the monster itself:
});
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ let orc = Monster.createMonster(builder,
+ offsetOfPos: pos,
+ hp: 300,
+ offsetOfName: name,
+ vectorOfInventory: inventoryOffset,
+ color: .red,
+ vectorOfWeapons: weaponsOffset,
+ equippedType: .weapon,
+ offsetOfEquipped: axe)
+~~~
+</div>
Note how we create `Vec3` struct in-line in the table. Unlike tables, structs
are simple combinations of scalars that are always stored inline, just like
@@ -1602,6 +1775,21 @@ a bit more flexibility.
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ let start = Monster.startMonster(builder)
+ Monster.add(pos: pos, builder)
+ Monster.add(hp: 300, builder)
+ Monster.add(name: name, builder)
+ Monster.addVectorOf(inventory: inventoryOffset, builder)
+ Monster.add(color: .red, builder)
+ Monster.addVectorOf(weapons: weaponsOffset, builder)
+ Monster.add(equippedType: .weapon, builder)
+ Monster.add(equipped: axe, builder)
+ var orc = Monster.endMonster(builder, start: start)
+~~~
+</div>
+
Before finishing the serialization, let's take a quick look at FlatBuffer
`union Equipped`. There are two parts to each FlatBuffer `union`. The first, is
a hidden field `_type`, that is generated to hold the type of `table` referred
@@ -1625,6 +1813,12 @@ Here is a repetition these lines, to help highlight them more clearly:
Monster.addEquipped(axe); // Union data
~~~
</div>
+<div class="language-kotlin">
+ ~~~{.kt}
+ Monster.addEquippedType(builder, Equipment.Weapon) // Union type
+ Monster.addEquipped(axe) // Union data
+ ~~~
+</div>
<div class="language-csharp">
~~~{.cs}
Monster.AddEquippedType(builder, Equipment.Weapon); // Union type
@@ -1687,8 +1881,8 @@ Here is a repetition these lines, to help highlight them more clearly:
</div>
<div class="language-lobster">
~~~{.lobster}
- builder.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
- builder.MyGame_Sample_MonsterAddEquipped(axe)
+ .add_equipped_type(MyGame_Sample_Equipment_Weapon)
+ .add_equipped(axe)
~~~
</div>
<div class="language-rust">
@@ -1699,6 +1893,13 @@ Here is a repetition these lines, to help highlight them more clearly:
monster_builder.add_equipped(axe.as_union_value()); // Union data
~~~
</div>
+<div class="language-swift">
+ ~~~{.swift}
+ Monster.add(equippedType: .weapon, builder) // Type of union
+ Monster.add(equipped: axe, builder) // Union data
+ ~~~
+</div>
+
After you have created your buffer, you will have the offset to the root of the
data in the `orc` variable, so you can finish the buffer by calling the
@@ -1720,6 +1921,12 @@ appropriate `finish` method.
builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ // Call `finish()` to instruct the builder that this monster is complete.
+ builder.finish(orc) // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
// Call `Finish()` to instruct the builder that this monster is complete.
@@ -1788,6 +1995,12 @@ appropriate `finish` method.
builder.finish(orc, None);
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // Call `finish(offset:)` to instruct the builder that this monster is complete.
+ builder.finish(offset: orc)
+~~~
+</div>
The buffer is now ready to be stored somewhere, sent over the network, be
compressed, or whatever you'd like to do with it. You can access the buffer
@@ -1812,6 +2025,17 @@ like so:
byte[] buf = builder.sizedByteArray();
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ // This must be called after `finish()`.
+ val buf = builder.dataBuffer()
+ // The data in this ByteBuffer does NOT start at 0, but at buf.position().
+ // The number of bytes is buf.remaining().
+
+ // Alternatively this copies the above data out of the ByteBuffer for you:
+ val buf = builder.sizedByteArray()
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
// This must be called after `Finish()`.
@@ -1905,6 +2129,15 @@ like so:
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // This must be called after `finish()`.
+ // `sizedByteArray` returns the finished buf of type [UInt8].
+ let buf = builder.sizedByteArray
+ // or you can use to get an object of type Data
+ let bufData = ByteBuffer(data: builder.data)
+~~~
+</div>
Now you can write the bytes to a file, send them over the network..
**Make sure your file mode (or transfer protocol) is set to BINARY, not text.**
@@ -1934,6 +2167,13 @@ before:
import com.google.flatbuffers.FlatBufferBuilder;
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
+
+ import com.google.flatbuffers.FlatBufferBuilder
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
using FlatBuffers;
@@ -2033,8 +2273,8 @@ import './monster_my_game.sample_generated.dart' as myGame;
</div>
<div class="language-lobster">
~~~{.lobster}
- include from "../lobster/" // Where to find flatbuffers.lobster
- include "monster_generated.lobster"
+ import from "../lobster/" // Where to find flatbuffers.lobster
+ import monster_generated
~~~
</div>
<div class="language-rust">
@@ -2082,6 +2322,15 @@ won't work**
Monster monster = Monster.getRootAsMonster(buf);
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ val bytes = /* the data you just read */
+ val buf = java.nio.ByteBuffer.wrap(bytes)
+
+ // Get an accessor to the root object inside the buffer.
+ Monster monster = Monster.getRootAsMonster(buf)
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
byte[] bytes = /* the data you just read */
@@ -2189,6 +2438,16 @@ myGame.Monster monster = new myGame.Monster(data);
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // create a ByteBuffer(:) from an [UInt8] or Data()
+ let buf = // Get your data
+
+ // Get an accessor to the root object inside the buffer.
+ let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
+~~~
+</div>
+
If you look in the generated files from the schema compiler, you will see it generated
accessors for all non-`deprecated` fields. For example:
@@ -2206,6 +2465,13 @@ accessors for all non-`deprecated` fields. For example:
String name = monster.name();
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ val hp = monster.hp
+ val mana = monster.mana
+ val name = monster.name
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
// For C#, unlike most other languages support by FlatBuffers, most values (except for
@@ -2289,6 +2555,14 @@ accessors for all non-`deprecated` fields. For example:
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ let hp = monster.hp
+ let mana = monster.mana
+ let name = monster.name // returns an optional string
+~~~
+</div>
+
These should hold `300`, `150`, and `"Orc"` respectively.
*Note: The default value `150` wasn't stored in `mana`, but we are still able to retrieve it.*
@@ -2311,6 +2585,14 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
float z = pos.z();
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ val pos = monster.pos!!
+ val x = pos.x
+ val y = pos.y
+ val z = pos.z
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
var pos = monster.Pos.Value;
@@ -2406,6 +2688,15 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ let pos = monster.pos
+ let x = pos.x
+ let y = pos.y
+ let z = pos.z
+~~~
+</div>
+
`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.
*Note: Had we not set `pos` during serialization, it would be a `NULL`-value.*
@@ -2417,7 +2708,7 @@ FlatBuffers `vector`.
<div class="language-cpp">
~~~{.cpp}
auto inv = monster->inventory(); // A pointer to a `flatbuffers::Vector<>`.
- auto inv_len = inv->Length();
+ auto inv_len = inv->size();
auto third_item = inv->Get(2);
~~~
</div>
@@ -2427,6 +2718,12 @@ FlatBuffers `vector`.
byte thirdItem = monster.inventory(2);
~~~
</div>
+<div class="language-kotlin">
+~~~{.kotlin}
+ val invLength = monster.inventoryLength
+ val thirdItem = monster.inventory(2)!!
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
int invLength = monster.InventoryLength;
@@ -2500,13 +2797,27 @@ FlatBuffers `vector`.
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // Get a the count of objects in the vector
+ let count = monster.inventoryCount
+
+ // get item at index 4
+ let object = monster.inventory(at: 4)
+
+ // or you can fetch the entire array
+ let inv = monster.inventory
+ // inv[4] should equal object
+~~~
+</div>
+
For `vector`s of `table`s, you can access the elements like any other vector,
except your need to handle the result as a FlatBuffer `table`:
<div class="language-cpp">
~~~{.cpp}
auto weapons = monster->weapons(); // A pointer to a `flatbuffers::Vector<>`.
- auto weapon_len = weapons->Length();
+ auto weapon_len = weapons->size();
auto second_weapon_name = weapons->Get(1)->name()->str();
auto second_weapon_damage = weapons->Get(1)->damage()
~~~
@@ -2518,6 +2829,13 @@ except your need to handle the result as a FlatBuffer `table`:
short secondWeaponDamage = monster.weapons(1).damage();
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ val weaponsLength = monster.weaponsLength
+ val secondWeaponName = monster.weapons(1)!!.name
+ val secondWeaponDamage = monster.weapons(1)!!.damage
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
int weaponsLength = monster.WeaponsLength;
@@ -2605,6 +2923,16 @@ except your need to handle the result as a FlatBuffer `table`:
let second_weapon_damage = wep2.damage();
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // Get the count of weapon objects
+ let wepsCount = monster.weaponsCount
+
+ let weapon2 = monster.weapons(at: 1)
+ let weaponName = weapon2.name
+ let weaponDmg = weapon2.damage
+~~~
+</div>
Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created
the `union`, we need to get both parts of the `union`: the type and the data.
@@ -2638,6 +2966,19 @@ We can access the type to dynamically cast the data as needed (since the
}
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ val unionType = monster.EquippedType
+
+ if (unionType == Equipment.Weapon) {
+ val weapon = monster.equipped(Weapon()) as Weapon // Requires explicit cast
+ // to `Weapon`.
+
+ val weaponName = weapon.name // "Axe"
+ val weaponDamage = weapon.damage // 5
+ }
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
var unionType = monster.EquippedType;
@@ -2779,6 +3120,17 @@ We can access the type to dynamically cast the data as needed (since the
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ // Get and check if the monster has an equipped item
+ if monster.equippedType == .weapon {
+ let _weapon = monster.equipped(type: Weapon.self)
+ let name = _weapon.name // should return "Axe"
+ let dmg = _weapon.damage // should return 5
+ }
+~~~
+</div>
+
## Mutating FlatBuffers
As you saw above, typically once you have created a FlatBuffer, it is read-only
@@ -2814,6 +3166,14 @@ mutators like so:
monster.mutateInventory(0, 1); // Set vector element.
~~~
</div>
+<div class="language-kotlin">
+~~~{.kt}
+ val monster = Monster.getRootAsMonster(buf)
+ monster.mutateHp(10) // Set table field.
+ monster.pos!!.mutateZ(4) // Set struct field.
+ monster.mutateInventory(0, 1) // Set vector element.
+~~~
+</div>
<div class="language-csharp">
~~~{.cs}
var monster = Monster.GetRootAsMonster(buf);
@@ -2874,6 +3234,15 @@ mutators like so:
~~~
</div>
+<div class="language-swift">
+~~~{.swift}
+ let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
+ monster.mutate(hp: 10) // mutates a value in a table
+ monster.pos.mutate(z: 4) // mutates a value in a struct
+ monster.mutate(inventory: 6, at index: 0) // mutates a value in an Scalar array
+~~~
+</div>
+
We use the somewhat verbose term `mutate` instead of `set` to indicate that this
is a special use case, not to be confused with the default way of constructing
FlatBuffer data.
@@ -2897,16 +3266,18 @@ If this is not sufficient, other ways of mutating FlatBuffers may be supported
in your language through an object based API (`--gen-object-api`) or reflection.
See the individual language documents for support.
-## JSON with FlatBuffers
+## Using `flatc` as a JSON Conversion Tool
-#### Using `flatc` as a Conversion Tool
-
-This is often the preferred method to use JSON with FlatBuffers, as it doesn't
-require you to add any new code to your program. It is also efficient, since you
-can ship with the binary data. The drawback is that it requires an extra step
-for your users/developers to perform (although it may be able to be automated
+If you are working with C, C++, or Lobster, you can parse JSON at runtime.
+If your language does not support JSON at the moment, `flatc` may provide an
+alternative. Using `flatc` is often the preferred method, as it doesn't require you to
+add any new code to your program. It is also efficient, since you can ship with
+the binary data. The drawback is that it requires an extra step for your
+users/developers to perform (although it may be able to be automated
as part of your compilation).
+#### JSON to binary representation
+
Lets say you have a JSON file that describes your monster. In this example,
we will use the file `flatbuffers/samples/monsterdata.json`.
@@ -2915,16 +3286,31 @@ Here are the contents of the file:
~~~{.json}
{
pos: {
- x: 1,
- y: 2,
- z: 3
+ x: 1.0,
+ y: 2.0,
+ z: 3.0
},
hp: 300,
- name: "Orc"
+ name: "Orc",
+ weapons: [
+ {
+ name: "axe",
+ damage: 100
+ },
+ {
+ name: "bow",
+ damage: 90
+ }
+ ],
+ equipped_type: "Weapon",
+ equipped: {
+ name: "bow",
+ damage: 90
+ }
}
~~~
-You can run this file through the `flatc` compile with the `-b` flag and
+You can run this file through the `flatc` compiler with the `-b` flag and
our `monster.fbs` schema to produce a FlatBuffer binary file.
~~~{.sh}
@@ -2953,6 +3339,30 @@ for `flatcc` to support this.*
Guide for more information.*
</div>
+#### FlatBuffer binary to JSON
+
+Converting from a FlatBuffer binary representation to JSON is supported as well:
+~~~{.sh}
+./../flatc --json --raw-binary monster.fbs -- monsterdata.bin
+~~~
+This will convert `monsterdata.bin` back to its original JSON representation.
+You need to pass the corresponding FlatBuffers schema so that flatc knows how to
+interpret the binary buffer. Since `monster.fbs` does not specify an explicit
+`file_identifier` for binary buffers, `flatc` needs to be forced into reading
+the `.bin` file using the `--raw-binary` option.
+
+The FlatBuffer binary representation does not explicitly encode default values,
+therefore they are not present in the resulting JSON unless you specify
+`--defaults-json`.
+
+If you intend to process the JSON with other tools, you may consider switching
+on `--strict-json` so that identifiers are quoted properly.
+
+*Note: The resulting JSON file is not necessarily identical with the original JSON.
+If the binary representation contains floating point numbers, floats and doubles
+are rounded to 6 and 12 digits, respectively, in order to represent them as
+decimals in the JSON document. *
+
## Advanced Features for Each Language
Each language has a dedicated `Use in XXX` page in the Programmer's Guide
@@ -2964,10 +3374,13 @@ For your chosen language, see:
[Use in C++](@ref flatbuffers_guide_use_cpp)
</div>
<div class="language-java">
-[Use in Java/C#](@ref flatbuffers_guide_use_java_c-sharp)
+[Use in Java](@ref flatbuffers_guide_use_java)
+</div>
+<div class="language-kotlin">
+[Use in Kotlin](@ref flatbuffers_guide_use_kotlin)
</div>
<div class="language-csharp">
-[Use in Java/C#](@ref flatbuffers_guide_use_java_c-sharp)
+[Use in C#](@ref flatbuffers_guide_use_c-sharp)
</div>
<div class="language-go">
[Use in Go](@ref flatbuffers_guide_use_go)
@@ -2999,5 +3412,7 @@ For your chosen language, see:
<div class="language-rust">
[Use in Rust](@ref flatbuffers_guide_use_rust)
</div>
-
+<div class="language-swift">
+[Use in Swift](@ref flatbuffers_guide_use_swift)
+</div>
<br>
diff --git a/docs/source/TypeScriptUsage.md b/docs/source/TypeScriptUsage.md
index 832c46ee..02aa239e 100644
--- a/docs/source/TypeScriptUsage.md
+++ b/docs/source/TypeScriptUsage.md
@@ -43,7 +43,7 @@ First, include the library and generated code. Then read the file into an
the ByteBuffer to the `getRootAsMonster` function.
~~~{.ts}
- // note: import flabuffers with your desired import method
+ // note: import flatbuffers with your desired import method
import { MyGame } from './monster_generated';
diff --git a/docs/source/doxyfile b/docs/source/doxyfile
index 6ba3c108..b381e3dd 100644
--- a/docs/source/doxyfile
+++ b/docs/source/doxyfile
@@ -778,7 +778,7 @@ INPUT = "FlatBuffers.md" \
"../../php/FlatbufferBuilder.php" \
"../../net/FlatBuffers/FlatBufferBuilder.cs" \
"../../include/flatbuffers/flatbuffers.h" \
- "../../go/builder.go"
+ "../../go/builder.go" \
"../../rust/flatbuffers/src/builder.rs"
# This tag can be used to specify the character encoding of the source files
diff --git a/docs/source/doxygen_layout.xml b/docs/source/doxygen_layout.xml
index a2325075..72888f95 100644
--- a/docs/source/doxygen_layout.xml
+++ b/docs/source/doxygen_layout.xml
@@ -29,8 +29,10 @@
title="Use in C"/>
<tab type="user" url="@ref flatbuffers_guide_use_go"
title="Use in Go"/>
- <tab type="user" url="@ref flatbuffers_guide_use_java_c-sharp"
- title="Use in Java/C#"/>
+ <tab type="user" url="@ref flatbuffers_guide_use_java"
+ title="Use in Java"/>
+ <tab type="user" url="@ref flatbuffers_guide_use_c-sharp"
+ title="Use in C#"/>
<tab type="user" url="@ref flatbuffers_guide_use_javascript"
title="Use in JavaScript"/>
<tab type="user" url="@ref flatbuffers_guide_use_typescript"
@@ -48,7 +50,7 @@
<tab type="user" url="@ref flatbuffers_guide_use_rust"
title="Use in Rust"/>
<tab type="user" url="@ref flexbuffers"
- title="Schema-less version"/>
+ title="FlexBuffers (Schema-less version)"/>
<tab type="usergroup" url="" title="gRPC">
<tab type="user" url="@ref flatbuffers_grpc_guide_use_cpp"
title="Use in C++"/>
diff --git a/go/BUILD.bazel b/go/BUILD.bazel
index 026e89c1..78bd8d81 100644
--- a/go/BUILD.bazel
+++ b/go/BUILD.bazel
@@ -1,5 +1,11 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
+alias(
+ name = "go_default_library",
+ actual = ":go",
+ visibility = ["//visibility:public"],
+)
+
go_library(
name = "go",
srcs = [
diff --git a/go/builder.go b/go/builder.go
index 8d75700c..0e763d7a 100644
--- a/go/builder.go
+++ b/go/builder.go
@@ -17,6 +17,8 @@ type Builder struct {
head UOffsetT
nested bool
finished bool
+
+ sharedStrings map[string]UOffsetT
}
const fileIdentifierLength = 4
@@ -33,7 +35,6 @@ func NewBuilder(initialSize int) *Builder {
b.head = UOffsetT(initialSize)
b.minalign = 1
b.vtables = make([]UOffsetT, 0, 16) // sensible default capacity
-
return b
}
@@ -307,6 +308,20 @@ func (b *Builder) EndVector(vectorNumElems int) UOffsetT {
return b.Offset()
}
+// CreateSharedString Checks if the string is already written
+// to the buffer before calling CreateString
+func (b *Builder) CreateSharedString(s string) UOffsetT {
+ if b.sharedStrings == nil {
+ b.sharedStrings = make(map[string]UOffsetT)
+ }
+ if v, ok := b.sharedStrings[s]; ok {
+ return v
+ }
+ off := b.CreateString(s)
+ b.sharedStrings[s] = off
+ return off
+}
+
// CreateString writes a null-terminated string as a vector.
func (b *Builder) CreateString(s string) UOffsetT {
b.assertNotNested()
diff --git a/go/grpc.go b/go/grpc.go
index e7dabd3c..15f1a510 100644
--- a/go/grpc.go
+++ b/go/grpc.go
@@ -3,21 +3,36 @@ package flatbuffers
// Codec implements gRPC-go Codec which is used to encode and decode messages.
var Codec = "flatbuffers"
+// FlatbuffersCodec defines the interface gRPC uses to encode and decode messages. Note
+// that implementations of this interface must be thread safe; a Codec's
+// methods can be called from concurrent goroutines.
type FlatbuffersCodec struct{}
+// Marshal returns the wire format of v.
func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
return v.(*Builder).FinishedBytes(), nil
}
+// Unmarshal parses the wire format into v.
func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
v.(flatbuffersInit).Init(data, GetUOffsetT(data))
return nil
}
+// String old gRPC Codec interface func
func (FlatbuffersCodec) String() string {
return Codec
}
+// Name returns the name of the Codec implementation. The returned string
+// will be used as part of content type in transmission. The result must be
+// static; the result cannot change between calls.
+//
+// add Name() for ForceCodec interface
+func (FlatbuffersCodec) Name() string {
+ return Codec
+}
+
type flatbuffersInit interface {
Init(data []byte, i UOffsetT)
}
diff --git a/grpc/build_grpc.sh b/grpc/build_grpc.sh
index 8fb9e1c4..3c0c27e1 100755
--- a/grpc/build_grpc.sh
+++ b/grpc/build_grpc.sh
@@ -5,7 +5,7 @@ grpc_1_15_1_githash=1a60e6971f428323245a930031ad267bb3142ba4
function build_grpc () {
git clone https://github.com/grpc/grpc.git google/grpc
cd google/grpc
- git checkout ${grpc_1_15_1_githash}
+ git checkout ${grpc_1_15_1_githash}
git submodule update --init
make
make install prefix=`pwd`/install
diff --git a/grpc/flatbuffers-java-grpc/pom.xml b/grpc/flatbuffers-java-grpc/pom.xml
index 40799aea..17814f65 100644
--- a/grpc/flatbuffers-java-grpc/pom.xml
+++ b/grpc/flatbuffers-java-grpc/pom.xml
@@ -6,7 +6,7 @@
<parent>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-parent</artifactId>
- <version>1.11.0</version>
+ <version>1.12.0</version>
</parent>
<artifactId>flatbuffers-java-grpc</artifactId>
<name>${project.artifactId}</name>
@@ -24,7 +24,7 @@
</developer>
</developers>
<properties>
- <gRPC.version>1.11.0</gRPC.version>
+ <gRPC.version>1.12.0</gRPC.version>
</properties>
<dependencies>
<dependency>
diff --git a/grpc/pom.xml b/grpc/pom.xml
index c51348d5..a134adeb 100644
--- a/grpc/pom.xml
+++ b/grpc/pom.xml
@@ -4,7 +4,7 @@
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-parent</artifactId>
<packaging>pom</packaging>
- <version>1.11.0</version>
+ <version>1.12.0</version>
<name>flatbuffers-parent</name>
<description>parent pom for flatbuffers java artifacts</description>
<properties>
diff --git a/grpc/samples/greeter/server.cpp b/grpc/samples/greeter/server.cpp
index 82c97dc5..db442593 100644
--- a/grpc/samples/greeter/server.cpp
+++ b/grpc/samples/greeter/server.cpp
@@ -12,7 +12,8 @@ class GreeterServiceImpl final : public Greeter::Service {
grpc::ServerContext *context,
const flatbuffers::grpc::Message<HelloRequest> *request_msg,
flatbuffers::grpc::Message<HelloReply> *response_msg) override {
- // flatbuffers::grpc::MessageBuilder mb_;
+ flatbuffers::grpc::MessageBuilder mb_;
+
// We call GetRoot to "parse" the message. Verification is already
// performed by default. See the notes below for more details.
const HelloRequest *request = request_msg->GetRoot();
diff --git a/grpc/src/compiler/BUILD b/grpc/src/compiler/BUILD
new file mode 100644
index 00000000..96a78584
--- /dev/null
+++ b/grpc/src/compiler/BUILD
@@ -0,0 +1,107 @@
+load("@rules_cc//cc:defs.bzl", "cc_library")
+
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+filegroup(
+ name = "common_headers",
+ srcs = [
+ "config.h",
+ "schema_interface.h",
+ ],
+)
+
+cc_library(
+ name = "cpp_generator",
+ srcs = [
+ "cpp_generator.cc",
+ ],
+ hdrs = [
+ "cpp_generator.h",
+ ":common_headers",
+ ],
+ include_prefix = "src/compiler",
+ strip_include_prefix = "/grpc/src/compiler",
+ deps = [
+ "//:flatbuffers",
+ ],
+)
+
+cc_library(
+ name = "go_generator",
+ srcs = [
+ "go_generator.cc",
+ ],
+ hdrs = [
+ "go_generator.h",
+ ":common_headers",
+ ],
+ include_prefix = "src/compiler",
+ strip_include_prefix = "/grpc/src/compiler",
+ deps = [
+ "//:flatbuffers",
+ ],
+)
+
+cc_library(
+ name = "java_generator",
+ srcs = [
+ "java_generator.cc",
+ ],
+ hdrs = [
+ "java_generator.h",
+ ":common_headers",
+ ],
+ include_prefix = "src/compiler",
+ strip_include_prefix = "/grpc/src/compiler",
+ deps = [
+ "//:flatbuffers",
+ ],
+)
+
+cc_library(
+ name = "python_generator",
+ hdrs = [
+ "python_generator.h",
+ ],
+ include_prefix = "src/compiler",
+ strip_include_prefix = "/grpc/src/compiler",
+ deps = [
+ ":python_generator_private",
+ ],
+)
+
+cc_library(
+ name = "python_generator_private",
+ srcs = [
+ "python_generator.cc",
+ ],
+ hdrs = [
+ "python_generator.h",
+ "python_private_generator.h",
+ ":common_headers",
+ ],
+ include_prefix = "src/compiler",
+ strip_include_prefix = "/grpc/src/compiler",
+ visibility = ["//visibility:private"],
+ deps = [
+ "//:flatbuffers",
+ ],
+)
+
+cc_library(
+ name = "swift_generator",
+ srcs = [
+ "swift_generator.cc",
+ ],
+ hdrs = [
+ "swift_generator.h",
+ ":common_headers",
+ ],
+ include_prefix = "src/compiler",
+ strip_include_prefix = "/grpc/src/compiler",
+ deps = [
+ "//:flatbuffers",
+ ],
+) \ No newline at end of file
diff --git a/grpc/src/compiler/java_generator.cc b/grpc/src/compiler/java_generator.cc
index 661c9ee6..d2cf5ccc 100644
--- a/grpc/src/compiler/java_generator.cc
+++ b/grpc/src/compiler/java_generator.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "java_generator.h"
+#include "src/compiler/java_generator.h"
#include <algorithm>
#include <iostream>
diff --git a/grpc/src/compiler/python_generator.cc b/grpc/src/compiler/python_generator.cc
new file mode 100644
index 00000000..3fcf7ea4
--- /dev/null
+++ b/grpc/src/compiler/python_generator.cc
@@ -0,0 +1,624 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <algorithm>
+#include <cassert>
+#include <cctype>
+#include <cstring>
+#include <fstream>
+#include <iostream>
+#include <map>
+#include <memory>
+#include <ostream>
+#include <set>
+#include <sstream>
+#include <tuple>
+#include <vector>
+
+#include "flatbuffers/util.h"
+#include "src/compiler/python_generator.h"
+#include "src/compiler/python_private_generator.h"
+
+using std::make_pair;
+using std::map;
+using std::pair;
+using std::replace;
+using std::tuple;
+using std::vector;
+using std::set;
+
+namespace grpc_python_generator {
+
+grpc::string generator_file_name;
+
+typedef map<grpc::string, grpc::string> StringMap;
+typedef vector<grpc::string> StringVector;
+typedef tuple<grpc::string, grpc::string> StringPair;
+typedef set<StringPair> StringPairSet;
+
+// Provides RAII indentation handling. Use as:
+// {
+// IndentScope raii_my_indent_var_name_here(my_py_printer);
+// // constructor indented my_py_printer
+// ...
+// // destructor called at end of scope, un-indenting my_py_printer
+// }
+class IndentScope {
+ public:
+ explicit IndentScope(grpc_generator::Printer* printer) : printer_(printer) {
+ printer_->Indent();
+ }
+
+ ~IndentScope() { printer_->Outdent(); }
+
+ private:
+ grpc_generator::Printer* printer_;
+};
+
+inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
+ const grpc::string& to, bool replace_all) {
+ size_t pos = 0;
+
+ do {
+ pos = str.find(from, pos);
+ if (pos == grpc::string::npos) {
+ break;
+ }
+ str.replace(pos, from.length(), to);
+ pos += to.length();
+ } while (replace_all);
+
+ return str;
+}
+
+inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
+ const grpc::string& to) {
+ return StringReplace(str, from, to, true);
+}
+
+grpc::string ModuleName(const grpc::string& filename,
+ const grpc::string& import_prefix) {
+ grpc::string basename = flatbuffers::StripExtension(filename);
+ basename = StringReplace(basename, "-", "_");
+ basename = StringReplace(basename, "/", ".");
+ return import_prefix + basename + "_fb";
+}
+
+grpc::string ModuleAlias(const grpc::string& filename,
+ const grpc::string& import_prefix) {
+ grpc::string module_name = ModuleName(filename, import_prefix);
+ // We can't have dots in the module name, so we replace each with _dot_.
+ // But that could lead to a collision between a.b and a_dot_b, so we also
+ // duplicate each underscore.
+ module_name = StringReplace(module_name, "_", "__");
+ module_name = StringReplace(module_name, ".", "_dot_");
+ return module_name;
+}
+
+PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config_,
+ const grpc_generator::File* file_)
+ : config(config_), file(file_) {}
+
+void PrivateGenerator::PrintBetaServicer(const grpc_generator::Service* service,
+ grpc_generator::Printer* out) {
+ StringMap service_dict;
+ service_dict["Service"] = service->name();
+ out->Print("\n\n");
+ out->Print(service_dict, "class Beta$Service$Servicer(object):\n");
+ {
+ IndentScope raii_class_indent(out);
+ out->Print(
+ "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
+ "\nIt is recommended to use the GA API (classes and functions in this\n"
+ "file not marked beta) for all further purposes. This class was "
+ "generated\n"
+ "only to ease transition from grpcio<0.15.0 to "
+ "grpcio>=0.15.0.\"\"\"\n");
+ for (int i = 0; i < service->method_count(); ++i) {
+ auto method = service->method(i);
+ grpc::string arg_name =
+ method->ClientStreaming() ? "request_iterator" : "request";
+ StringMap method_dict;
+ method_dict["Method"] = method->name();
+ method_dict["ArgName"] = arg_name;
+ out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
+ {
+ IndentScope raii_method_indent(out);
+ out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
+ }
+ }
+ }
+}
+
+void PrivateGenerator::PrintBetaStub(const grpc_generator::Service* service,
+ grpc_generator::Printer* out) {
+ StringMap service_dict;
+ service_dict["Service"] = service->name();
+ out->Print("\n\n");
+ out->Print(service_dict, "class Beta$Service$Stub(object):\n");
+ {
+ IndentScope raii_class_indent(out);
+ out->Print(
+ "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
+ "\nIt is recommended to use the GA API (classes and functions in this\n"
+ "file not marked beta) for all further purposes. This class was "
+ "generated\n"
+ "only to ease transition from grpcio<0.15.0 to "
+ "grpcio>=0.15.0.\"\"\"\n");
+ for (int i = 0; i < service->method_count(); ++i) {
+ auto method = service->method(i);
+ grpc::string arg_name =
+ method->ClientStreaming() ? "request_iterator" : "request";
+ StringMap method_dict;
+ method_dict["Method"] = method->name();
+ method_dict["ArgName"] = arg_name;
+ out->Print(method_dict,
+ "def $Method$(self, $ArgName$, timeout, metadata=None, "
+ "with_call=False, protocol_options=None):\n");
+ {
+ IndentScope raii_method_indent(out);
+ out->Print("raise NotImplementedError()\n");
+ }
+ if (!method->ServerStreaming()) {
+ out->Print(method_dict, "$Method$.future = None\n");
+ }
+ }
+ }
+}
+
+void PrivateGenerator::PrintBetaServerFactory(
+ const grpc::string& package_qualified_service_name,
+ const grpc_generator::Service* service, grpc_generator::Printer* out) {
+ StringMap service_dict;
+ service_dict["Service"] = service->name();
+ out->Print("\n\n");
+ out->Print(service_dict,
+ "def beta_create_$Service$_server(servicer, pool=None, "
+ "pool_size=None, default_timeout=None, maximum_timeout=None):\n");
+ {
+ IndentScope raii_create_server_indent(out);
+ out->Print(
+ "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
+ "\nIt is recommended to use the GA API (classes and functions in this\n"
+ "file not marked beta) for all further purposes. This function was\n"
+ "generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
+ "\"\"\"\n");
+ StringMap method_implementation_constructors;
+ StringMap input_message_modules_and_classes;
+ StringMap output_message_modules_and_classes;
+ for (int i = 0; i < service->method_count(); ++i) {
+ auto method = service->method(i);
+ const grpc::string method_implementation_constructor =
+ grpc::string(method->ClientStreaming() ? "stream_" : "unary_") +
+ grpc::string(method->ServerStreaming() ? "stream_" : "unary_") +
+ "inline";
+ grpc::string input_message_module_and_class = method->get_fb_builder();
+ grpc::string output_message_module_and_class = method->get_fb_builder();
+ method_implementation_constructors.insert(
+ make_pair(method->name(), method_implementation_constructor));
+ input_message_modules_and_classes.insert(
+ make_pair(method->name(), input_message_module_and_class));
+ output_message_modules_and_classes.insert(
+ make_pair(method->name(), output_message_module_and_class));
+ }
+ StringMap method_dict;
+ method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
+// out->Print("request_deserializers = {\n");
+// for (StringMap::iterator name_and_input_module_class_pair =
+// input_message_modules_and_classes.begin();
+// name_and_input_module_class_pair !=
+// input_message_modules_and_classes.end();
+// name_and_input_module_class_pair++) {
+// method_dict["MethodName"] = name_and_input_module_class_pair->first;
+// method_dict["InputTypeModuleAndClass"] =
+// name_and_input_module_class_pair->second;
+// IndentScope raii_indent(out);
+// out->Print(method_dict,
+// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+// "$InputTypeModuleAndClass$.FromString,\n");
+// }
+// out->Print("}\n");
+// out->Print("response_serializers = {\n");
+// for (StringMap::iterator name_and_output_module_class_pair =
+// output_message_modules_and_classes.begin();
+// name_and_output_module_class_pair !=
+// output_message_modules_and_classes.end();
+// name_and_output_module_class_pair++) {
+// method_dict["MethodName"] = name_and_output_module_class_pair->first;
+// method_dict["OutputTypeModuleAndClass"] =
+// name_and_output_module_class_pair->second;
+// IndentScope raii_indent(out);
+// out->Print(method_dict,
+// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+// "$OutputTypeModuleAndClass$.SerializeToString,\n");
+// }
+// out->Print("}\n");
+ out->Print("method_implementations = {\n");
+ for (StringMap::iterator name_and_implementation_constructor =
+ method_implementation_constructors.begin();
+ name_and_implementation_constructor !=
+ method_implementation_constructors.end();
+ name_and_implementation_constructor++) {
+ method_dict["Method"] = name_and_implementation_constructor->first;
+ method_dict["Constructor"] = name_and_implementation_constructor->second;
+ IndentScope raii_descriptions_indent(out);
+ const grpc::string method_name =
+ name_and_implementation_constructor->first;
+ out->Print(method_dict,
+ "(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
+ "face_utilities.$Constructor$(servicer.$Method$),\n");
+ }
+ out->Print("}\n");
+ out->Print(
+ "server_options = beta_implementations.server_options("
+ "thread_pool=pool, thread_pool_size=pool_size, "
+ "default_timeout=default_timeout, "
+ "maximum_timeout=maximum_timeout)\n");
+ out->Print(
+ "return beta_implementations.server(method_implementations, "
+ "options=server_options)\n");
+ //"request_deserializers=request_deserializers, "
+ //"response_serializers=response_serializers, "
+ }
+}
+
+void PrivateGenerator::PrintBetaStubFactory(
+ const grpc::string& package_qualified_service_name,
+ const grpc_generator::Service* service, grpc_generator::Printer* out) {
+ StringMap dict;
+ dict["Service"] = service->name();
+ out->Print("\n\n");
+ out->Print(dict,
+ "def beta_create_$Service$_stub(channel, host=None,"
+ " metadata_transformer=None, pool=None, pool_size=None):\n");
+ {
+ IndentScope raii_create_server_indent(out);
+ out->Print(
+ "\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
+ "\nIt is recommended to use the GA API (classes and functions in this\n"
+ "file not marked beta) for all further purposes. This function was\n"
+ "generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
+ "\"\"\"\n");
+ StringMap method_cardinalities;
+ StringMap input_message_modules_and_classes;
+ StringMap output_message_modules_and_classes;
+ for (int i = 0; i < service->method_count(); ++i) {
+ auto method = service->method(i);
+ const grpc::string method_cardinality =
+ grpc::string(method->ClientStreaming() ? "STREAM" : "UNARY") +
+ "_" +
+ grpc::string(method->ServerStreaming() ? "STREAM" : "UNARY");
+ grpc::string input_message_module_and_class = method->get_fb_builder();
+ grpc::string output_message_module_and_class = method->get_fb_builder();
+ method_cardinalities.insert(
+ make_pair(method->name(), method_cardinality));
+ input_message_modules_and_classes.insert(
+ make_pair(method->name(), input_message_module_and_class));
+ output_message_modules_and_classes.insert(
+ make_pair(method->name(), output_message_module_and_class));
+ }
+ StringMap method_dict;
+ method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
+// out->Print("request_serializers = {\n");
+// for (StringMap::iterator name_and_input_module_class_pair =
+// input_message_modules_and_classes.begin();
+// name_and_input_module_class_pair !=
+// input_message_modules_and_classes.end();
+// name_and_input_module_class_pair++) {
+// method_dict["MethodName"] = name_and_input_module_class_pair->first;
+// method_dict["InputTypeModuleAndClass"] =
+// name_and_input_module_class_pair->second;
+// IndentScope raii_indent(out);
+// out->Print(method_dict,
+// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+// "$InputTypeModuleAndClass$.SerializeToString,\n");
+// }
+// out->Print("}\n");
+// out->Print("response_deserializers = {\n");
+// for (StringMap::iterator name_and_output_module_class_pair =
+// output_message_modules_and_classes.begin();
+// name_and_output_module_class_pair !=
+// output_message_modules_and_classes.end();
+// name_and_output_module_class_pair++) {
+// method_dict["MethodName"] = name_and_output_module_class_pair->first;
+// method_dict["OutputTypeModuleAndClass"] =
+// name_and_output_module_class_pair->second;
+// IndentScope raii_indent(out);
+// out->Print(method_dict,
+// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
+// "$OutputTypeModuleAndClass$.FromString,\n");
+// }
+// out->Print("}\n");
+ out->Print("cardinalities = {\n");
+ for (StringMap::iterator name_and_cardinality =
+ method_cardinalities.begin();
+ name_and_cardinality != method_cardinalities.end();
+ name_and_cardinality++) {
+ method_dict["Method"] = name_and_cardinality->first;
+ method_dict["Cardinality"] = name_and_cardinality->second;
+ IndentScope raii_descriptions_indent(out);
+ out->Print(method_dict,
+ "\'$Method$\': cardinality.Cardinality.$Cardinality$,\n");
+ }
+ out->Print("}\n");
+ out->Print(
+ "stub_options = beta_implementations.stub_options("
+ "host=host, metadata_transformer=metadata_transformer, "
+ "thread_pool=pool, thread_pool_size=pool_size)\n");
+ out->Print(method_dict,
+ "return beta_implementations.dynamic_stub(channel, "
+ "\'$PackageQualifiedServiceName$\', "
+ "cardinalities, options=stub_options)\n");
+ // "request_serializers=request_serializers, "
+ //"response_deserializers=response_deserializers, "
+ }
+}
+
+void PrivateGenerator::PrintStub(
+ const grpc::string& package_qualified_service_name,
+ const grpc_generator::Service* service, grpc_generator::Printer* out) {
+ StringMap dict;
+ dict["Service"] = service->name();
+ out->Print("\n\n");
+ out->Print(dict, "class $Service$Stub(object):\n");
+ {
+ IndentScope raii_class_indent(out);
+ out->Print("\n");
+ out->Print("def __init__(self, channel):\n");
+ {
+ IndentScope raii_init_indent(out);
+ out->Print("\"\"\"Constructor.\n");
+ out->Print("\n");
+ out->Print("Args:\n");
+ {
+ IndentScope raii_args_indent(out);
+ out->Print("channel: A grpc.Channel.\n");
+ }
+ out->Print("\"\"\"\n");
+ for (int i = 0; i < service->method_count(); ++i) {
+ auto method = service->method(i);
+ grpc::string multi_callable_constructor =
+ grpc::string(method->ClientStreaming() ? "stream" : "unary") +
+ "_" +
+ grpc::string(method->ServerStreaming() ? "stream" : "unary");
+ grpc::string request_module_and_class = method->get_fb_builder();
+ grpc::string response_module_and_class = method->get_fb_builder();
+ StringMap method_dict;
+ method_dict["Method"] = method->name();
+ method_dict["MultiCallableConstructor"] = multi_callable_constructor;
+ out->Print(method_dict,
+ "self.$Method$ = channel.$MultiCallableConstructor$(\n");
+ {
+ method_dict["PackageQualifiedService"] =
+ package_qualified_service_name;
+ method_dict["RequestModuleAndClass"] = request_module_and_class;
+ method_dict["ResponseModuleAndClass"] = response_module_and_class;
+ IndentScope raii_first_attribute_indent(out);
+ IndentScope raii_second_attribute_indent(out);
+ out->Print(method_dict, "'/$PackageQualifiedService$/$Method$',\n");
+ out->Print(method_dict,"\n");
+ out->Print(
+ method_dict,"\n");
+ out->Print(")\n");
+ }
+ }
+ }
+ }
+}
+
+void PrivateGenerator::PrintServicer(const grpc_generator::Service* service,
+ grpc_generator::Printer* out) {
+ StringMap service_dict;
+ service_dict["Service"] = service->name();
+ out->Print("\n\n");
+ out->Print(service_dict, "class $Service$Servicer(object):\n");
+ {
+ IndentScope raii_class_indent(out);
+ for (int i = 0; i < service->method_count(); ++i) {
+ auto method = service->method(i);
+ grpc::string arg_name =
+ method->ClientStreaming() ? "request_iterator" : "request";
+ StringMap method_dict;
+ method_dict["Method"] = method->name();
+ method_dict["ArgName"] = arg_name;
+ out->Print("\n");
+ out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
+ {
+ IndentScope raii_method_indent(out);
+ out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
+ out->Print("context.set_details('Method not implemented!')\n");
+ out->Print("raise NotImplementedError('Method not implemented!')\n");
+ }
+ }
+ }
+}
+
+void PrivateGenerator::PrintAddServicerToServer(
+ const grpc::string& package_qualified_service_name,
+ const grpc_generator::Service* service, grpc_generator::Printer* out) {
+ StringMap service_dict;
+ service_dict["Service"] = service->name();
+ out->Print("\n\n");
+ out->Print(service_dict,
+ "def add_$Service$Servicer_to_server(servicer, server):\n");
+ {
+ IndentScope raii_class_indent(out);
+ out->Print("rpc_method_handlers = {\n");
+ {
+ IndentScope raii_dict_first_indent(out);
+ IndentScope raii_dict_second_indent(out);
+ for (int i = 0; i < service->method_count(); ++i) {
+ auto method = service->method(i);
+ grpc::string method_handler_constructor =
+ grpc::string(method->ClientStreaming() ? "stream" : "unary") +
+ "_" +
+ grpc::string(method->ServerStreaming() ? "stream" : "unary") +
+ "_rpc_method_handler";
+ grpc::string request_module_and_class = method->get_fb_builder();
+ grpc::string response_module_and_class = method->get_fb_builder();
+ StringMap method_dict;
+ method_dict["Method"] = method->name();
+ method_dict["MethodHandlerConstructor"] = method_handler_constructor;
+ method_dict["RequestModuleAndClass"] = request_module_and_class;
+ method_dict["ResponseModuleAndClass"] = response_module_and_class;
+ out->Print(method_dict,
+ "'$Method$': grpc.$MethodHandlerConstructor$(\n");
+ {
+ IndentScope raii_call_first_indent(out);
+ IndentScope raii_call_second_indent(out);
+ out->Print(method_dict, "servicer.$Method$,\n");
+ out->Print(
+ method_dict,"\n");
+ out->Print(
+ method_dict,
+ "\n");
+ }
+ out->Print("),\n");
+ }
+ }
+ StringMap method_dict;
+ method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
+ out->Print("}\n");
+ out->Print("generic_handler = grpc.method_handlers_generic_handler(\n");
+ {
+ IndentScope raii_call_first_indent(out);
+ IndentScope raii_call_second_indent(out);
+ out->Print(method_dict,
+ "'$PackageQualifiedServiceName$', rpc_method_handlers)\n");
+ }
+ out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
+ }
+}
+
+void PrivateGenerator::PrintBetaPreamble(grpc_generator::Printer* out) {
+ StringMap var;
+ var["Package"] = config.beta_package_root;
+ out->Print(var,
+ "from $Package$ import implementations as beta_implementations\n");
+ out->Print(var, "from $Package$ import interfaces as beta_interfaces\n");
+ out->Print("from grpc.framework.common import cardinality\n");
+ out->Print(
+ "from grpc.framework.interfaces.face import utilities as "
+ "face_utilities\n");
+}
+
+void PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
+ StringMap var;
+ var["Package"] = config.grpc_package_root;
+ out->Print(var, "import $Package$\n");
+ out->Print("\n");
+ StringPairSet imports_set;
+ for (int i = 0; i < file->service_count(); ++i) {
+ auto service = file->service(i);
+ for (int j = 0; j < service->method_count(); ++j) {
+ auto method = service.get()->method(j);
+
+ grpc::string input_type_file_name = method->get_fb_builder();
+ grpc::string input_module_name =
+ ModuleName(input_type_file_name, config.import_prefix);
+ grpc::string input_module_alias =
+ ModuleAlias(input_type_file_name, config.import_prefix);
+ imports_set.insert(
+ std::make_tuple(input_module_name, input_module_alias));
+
+ grpc::string output_type_file_name = method->get_fb_builder();
+ grpc::string output_module_name =
+ ModuleName(output_type_file_name, config.import_prefix);
+ grpc::string output_module_alias =
+ ModuleAlias(output_type_file_name, config.import_prefix);
+ imports_set.insert(
+ std::make_tuple(output_module_name, output_module_alias));
+ }
+ }
+
+ for (StringPairSet::iterator it = imports_set.begin();
+ it != imports_set.end(); ++it) {
+ var["ModuleName"] = std::get<0>(*it);
+ var["ModuleAlias"] = std::get<1>(*it);
+ out->Print(var, "import $ModuleName$ as $ModuleAlias$\n");
+ }
+}
+
+void PrivateGenerator::PrintGAServices(grpc_generator::Printer* out) {
+ grpc::string package = file->package();
+ if (!package.empty()) {
+ package = package.append(".");
+ }
+
+ out->Print(file->additional_headers().c_str());
+
+ for (int i = 0; i < file->service_count(); ++i) {
+ auto service = file->service(i);
+
+ grpc::string package_qualified_service_name = package + service->name();
+ PrintStub(package_qualified_service_name, service.get(), out);
+ PrintServicer(service.get(), out);
+ PrintAddServicerToServer(package_qualified_service_name, service.get(),
+ out);
+ }
+}
+
+void PrivateGenerator::PrintBetaServices(grpc_generator::Printer* out) {
+ grpc::string package = file->package();
+ if (!package.empty()) {
+ package = package.append(".");
+ }
+ for (int i = 0; i < file->service_count(); ++i) {
+ auto service = file->service(i);
+
+ grpc::string package_qualified_service_name = package + service->name();
+ PrintBetaServicer(service.get(), out);
+ PrintBetaStub(service.get(), out);
+ PrintBetaServerFactory(package_qualified_service_name, service.get(), out);
+ PrintBetaStubFactory(package_qualified_service_name, service.get(), out);
+ }
+}
+
+grpc::string PrivateGenerator::GetGrpcServices() {
+ grpc::string output;
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ auto out = file->CreatePrinter(&output);
+ out->Print(
+ "# Generated by the gRPC Python protocol compiler plugin. "
+ "DO NOT EDIT!\n");
+ StringMap var;
+ var["Package"] = config.grpc_package_root;
+ out->Print(var, "import $Package$\n");
+ PrintGAServices(out.get());
+ out->Print("try:\n");
+ {
+ IndentScope raii_dict_try_indent(out.get());
+ out->Print(
+ "# THESE ELEMENTS WILL BE DEPRECATED.\n"
+ "# Please use the generated *_pb2_grpc.py files instead.\n");
+ out->Print(var, "import $Package$\n");
+ PrintBetaPreamble(out.get());
+ PrintGAServices(out.get());
+ PrintBetaServices(out.get());
+ }
+ out->Print("except ImportError:\n");
+ {
+ IndentScope raii_dict_except_indent(out.get());
+ out->Print("pass");
+ }
+ }
+ return output;
+}
+
+} // namespace grpc_python_generator
diff --git a/grpc/src/compiler/python_generator.h b/grpc/src/compiler/python_generator.h
new file mode 100644
index 00000000..d92cb025
--- /dev/null
+++ b/grpc/src/compiler/python_generator.h
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
+
+#include <utility>
+
+#include "src/compiler/schema_interface.h"
+
+namespace grpc_python_generator {
+
+// Data pertaining to configuration of the generator with respect to anything
+// that may be used internally at Google.
+struct GeneratorConfiguration {
+ grpc::string grpc_package_root;
+ // TODO(https://github.com/grpc/grpc/issues/8622): Drop this.
+ grpc::string beta_package_root;
+ // TODO(https://github.com/google/protobuf/issues/888): Drop this.
+ grpc::string import_prefix;
+};
+
+} // namespace grpc_python_generator
+
+#endif // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
diff --git a/grpc/src/compiler/python_private_generator.h b/grpc/src/compiler/python_private_generator.h
new file mode 100644
index 00000000..30ba0d7b
--- /dev/null
+++ b/grpc/src/compiler/python_private_generator.h
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright 2015 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
+
+#include <iostream>
+#include <vector>
+
+#include "src/compiler/python_generator.h"
+#include "src/compiler/schema_interface.h"
+
+namespace grpc_python_generator {
+
+// Tucks all generator state in an anonymous namespace away from
+// PythonGrpcGenerator and the header file, mostly to encourage future changes
+// to not require updates to the grpcio-tools C++ code part. Assumes that it is
+// only ever used from a single thread.
+struct PrivateGenerator {
+ const GeneratorConfiguration& config;
+ const grpc_generator::File* file;
+
+ PrivateGenerator(const GeneratorConfiguration& config,
+ const grpc_generator::File* file);
+
+ grpc::string GetGrpcServices();
+
+ private:
+ void PrintPreamble(grpc_generator::Printer* out);
+ void PrintBetaPreamble(grpc_generator::Printer* out);
+ void PrintGAServices(grpc_generator::Printer* out);
+ void PrintBetaServices(grpc_generator::Printer* out);
+
+ void PrintAddServicerToServer(
+ const grpc::string& package_qualified_service_name,
+ const grpc_generator::Service* service, grpc_generator::Printer* out);
+ void PrintServicer(const grpc_generator::Service* service,
+ grpc_generator::Printer* out);
+ void PrintStub(const grpc::string& package_qualified_service_name,
+ const grpc_generator::Service* service,
+ grpc_generator::Printer* out);
+
+ void PrintBetaServicer(const grpc_generator::Service* service,
+ grpc_generator::Printer* out);
+ void PrintBetaServerFactory(
+ const grpc::string& package_qualified_service_name,
+ const grpc_generator::Service* service, grpc_generator::Printer* out);
+ void PrintBetaStub(const grpc_generator::Service* service,
+ grpc_generator::Printer* out);
+ void PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
+ const grpc_generator::Service* service,
+ grpc_generator::Printer* out);
+};
+
+} // namespace grpc_python_generator
+
+#endif // GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
diff --git a/grpc/src/compiler/schema_interface.h b/grpc/src/compiler/schema_interface.h
index 2be2ed73..9611642e 100644
--- a/grpc/src/compiler/schema_interface.h
+++ b/grpc/src/compiler/schema_interface.h
@@ -1,44 +1,29 @@
/*
*
- * Copyright 2015, Google Inc.
- * All rights reserved.
+ * Copyright 2015 gRPC authors.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
-#include "src/compiler/config.h"
-
#include <memory>
#include <vector>
+#include "src/compiler/config.h"
+
#ifndef GRPC_CUSTOM_STRING
# include <string>
# define GRPC_CUSTOM_STRING std::string
@@ -79,6 +64,9 @@ struct Method : public CommentHolder {
virtual grpc::string get_input_type_name() const = 0;
virtual grpc::string get_output_type_name() const = 0;
+
+ virtual grpc::string get_fb_builder() const = 0;
+
virtual bool NoStreaming() const = 0;
virtual bool ClientStreaming() const = 0;
virtual bool ServerStreaming() const = 0;
diff --git a/grpc/src/compiler/swift_generator.cc b/grpc/src/compiler/swift_generator.cc
new file mode 100644
index 00000000..7997278b
--- /dev/null
+++ b/grpc/src/compiler/swift_generator.cc
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * NOTE: The following implementation is a translation for the Swift-grpc
+ * generator since flatbuffers doesnt allow plugins for now. if an issue arises
+ * please open an issue in the flatbuffers repository. This file should always
+ * be maintained according to the Swift-grpc repository
+ */
+#include <map>
+#include <sstream>
+
+#include "flatbuffers/util.h"
+#include "src/compiler/schema_interface.h"
+#include "src/compiler/swift_generator.h"
+
+namespace grpc_swift_generator {
+
+grpc::string GenerateMessage(const grpc::string &name) {
+ return "Message<" + name + ">";
+}
+
+// MARK: - Client
+
+grpc::string GenerateClientFuncName(const grpc_generator::Method *method) {
+ if (method->NoStreaming()) {
+ return "$GenAccess$ func $MethodName$(_ request: $Input$"
+ ", callOptions: CallOptions?$isNil$) -> UnaryCall<$Input$,$Output$>";
+ }
+
+ if (method->ClientStreaming()) {
+ return "$GenAccess$ func $MethodName$"
+ "(callOptions: CallOptions?$isNil$) -> "
+ "ClientStreamingCall<$Input$,$Output$>";
+ }
+
+ if (method->ServerStreaming()) {
+ return "$GenAccess$ func $MethodName$(_ request: $Input$"
+ ", callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
+ ") -> Void) -> ServerStreamingCall<$Input$, $Output$>";
+ }
+ return "$GenAccess$ func $MethodName$"
+ "(callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
+ ") -> Void) -> BidirectionalStreamingCall<$Input$, $Output$>";
+}
+
+grpc::string GenerateClientFuncBody(const grpc_generator::Method *method) {
+ if (method->NoStreaming()) {
+ return "return self.makeUnaryCall(path: "
+ "\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
+ "callOptions: callOptions ?? self.defaultCallOptions)";
+ }
+
+ if (method->ClientStreaming()) {
+ return "return self.makeClientStreamingCall(path: "
+ "\"/$PATH$$ServiceName$/$MethodName$\", callOptions: callOptions ?? "
+ "self.defaultCallOptions)";
+ }
+
+ if (method->ServerStreaming()) {
+ return "return self.makeServerStreamingCall(path: "
+ "\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
+ "callOptions: callOptions ?? self.defaultCallOptions, handler: "
+ "handler)";
+ }
+ return "return self.makeBidirectionalStreamingCall(path: "
+ "\"/$PATH$$ServiceName$/$MethodName$\", callOptions: callOptions ?? "
+ "self.defaultCallOptions, handler: handler)";
+}
+
+void GenerateClientProtocol(const grpc_generator::Service *service,
+ grpc_generator::Printer *printer,
+ std::map<grpc::string, grpc::string> *dictonary) {
+ auto vars = *dictonary;
+ printer->Print(vars, "$ACCESS$ protocol $ServiceName$Service {\n");
+ vars["GenAccess"] = "";
+ for (auto it = 0; it < service->method_count(); it++) {
+ auto method = service->method(it);
+ vars["Input"] = GenerateMessage(method->get_input_type_name());
+ vars["Output"] = GenerateMessage(method->get_output_type_name());
+ vars["MethodName"] = method->name();
+ vars["isNil"] = "";
+ printer->Print("\t");
+ auto func = GenerateClientFuncName(method.get());
+ printer->Print(vars, func.c_str());
+ printer->Print("\n");
+ }
+ printer->Print("}\n\n");
+}
+
+void GenerateClientClass(const grpc_generator::Service *service,
+ grpc_generator::Printer *printer,
+ std::map<grpc::string, grpc::string> *dictonary) {
+ auto vars = *dictonary;
+ printer->Print(vars,
+ "$ACCESS$ final class $ServiceName$ServiceClient: GRPCClient, "
+ "$ServiceName$Service {\n");
+ printer->Print(vars, "\t$ACCESS$ let connection: ClientConnection\n");
+ printer->Print(vars, "\t$ACCESS$ var defaultCallOptions: CallOptions\n");
+ printer->Print("\n");
+ printer->Print(vars,
+ "\t$ACCESS$ init(connection: ClientConnection, "
+ "defaultCallOptions: CallOptions = CallOptions()) {\n");
+ printer->Print("\t\tself.connection = connection\n");
+ printer->Print("\t\tself.defaultCallOptions = defaultCallOptions\n");
+ printer->Print("\t}");
+ printer->Print("\n");
+ vars["GenAccess"] = "public";
+ for (auto it = 0; it < service->method_count(); it++) {
+ auto method = service->method(it);
+ vars["Input"] = GenerateMessage(method->get_input_type_name());
+ vars["Output"] = GenerateMessage(method->get_output_type_name());
+ vars["MethodName"] = method->name();
+ vars["isNil"] = " = nil";
+ printer->Print("\n\t");
+ auto func = GenerateClientFuncName(method.get());
+ printer->Print(vars, func.c_str());
+ printer->Print(" {\n");
+ auto body = GenerateClientFuncBody(method.get());
+ printer->Print("\t\t");
+ printer->Print(vars, body.c_str());
+ printer->Print("\n\t}\n");
+ }
+ printer->Print("}\n");
+}
+
+// MARK: - Server
+
+grpc::string GenerateServerFuncName(const grpc_generator::Method *method) {
+ if (method->NoStreaming()) {
+ return "func $MethodName$(_ request: $Input$"
+ ", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>";
+ }
+
+ if (method->ClientStreaming()) {
+ return "func $MethodName$(context: UnaryResponseCallContext<$Output$>) -> "
+ "EventLoopFuture<(StreamEvent<$Input$"
+ ">) -> Void>";
+ }
+
+ if (method->ServerStreaming()) {
+ return "func $MethodName$(request: $Input$"
+ ", context: StreamingResponseCallContext<$Output$>) -> "
+ "EventLoopFuture<GRPCStatus>";
+ }
+ return "func $MethodName$(context: StreamingResponseCallContext<$Output$>) "
+ "-> EventLoopFuture<(StreamEvent<$Input$>) -> Void>";
+}
+
+grpc::string GenerateServerExtensionBody(const grpc_generator::Method *method) {
+ grpc::string start = "\t\tcase \"$MethodName$\":\n\t\t";
+ if (method->NoStreaming()) {
+ return start +
+ "return UnaryCallHandler(callHandlerContext: callHandlerContext) { "
+ "context in"
+ "\n\t\t\t"
+ "return { request in"
+ "\n\t\t\t\t"
+ "self.$MethodName$(request, context: context)"
+ "\n\t\t\t}"
+ "\n\t\t}";
+ }
+ if (method->ClientStreaming()) {
+ return start +
+ "return ClientStreamingCallHandler(callHandlerContext: "
+ "callHandlerContext) { context in"
+ "\n\t\t\t"
+ "return { request in"
+ "\n\t\t\t\t"
+ "self.$MethodName$(request: request, context: context)"
+ "\n\t\t\t}"
+ "\n\t\t}";
+ }
+ if (method->ServerStreaming()) {
+ return start +
+ "return ServerStreamingCallHandler(callHandlerContext: "
+ "callHandlerContext) { context in"
+ "\n\t\t\t"
+ "return { request in"
+ "\n\t\t\t\t"
+ "self.$MethodName$(request: request, context: context)"
+ "\n\t\t\t}"
+ "\n\t\t}";
+ }
+ if (method->BidiStreaming()) {
+ return start +
+ "return BidirectionalStreamingCallHandler(callHandlerContext: "
+ "callHandlerContext) { context in"
+ "\n\t\t\t"
+ "return { request in"
+ "\n\t\t\t\t"
+ "self.$MethodName$(request: request, context: context)"
+ "\n\t\t\t}"
+ "\n\t\t}";
+ }
+ return "";
+}
+
+void GenerateServerProtocol(const grpc_generator::Service *service,
+ grpc_generator::Printer *printer,
+ std::map<grpc::string, grpc::string> *dictonary) {
+ auto vars = *dictonary;
+ printer->Print(
+ vars, "$ACCESS$ protocol $ServiceName$Provider: CallHandlerProvider {\n");
+ for (auto it = 0; it < service->method_count(); it++) {
+ auto method = service->method(it);
+ vars["Input"] = GenerateMessage(method->get_input_type_name());
+ vars["Output"] = GenerateMessage(method->get_output_type_name());
+ vars["MethodName"] = method->name();
+ printer->Print("\t");
+ auto func = GenerateServerFuncName(method.get());
+ printer->Print(vars, func.c_str());
+ printer->Print("\n");
+ }
+ printer->Print("}\n\n");
+
+ printer->Print(vars, "$ACCESS$ extension $ServiceName$Provider {\n");
+ printer->Print(vars,
+ "\tvar serviceName: String { return "
+ "\"$PATH$$ServiceName$\" }\n");
+ printer->Print(
+ "\tfunc handleMethod(_ methodName: String, callHandlerContext: "
+ "CallHandlerContext) -> GRPCCallHandler? {\n");
+ printer->Print("\t\tswitch methodName {\n");
+ for (auto it = 0; it < service->method_count(); it++) {
+ auto method = service->method(it);
+ vars["Input"] = GenerateMessage(method->get_input_type_name());
+ vars["Output"] = GenerateMessage(method->get_output_type_name());
+ vars["MethodName"] = method->name();
+ auto body = GenerateServerExtensionBody(method.get());
+ printer->Print(vars, body.c_str());
+ printer->Print("\n");
+ }
+ printer->Print("\t\tdefault: return nil;\n");
+ printer->Print("\t\t}\n");
+ printer->Print("\t}\n\n");
+ printer->Print("}\n\n");
+}
+
+grpc::string Generate(grpc_generator::File *file,
+ const grpc_generator::Service *service) {
+ grpc::string output;
+ std::map<grpc::string, grpc::string> vars;
+ vars["PATH"] = file->package();
+ if (!file->package().empty()) { vars["PATH"].append("."); }
+ vars["ServiceName"] = service->name();
+ vars["ACCESS"] = "public";
+ auto printer = file->CreatePrinter(&output);
+ printer->Print(vars,
+ "/// Usage: instantiate $ServiceName$ServiceClient, then call "
+ "methods of this protocol to make API calls.\n");
+ GenerateClientProtocol(service, &*printer, &vars);
+ GenerateClientClass(service, &*printer, &vars);
+ printer->Print("\n");
+ GenerateServerProtocol(service, &*printer, &vars);
+ return output;
+}
+
+grpc::string GenerateHeader() {
+ grpc::string code;
+ code +=
+ "/// The following code is generated by the Flatbuffers library which "
+ "might not be in sync with grpc-swift\n";
+ code +=
+ "/// in case of an issue please open github issue, though it would be "
+ "maintained\n";
+ code += "import Foundation\n";
+ code += "import GRPC\n";
+ code += "import NIO\n";
+ code += "import NIOHTTP1\n";
+ code += "import FlatBuffers\n";
+ code += "\n";
+ code +=
+ "public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage "
+ "{}\n";
+
+ code += "public extension GRPCFlatBufPayload {\n";
+ code += " init(serializedByteBuffer: inout NIO.ByteBuffer) throws {\n";
+ code +=
+ " self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: "
+ "serializedByteBuffer.readableBytesView, count: "
+ "serializedByteBuffer.readableBytes))\n";
+ code += " }\n";
+
+ code += " func serialize(into buffer: inout NIO.ByteBuffer) throws {\n";
+ code +=
+ " let buf = UnsafeRawBufferPointer(start: self.rawPointer, count: "
+ "Int(self.size))\n";
+ code += " buffer.writeBytes(buf)\n";
+ code += " }\n";
+ code += "}\n";
+ code += "extension Message: GRPCFlatBufPayload {}\n";
+ return code;
+}
+} // namespace grpc_swift_generator
diff --git a/grpc/src/compiler/swift_generator.h b/grpc/src/compiler/swift_generator.h
new file mode 100644
index 00000000..1639cb07
--- /dev/null
+++ b/grpc/src/compiler/swift_generator.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * Copyright 2020, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <memory>
+#include <vector>
+
+#include "src/compiler/config.h"
+#include "src/compiler/schema_interface.h"
+
+#ifndef GRPC_CUSTOM_STRING
+# include <string>
+# define GRPC_CUSTOM_STRING std::string
+#endif
+
+namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
+} // namespace grpc
+
+namespace grpc_swift_generator {
+grpc::string Generate(grpc_generator::File *file,
+ const grpc_generator::Service *service);
+grpc::string GenerateHeader();
+} // namespace grpc_swift_generator
diff --git a/grpc/tests/JavaGrpcTest.java b/grpc/tests/JavaGrpcTest.java
index 98a67b51..27329116 100644
--- a/grpc/tests/JavaGrpcTest.java
+++ b/grpc/tests/JavaGrpcTest.java
@@ -96,7 +96,7 @@ public class JavaGrpcTest {
if (monster.hp() > maxHp.get()) {
// Found a monster of higher hit points.
maxHp.set(monster.hp());
- maxHpMonsterName.set(monster.name());
+ maxHpMonsterName.set(monster.name());
maxHpCount.set(1);
}
else if (monster.hp() == maxHp.get()) {
@@ -141,7 +141,7 @@ public class JavaGrpcTest {
channel = ManagedChannelBuilder.forAddress("localhost", port)
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
// needing certificates.
- .usePlaintext(true)
+ .usePlaintext()
.directExecutor()
.build();
blockingStub = MonsterStorageGrpc.newBlockingStub(channel);
@@ -177,7 +177,7 @@ public class JavaGrpcTest {
final CountDownLatch streamAlive = new CountDownLatch(1);
StreamObserver<Stat> statObserver = new StreamObserver<Stat>() {
- public void onCompleted() {
+ public void onCompleted() {
streamAlive.countDown();
}
public void onError(Throwable ex) { }
diff --git a/grpc/tests/grpctest.cpp b/grpc/tests/grpctest.cpp
index 7e5c6e6c..decf5e51 100644
--- a/grpc/tests/grpctest.cpp
+++ b/grpc/tests/grpctest.cpp
@@ -14,17 +14,17 @@
* limitations under the License.
*/
-#include <thread>
-
#include <grpc++/grpc++.h>
+#include <thread>
+
#include "monster_test.grpc.fb.h"
#include "monster_test_generated.h"
#include "test_assert.h"
using namespace MyGame::Example;
-using flatbuffers::grpc::MessageBuilder;
using flatbuffers::FlatBufferBuilder;
+using flatbuffers::grpc::MessageBuilder;
void message_builder_tests();
@@ -97,8 +97,7 @@ void RunServer() {
server_instance->Wait();
}
-template <class Builder>
-void StoreRPC(MonsterStorage::Stub *stub) {
+template<class Builder> void StoreRPC(MonsterStorage::Stub *stub) {
Builder fbb;
grpc::ClientContext context;
// Build a request with the name set.
@@ -119,8 +118,7 @@ void StoreRPC(MonsterStorage::Stub *stub) {
}
}
-template <class Builder>
-void RetrieveRPC(MonsterStorage::Stub *stub) {
+template<class Builder> void RetrieveRPC(MonsterStorage::Stub *stub) {
Builder fbb;
grpc::ClientContext context;
fbb.Clear();
@@ -155,7 +153,6 @@ int grpc_server_test() {
RetrieveRPC<MessageBuilder>(stub.get());
RetrieveRPC<FlatBufferBuilder>(stub.get());
-
#if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
{
// Test that an invalid request errors out correctly
@@ -181,7 +178,7 @@ int grpc_server_test() {
return 0;
}
-int main(int /*argc*/, const char * /*argv*/ []) {
+int main(int /*argc*/, const char * /*argv*/[]) {
message_builder_tests();
grpc_server_test();
@@ -193,4 +190,3 @@ int main(int /*argc*/, const char * /*argv*/ []) {
return 1;
}
}
-
diff --git a/grpc/tests/grpctest.py b/grpc/tests/grpctest.py
new file mode 100644
index 00000000..1c5e92f0
--- /dev/null
+++ b/grpc/tests/grpctest.py
@@ -0,0 +1,174 @@
+from __future__ import print_function
+
+import os
+import sys
+import grpc
+import flatbuffers
+
+from concurrent import futures
+
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'tests'))
+import MyGame.Example.Monster as Monster
+import MyGame.Example.Stat as Stat
+import MyGame.Example.Vec3 as Vec3
+import MyGame.Example.Test as Test
+import MyGame.Example.monster_test_grpc_fb as monster_grpc_fb
+
+
+test_stat_id = "test_stat_id"
+test_stat_val = 8
+test_stat_count = 1
+
+test_monster_name1 = "test_monster_name1"
+test_monster_name2 = "test_monster_name2"
+test_string = "test_string"
+test_color = 2
+test_X = 3.0
+test_Y = 2.0
+test_Z = 6.0
+test_test1 = 4.0
+test_a = 8
+test_b = 5
+test_hp = 67
+test_inventory = [1, 1, 2, 3, 5, 8]
+test_testtype = 4
+
+test_monsters_name_retrieve = ["big_monster", "small_monster"]
+test_no_of_monsters = 2
+
+
+class MonsterStorage(monster_grpc_fb.MonsterStorageServicer):
+
+ def Store(self, request, context):
+
+ m = Monster.Monster().GetRootAsMonster(request, 0)
+
+ assert m.Name().decode("utf-8") == test_monster_name1
+
+ assert m.Pos().X() == test_X
+ assert m.Pos().Y() == test_Y
+ assert m.Pos().Z() == test_Z
+ assert m.Pos().Test1() == test_test1
+ assert m.Pos().Test2() == test_color
+ test3 = Test.Test()
+ assert m.Pos().Test3(test3).A() == test_a
+ assert m.Pos().Test3(test3).B() == test_b
+
+ assert m.Hp() == test_hp
+
+ assert m.Color() == test_color
+
+ assert m.InventoryLength() == len(test_inventory)
+ for i in range(0, len(test_inventory)):
+ assert m.Inventory(i) == test_inventory[len(test_inventory)-i -1]
+
+ assert m.TestType() == test_testtype
+
+ assert m.Test() is not None
+ table = m.Test()
+
+ m2 = Monster.Monster()
+ m2.Init(table.Bytes, table.Pos)
+ assert m2.Name().decode("utf-8") == test_monster_name2
+
+ m3 = m.Enemy()
+ assert m3.Name().decode("utf-8") == test_monster_name2
+
+ assert m.Testarrayofstring(0).decode("utf-8") == test_string
+
+ b = flatbuffers.Builder(0)
+ i = b.CreateString(test_stat_id)
+ Stat.StatStart(b)
+ Stat.StatAddId(b, i)
+ Stat.StatAddVal(b, test_stat_val)
+ Stat.StatAddCount(b, test_stat_count)
+ b.Finish(Stat.StatEnd(b))
+ return bytes(b.Output())
+
+ def Retrieve(self, request, context):
+
+ s = Stat.Stat().GetRootAsStat(request, 0)
+
+ no_of_monsters = test_no_of_monsters
+ for i in range(0, no_of_monsters):
+ b = flatbuffers.Builder(0)
+ i = b.CreateString(test_monsters_name_retrieve[i])
+ Monster.MonsterStart(b)
+ Monster.MonsterAddName(b, i)
+ b.Finish(Monster.MonsterEnd(b))
+ yield bytes(b.Output())
+
+
+def serve():
+
+ server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+ monster_grpc_fb.add_MonsterStorageServicer_to_server(MonsterStorage(), server)
+ server.add_insecure_port('[::]:50051')
+
+ server.start()
+
+ run()
+
+
+def run():
+
+ channel = grpc.insecure_channel('127.0.0.1:50051')
+ stub = monster_grpc_fb.MonsterStorageStub(channel)
+
+ b = flatbuffers.Builder(0)
+ name2 = b.CreateString(test_monster_name2)
+ name1 = b.CreateString(test_monster_name1)
+ Monster.MonsterStart(b)
+ Monster.MonsterAddName(b, name2)
+ monster2 = Monster.MonsterEnd(b)
+ test1 = b.CreateString(test_string)
+
+ Monster.MonsterStartInventoryVector(b, len(test_inventory))
+ for i in range(0, len(test_inventory)):
+ b.PrependByte(test_inventory[i])
+ inv = b.EndVector(len(test_inventory))
+
+ Monster.MonsterStartTest4Vector(b, 2)
+ Test.CreateTest(b, 10, 20)
+ Test.CreateTest(b, 30, 40)
+ test4 = b.EndVector(2)
+
+ Monster.MonsterStartTestarrayofstringVector(b, 1)
+ b.PrependUOffsetTRelative(test1)
+ test_array_of_string = b.EndVector(1)
+
+ Monster.MonsterStart(b)
+
+ Monster.MonsterAddHp(b, test_hp)
+ Monster.MonsterAddName(b, name1)
+ Monster.MonsterAddColor(b, test_color)
+ pos = Vec3.CreateVec3(b, test_X, test_Y, test_Z, test_test1, test_color, test_a, test_b)
+ Monster.MonsterAddPos(b, pos)
+ Monster.MonsterAddInventory(b, inv)
+ Monster.MonsterAddTestType(b, test_testtype)
+ Monster.MonsterAddTest(b, monster2)
+ Monster.MonsterAddTest4(b, test4)
+ Monster.MonsterAddEnemy(b, monster2)
+ Monster.MonsterAddTestarrayofstring(b, test_array_of_string)
+ monster = Monster.MonsterEnd(b)
+
+ b.Finish(monster)
+
+ stat_response = stub.Store(bytes(b.Output()))
+
+ s = Stat.Stat().GetRootAsStat(stat_response, 0)
+
+ assert s.Id().decode("utf-8") == test_stat_id
+ assert s.Val() == test_stat_val
+ assert s.Count() == test_stat_count
+
+ monster_reponses = stub.Retrieve(stat_response)
+ count = 0
+ for monster_reponse in monster_reponses:
+ m = Monster.Monster().GetRootAsMonster(monster_reponse, 0)
+ assert m.Name().decode("utf-8") == test_monsters_name_retrieve[count]
+ count = count + 1
+
+
+if __name__ == '__main__':
+ serve()
diff --git a/grpc/tests/message_builder_test.cpp b/grpc/tests/message_builder_test.cpp
index 36f5bc2e..3ce33a98 100644
--- a/grpc/tests/message_builder_test.cpp
+++ b/grpc/tests/message_builder_test.cpp
@@ -3,22 +3,28 @@
#include "test_assert.h"
#include "test_builder.h"
-using MyGame::Example::Vec3;
-using MyGame::Example::CreateStat;
using MyGame::Example::Any_NONE;
+using MyGame::Example::CreateStat;
+using MyGame::Example::Vec3;
-bool verify(flatbuffers::grpc::Message<Monster> &msg, const std::string &expected_name, Color color) {
+bool verify(flatbuffers::grpc::Message<Monster> &msg,
+ const std::string &expected_name, Color expected_color) {
const Monster *monster = msg.GetRoot();
- return (monster->name()->str() == expected_name) && (monster->color() == color);
+ const auto name = monster->name()->str();
+ const auto color = monster->color();
+ TEST_EQ(name, expected_name);
+ TEST_EQ(color, expected_color);
+ return (name == expected_name) && (color == expected_color);
}
-bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color) {
+bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
+ const std::string &expected_name, Color expected_color) {
flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
- const Monster *monster = msg.GetRoot();
- return (monster->name()->str() == expected_name) && (monster->color() == color);
+ return verify(msg, expected_name, expected_color);
}
-void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder dst) {
+void builder_move_assign_after_releaseraw_test(
+ flatbuffers::grpc::MessageBuilder dst) {
auto root_offset1 = populate1(dst);
dst.Finish(root_offset1);
size_t size, offset;
@@ -31,17 +37,16 @@ void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder
// Move into a released builder.
dst = std::move(src);
TEST_EQ(dst.GetSize(), src_size);
- TEST_ASSERT(release_n_verify(dst, m2_name, m2_color));
+ TEST_ASSERT(release_n_verify(dst, m2_name(), m2_color()));
TEST_EQ(src.GetSize(), 0);
grpc_slice_unref(slice);
}
-template <class SrcBuilder>
+template<class SrcBuilder>
struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
- static void builder_reusable_after_release_message_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) {
- return;
- }
+ static void builder_reusable_after_release_message_test(
+ TestSelector selector) {
+ if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) { return; }
flatbuffers::grpc::MessageBuilder mb;
std::vector<flatbuffers::grpc::Message<Monster>> buffers;
@@ -49,17 +54,15 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
auto root_offset1 = populate1(mb);
mb.Finish(root_offset1);
buffers.push_back(mb.ReleaseMessage<Monster>());
- TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
}
}
static void builder_reusable_after_release_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE)) {
- return;
- }
+ if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
- // FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in SliceAllocator::allocate
- // in the second iteration.
+ // FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in
+ // SliceAllocator::allocate in the second iteration.
flatbuffers::grpc::MessageBuilder mb;
std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -67,14 +70,12 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
auto root_offset1 = populate1(mb);
mb.Finish(root_offset1);
buffers.push_back(mb.Release());
- TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
}
}
static void builder_reusable_after_releaseraw_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
- return;
- }
+ if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
flatbuffers::grpc::MessageBuilder mb;
for (int i = 0; i < 5; ++i) {
@@ -83,18 +84,18 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
size_t size, offset;
grpc_slice slice;
const uint8_t *buf = mb.ReleaseRaw(size, offset, slice);
- TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
grpc_slice_unref(slice);
}
}
- static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
- return;
- }
+ static void builder_reusable_after_release_and_move_assign_test(
+ TestSelector selector) {
+ if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
- // FIXME: Release-move_assign loop fails assert(p == GRPC_SLICE_START_PTR(slice_))
- // in DetachedBuffer destructor after all the iterations
+ // FIXME: Release-move_assign loop fails assert(p ==
+ // GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the
+ // iterations
flatbuffers::grpc::MessageBuilder dst;
std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -103,7 +104,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
auto root_offset1 = populate1(dst);
dst.Finish(root_offset1);
buffers.push_back(dst.Release());
- TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
// bring dst back to life.
SrcBuilder src;
@@ -113,7 +114,8 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
}
}
- static void builder_reusable_after_release_message_and_move_assign_test(TestSelector selector) {
+ static void builder_reusable_after_release_message_and_move_assign_test(
+ TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
return;
}
@@ -125,7 +127,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
auto root_offset1 = populate1(dst);
dst.Finish(root_offset1);
buffers.push_back(dst.ReleaseMessage<Monster>());
- TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
// bring dst back to life.
SrcBuilder src;
@@ -135,10 +137,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
}
}
- static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
- return;
- }
+ static void builder_reusable_after_releaseraw_and_move_assign_test(
+ TestSelector selector) {
+ if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
flatbuffers::grpc::MessageBuilder dst;
for (int i = 0; i < 5; ++i) {
@@ -147,7 +148,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
size_t size, offset;
grpc_slice slice = grpc_empty_slice();
const uint8_t *buf = dst.ReleaseRaw(size, offset, slice);
- TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
grpc_slice_unref(slice);
SrcBuilder src;
@@ -175,11 +176,11 @@ void slice_allocator_tests() {
uint8_t *buf = sa1.allocate(size);
TEST_ASSERT_FUNC(buf != 0);
buf[0] = 100;
- buf[size-1] = 200;
+ buf[size - 1] = 200;
flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
// buf should not be deleted after move-construct
TEST_EQ_FUNC(buf[0], 100);
- TEST_EQ_FUNC(buf[size-1], 200);
+ TEST_EQ_FUNC(buf[size - 1], 200);
// buf is freed here
}
@@ -194,13 +195,16 @@ void slice_allocator_tests() {
}
}
-/// This function does not populate exactly the first half of the table. But it could.
-void populate_first_half(MyGame::Example::MonsterBuilder &wrapper, flatbuffers::Offset<flatbuffers::String> name_offset) {
+/// This function does not populate exactly the first half of the table. But it
+/// could.
+void populate_first_half(MyGame::Example::MonsterBuilder &wrapper,
+ flatbuffers::Offset<flatbuffers::String> name_offset) {
wrapper.add_name(name_offset);
- wrapper.add_color(m1_color);
+ wrapper.add_color(m1_color());
}
-/// This function does not populate exactly the second half of the table. But it could.
+/// This function does not populate exactly the second half of the table. But it
+/// could.
void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
wrapper.add_hp(77);
wrapper.add_mana(88);
@@ -208,114 +212,138 @@ void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
wrapper.add_pos(&vec3);
}
-/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in the MonsterBuilder object.
-/// This function will break if fbb_ is not the first member in MonsterBuilder. In that case, some offset must be added.
-/// This function is used exclusively for testing correctness of move operations between FlatBufferBuilders.
-/// If MonsterBuilder had a fbb_ pointer, this hack would be unnecessary. That involves a code-generator change though.
-void test_only_hack_update_fbb_reference(MyGame::Example::MonsterBuilder &monsterBuilder,
- flatbuffers::grpc::MessageBuilder &mb) {
+/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in
+/// the MonsterBuilder object. This function will break if fbb_ is not the first
+/// member in MonsterBuilder. In that case, some offset must be added. This
+/// function is used exclusively for testing correctness of move operations
+/// between FlatBufferBuilders. If MonsterBuilder had a fbb_ pointer, this hack
+/// would be unnecessary. That involves a code-generator change though.
+void test_only_hack_update_fbb_reference(
+ MyGame::Example::MonsterBuilder &monsterBuilder,
+ flatbuffers::grpc::MessageBuilder &mb) {
*reinterpret_cast<flatbuffers::FlatBufferBuilder **>(&monsterBuilder) = &mb;
}
-/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
-/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
-/// of the table is constructed using a MessageBuilder.
+/// This test validates correctness of move conversion of FlatBufferBuilder to a
+/// MessageBuilder DURING a table construction. Half of the table is constructed
+/// using FlatBufferBuilder and the other half of the table is constructed using
+/// a MessageBuilder.
void builder_move_ctor_conversion_before_finish_half_n_half_table_test() {
- for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
+ for (size_t initial_size = 4; initial_size <= 2048; initial_size *= 2) {
flatbuffers::FlatBufferBuilder fbb(initial_size);
- auto name_offset = fbb.CreateString(m1_name);
- MyGame::Example::MonsterBuilder monsterBuilder(fbb); // starts a table in FlatBufferBuilder
+ auto name_offset = fbb.CreateString(m1_name());
+ MyGame::Example::MonsterBuilder monsterBuilder(
+ fbb); // starts a table in FlatBufferBuilder
populate_first_half(monsterBuilder, name_offset);
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
- test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
+ test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
populate_second_half(monsterBuilder);
- mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
- TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+ mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
+ TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
-/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
+/// This test populates a COMPLETE inner table before move conversion and later
+/// populates more members in the outer table.
void builder_move_ctor_conversion_before_finish_test() {
- for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
+ for (size_t initial_size = 1; initial_size <= 2048; initial_size += 1) {
flatbuffers::FlatBufferBuilder fbb(initial_size);
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
- auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
+ auto monster_offset =
+ CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
+ m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset);
- TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+ {
+ auto mon = flatbuffers::GetRoot<Monster>(mb.GetBufferPointer());
+ TEST_NOTNULL(mon);
+ TEST_NOTNULL(mon->name());
+ TEST_EQ_STR(mon->name()->c_str(), m1_name().c_str());
+ TEST_EQ(mon->color(), m1_color());
+ }
+ TEST_EQ(1, MyGame::Example::Color_Red);
+ TEST_EQ(1, m1_color());
+ TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
-/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
-/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
-/// of the table is constructed using a MessageBuilder.
+/// This test validates correctness of move conversion of FlatBufferBuilder to a
+/// MessageBuilder DURING a table construction. Half of the table is constructed
+/// using FlatBufferBuilder and the other half of the table is constructed using
+/// a MessageBuilder.
void builder_move_assign_conversion_before_finish_half_n_half_table_test() {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb;
- for (int i = 0;i < 5; ++i) {
+ for (int i = 0; i < 5; ++i) {
flatbuffers::FlatBufferBuilder fbb;
- auto name_offset = fbb.CreateString(m1_name);
- MyGame::Example::MonsterBuilder monsterBuilder(fbb); // starts a table in FlatBufferBuilder
+ auto name_offset = fbb.CreateString(m1_name());
+ MyGame::Example::MonsterBuilder monsterBuilder(
+ fbb); // starts a table in FlatBufferBuilder
populate_first_half(monsterBuilder, name_offset);
mb = std::move(fbb);
- test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
+ test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
populate_second_half(monsterBuilder);
- mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
- TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+ mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
+ TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
-/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
+/// This test populates a COMPLETE inner table before move conversion and later
+/// populates more members in the outer table.
void builder_move_assign_conversion_before_finish_test() {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb;
- for (int i = 0;i < 5; ++i) {
+ for (int i = 0; i < 5; ++i) {
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
mb = std::move(fbb);
- auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
+ auto monster_offset =
+ CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
+ m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset);
- TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
-/// This test populates data, finishes the buffer, and does move conversion after.
+/// This test populates data, finishes the buffer, and does move conversion
+/// after.
void builder_move_ctor_conversion_after_finish_test() {
flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(populate1(fbb));
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
- TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
-/// This test populates data, finishes the buffer, and does move conversion after.
+/// This test populates data, finishes the buffer, and does move conversion
+/// after.
void builder_move_assign_conversion_after_finish_test() {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb;
- for (int i = 0;i < 5; ++i) {
+ for (int i = 0; i < 5; ++i) {
fbb.Finish(populate1(fbb));
mb = std::move(fbb);
- TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
void message_builder_tests() {
- using flatbuffers::grpc::MessageBuilder;
using flatbuffers::FlatBufferBuilder;
+ using flatbuffers::grpc::MessageBuilder;
slice_allocator_tests();
#ifndef __APPLE__
builder_move_ctor_conversion_before_finish_half_n_half_table_test();
builder_move_assign_conversion_before_finish_half_n_half_table_test();
-#endif // __APPLE__
+#endif // __APPLE__
builder_move_ctor_conversion_before_finish_test();
builder_move_assign_conversion_before_finish_test();
@@ -326,15 +354,18 @@ void message_builder_tests() {
BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests();
BuilderReuseTestSelector tests[6] = {
- //REUSABLE_AFTER_RELEASE, // Assertion failed: (GRPC_SLICE_IS_EMPTY(slice_))
- //REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p == GRPC_SLICE_START_PTR(slice_)
+ // REUSABLE_AFTER_RELEASE, // Assertion failed:
+ // (GRPC_SLICE_IS_EMPTY(slice_))
+ // REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p ==
+ // GRPC_SLICE_START_PTR(slice_)
- REUSABLE_AFTER_RELEASE_RAW,
- REUSABLE_AFTER_RELEASE_MESSAGE,
+ REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE,
REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
};
- BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(TestSelector(tests, tests+6));
- BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+6));
+ BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(
+ TestSelector(tests, tests + 6));
+ BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(
+ TestSelector(tests, tests + 6));
}
diff --git a/grpc/tests/pom.xml b/grpc/tests/pom.xml
index 5f8731e5..117bec67 100644
--- a/grpc/tests/pom.xml
+++ b/grpc/tests/pom.xml
@@ -4,13 +4,13 @@
<parent>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-parent</artifactId>
- <version>1.11.0</version>
+ <version>1.12.0</version>
</parent>
<artifactId>grpc-test</artifactId>
<description>Example/Test project demonstrating usage of flatbuffers with GRPC-Java instead of protobufs
</description>
<properties>
- <gRPC.version>1.11.0</gRPC.version>
+ <gRPC.version>1.12.0</gRPC.version>
</properties>
<dependencies>
<dependency>
diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h
index ee8021fd..95573806 100644
--- a/include/flatbuffers/base.h
+++ b/include/flatbuffers/base.h
@@ -55,6 +55,10 @@
#include "flatbuffers/stl_emulation.h"
+#if defined(__ICCARM__)
+#include <intrinsics.h>
+#endif
+
// Note the __clang__ check is needed, because clang presents itself
// as an older GNUC compiler (4.2).
// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
@@ -95,7 +99,7 @@
#if !defined(__clang__) && \
defined(__GNUC__) && \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
- // Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr
+ // Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr
// and constexpr keywords. Note the __clang__ check is needed, because clang
// presents itself as an older GNUC compiler.
#ifndef nullptr_t
@@ -117,7 +121,7 @@
#define FLATBUFFERS_LITTLEENDIAN 0
#endif // __s390x__
#if !defined(FLATBUFFERS_LITTLEENDIAN)
- #if defined(__GNUC__) || defined(__clang__)
+ #if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
#if (defined(__BIG_ENDIAN__) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define FLATBUFFERS_LITTLEENDIAN 0
@@ -136,10 +140,14 @@
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
#define FLATBUFFERS_VERSION_MAJOR 1
-#define FLATBUFFERS_VERSION_MINOR 11
+#define FLATBUFFERS_VERSION_MINOR 12
#define FLATBUFFERS_VERSION_REVISION 0
#define FLATBUFFERS_STRING_EXPAND(X) #X
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
+namespace flatbuffers {
+ // Returns version as string "MAJOR.MINOR.REVISION".
+ const char* FLATBUFFERS_VERSION();
+}
#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \
@@ -191,7 +199,7 @@
// to detect a header that provides an implementation
#if defined(__has_include)
// Check for std::string_view (in c++17)
- #if __has_include(<string_view>) && (__cplusplus >= 201606 || _HAS_CXX17)
+ #if __has_include(<string_view>) && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17))
#include <string_view>
namespace flatbuffers {
typedef std::string_view string_view;
@@ -204,6 +212,13 @@
typedef std::experimental::string_view string_view;
}
#define FLATBUFFERS_HAS_STRING_VIEW 1
+ // Check for absl::string_view
+ #elif __has_include("absl/strings/string_view.h")
+ #include "absl/strings/string_view.h"
+ namespace flatbuffers {
+ typedef absl::string_view string_view;
+ }
+ #define FLATBUFFERS_HAS_STRING_VIEW 1
#endif
#endif // __has_include
#endif // !FLATBUFFERS_HAS_STRING_VIEW
@@ -234,7 +249,7 @@
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
// - __supress_ubsan__("undefined")
// - __supress_ubsan__("signed-integer-overflow")
-#if defined(__clang__)
+#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))
#define __supress_ubsan__(type) __attribute__((no_sanitize(type)))
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
#define __supress_ubsan__(type) __attribute__((no_sanitize_undefined))
@@ -288,7 +303,7 @@ typedef uint16_t voffset_t;
typedef uintmax_t largest_scalar_t;
// In 32bits, this evaluates to 2GB - 1
-#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
+#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1)
// We support aligning the contents of buffers up to this size.
#define FLATBUFFERS_MAX_ALIGNMENT 16
@@ -303,6 +318,11 @@ template<typename T> T EndianSwap(T t) {
#define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
#define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
#define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
+ #elif defined(__ICCARM__)
+ #define FLATBUFFERS_BYTESWAP16 __REV16
+ #define FLATBUFFERS_BYTESWAP32 __REV
+ #define FLATBUFFERS_BYTESWAP64(x) \
+ ((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U)
#else
#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
// __builtin_bswap16 was missing prior to GCC 4.8.
@@ -317,22 +337,20 @@ template<typename T> T EndianSwap(T t) {
if (sizeof(T) == 1) { // Compile-time if-then's.
return t;
} else if (sizeof(T) == 2) {
- union { T t; uint16_t i; } u;
- u.t = t;
+ union { T t; uint16_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP16(u.i);
return u.t;
} else if (sizeof(T) == 4) {
- union { T t; uint32_t i; } u;
- u.t = t;
+ union { T t; uint32_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP32(u.i);
return u.t;
} else if (sizeof(T) == 8) {
- union { T t; uint64_t i; } u;
- u.t = t;
+ union { T t; uint64_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP64(u.i);
return u.t;
} else {
FLATBUFFERS_ASSERT(0);
+ return t;
}
}
@@ -371,6 +389,7 @@ template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Of
// Computes how many bytes you'd have to pad to be able to write an
// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
// memory).
+__supress_ubsan__("unsigned-integer-overflow")
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
return ((~buf_size) + 1) & (scalar_size - 1);
}
diff --git a/include/flatbuffers/code_generators.h b/include/flatbuffers/code_generators.h
index c2ed707a..bccd9fe0 100644
--- a/include/flatbuffers/code_generators.h
+++ b/include/flatbuffers/code_generators.h
@@ -19,6 +19,7 @@
#include <map>
#include <sstream>
+
#include "flatbuffers/idl.h"
namespace flatbuffers {
@@ -26,7 +27,7 @@ namespace flatbuffers {
// Utility class to assist in generating code through use of text templates.
//
// Example code:
-// CodeWriter code;
+// CodeWriter code("\t");
// code.SetValue("NAME", "Foo");
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
// code.SetValue("NAME", "Bar");
@@ -38,7 +39,8 @@ namespace flatbuffers {
// void Bar() { printf("%s", "Bar"); }
class CodeWriter {
public:
- CodeWriter() {}
+ CodeWriter(std::string pad = std::string())
+ : pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {}
// Clears the current "written" code.
void Clear() {
@@ -53,6 +55,11 @@ class CodeWriter {
value_map_[key] = value;
}
+ std::string GetValue(const std::string &key) const {
+ const auto it = value_map_.find(key);
+ return it == value_map_.end() ? "" : it->second;
+ }
+
// Appends the given text to the generated code as well as a newline
// character. Any text within {{ and }} delimeters is replaced by values
// previously stored in the CodeWriter by calling SetValue above. The newline
@@ -62,9 +69,22 @@ class CodeWriter {
// Returns the current contents of the CodeWriter as a std::string.
std::string ToString() const { return stream_.str(); }
+ // Increase ident level for writing code
+ void IncrementIdentLevel() { cur_ident_lvl_++; }
+ // Decrease ident level for writing code
+ void DecrementIdentLevel() {
+ if (cur_ident_lvl_) cur_ident_lvl_--;
+ }
+
private:
std::map<std::string, std::string> value_map_;
std::stringstream stream_;
+ std::string pad_;
+ int cur_ident_lvl_;
+ bool ignore_ident_;
+
+ // Add ident padding (tab or space) based on ident level
+ void AppendIdent(std::stringstream &stream);
};
class BaseGenerator {
@@ -74,16 +94,20 @@ class BaseGenerator {
static std::string NamespaceDir(const Parser &parser, const std::string &path,
const Namespace &ns);
+ std::string GeneratedFileName(const std::string &path,
+ const std::string &file_name,
+ const IDLOptions &options) const;
+
protected:
BaseGenerator(const Parser &parser, const std::string &path,
- const std::string &file_name,
- const std::string qualifying_start,
- const std::string qualifying_separator)
+ const std::string &file_name, std::string qualifying_start,
+ std::string qualifying_separator, std::string default_extension)
: parser_(parser),
path_(path),
file_name_(file_name),
qualifying_start_(qualifying_start),
- qualifying_separator_(qualifying_separator) {}
+ qualifying_separator_(qualifying_separator),
+ default_extension_(default_extension) {}
virtual ~BaseGenerator() {}
// No copy/assign.
@@ -104,8 +128,9 @@ class BaseGenerator {
// which works for js and php
virtual const Namespace *CurrentNameSpace() const { return nullptr; }
- // Ensure that a type is prefixed with its namespace whenever it is used
- // outside of its namespace.
+ // Ensure that a type is prefixed with its namespace even within
+ // its own namespace to avoid conflict between generated method
+ // names and similarly named classes or structs
std::string WrapInNameSpace(const Namespace *ns,
const std::string &name) const;
@@ -118,6 +143,7 @@ class BaseGenerator {
const std::string &file_name_;
const std::string qualifying_start_;
const std::string qualifying_separator_;
+ const std::string default_extension_;
};
struct CommentConfig {
diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h
index a1a95f00..c4dc5bcd 100644
--- a/include/flatbuffers/flatbuffers.h
+++ b/include/flatbuffers/flatbuffers.h
@@ -20,24 +20,43 @@
#include "flatbuffers/base.h"
#if defined(FLATBUFFERS_NAN_DEFAULTS)
-#include <cmath>
+# include <cmath>
#endif
namespace flatbuffers {
// Generic 'operator==' with conditional specialisations.
+// T e - new value of a scalar field.
+// T def - default of scalar (is known at compile-time).
template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
- (!defined(_MSC_VER) || _MSC_VER >= 1800)
+ defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Like `operator==(e, def)` with weak NaN if T=(float|double).
+template<typename T> inline bool IsFloatTheSameAs(T e, T def) {
+ return (e == def) || ((def != def) && (e != e));
+}
template<> inline bool IsTheSameAs<float>(float e, float def) {
- return (e == def) || (std::isnan(def) && std::isnan(e));
+ return IsFloatTheSameAs(e, def);
}
template<> inline bool IsTheSameAs<double>(double e, double def) {
- return (e == def) || (std::isnan(def) && std::isnan(e));
+ return IsFloatTheSameAs(e, def);
}
#endif
+// Check 'v' is out of closed range [low; high].
+// Workaround for GCC warning [-Werror=type-limits]:
+// comparison is always true due to limited range of data type.
+template<typename T>
+inline bool IsOutRange(const T &v, const T &low, const T &high) {
+ return (v < low) || (high < v);
+}
+
+// Check 'v' is in closed range [low; high].
+template<typename T>
+inline bool IsInRange(const T &v, const T &low, const T &high) {
+ return !IsOutRange(v, low, high);
+}
+
// Wrapper for uoffset_t to allow safe template specialization.
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
template<typename T> struct Offset {
@@ -198,17 +217,18 @@ template<typename T, typename IT> struct VectorIterator {
const uint8_t *data_;
};
-template<typename Iterator> struct VectorReverseIterator :
- public std::reverse_iterator<Iterator> {
+template<typename Iterator>
+struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
+ explicit VectorReverseIterator(Iterator iter)
+ : std::reverse_iterator<Iterator>(iter) {}
- explicit VectorReverseIterator(Iterator iter) : iter_(iter) {}
-
- typename Iterator::value_type operator*() const { return *(iter_ - 1); }
-
- typename Iterator::value_type operator->() const { return *(iter_ - 1); }
+ typename Iterator::value_type operator*() const {
+ return *(std::reverse_iterator<Iterator>::current);
+ }
- private:
- Iterator iter_;
+ typename Iterator::value_type operator->() const {
+ return *(std::reverse_iterator<Iterator>::current);
+ }
};
struct String;
@@ -269,11 +289,15 @@ template<typename T> class Vector {
iterator end() { return iterator(Data(), size()); }
const_iterator end() const { return const_iterator(Data(), size()); }
- reverse_iterator rbegin() { return reverse_iterator(end()); }
- const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end() - 1);
+ }
- reverse_iterator rend() { return reverse_iterator(end()); }
- const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin() - 1); }
+ const_reverse_iterator rend() const {
+ return const_reverse_iterator(begin() - 1);
+ }
const_iterator cbegin() const { return begin(); }
@@ -341,6 +365,7 @@ template<typename T> class Vector {
// This class is a pointer. Copying will therefore create an invalid object.
// Private and unimplemented copy constructor.
Vector(const Vector &);
+ Vector &operator=(const Vector &);
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
const K *key = reinterpret_cast<const K *>(ap);
@@ -371,6 +396,7 @@ class VectorOfAny {
private:
VectorOfAny(const VectorOfAny &);
+ VectorOfAny &operator=(const VectorOfAny &);
};
#ifndef FLATBUFFERS_CPP98_STL
@@ -393,6 +419,131 @@ template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
return v ? v->size() : 0;
}
+// This is used as a helper type for accessing arrays.
+template<typename T, uint16_t length> class Array {
+ typedef
+ typename flatbuffers::integral_constant<bool,
+ flatbuffers::is_scalar<T>::value>
+ scalar_tag;
+ typedef
+ typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type
+ IndirectHelperType;
+
+ public:
+ typedef typename IndirectHelper<IndirectHelperType>::return_type return_type;
+ typedef VectorIterator<T, return_type> const_iterator;
+ typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
+
+ FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; }
+
+ return_type Get(uoffset_t i) const {
+ FLATBUFFERS_ASSERT(i < size());
+ return IndirectHelper<IndirectHelperType>::Read(Data(), i);
+ }
+
+ return_type operator[](uoffset_t i) const { return Get(i); }
+
+ // If this is a Vector of enums, T will be its storage type, not the enum
+ // type. This function makes it convenient to retrieve value with enum
+ // type E.
+ template<typename E> E GetEnum(uoffset_t i) const {
+ return static_cast<E>(Get(i));
+ }
+
+ const_iterator begin() const { return const_iterator(Data(), 0); }
+ const_iterator end() const { return const_iterator(Data(), size()); }
+
+ const_reverse_iterator rbegin() const {
+ return const_reverse_iterator(end());
+ }
+ const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
+
+ const_iterator cbegin() const { return begin(); }
+ const_iterator cend() const { return end(); }
+
+ const_reverse_iterator crbegin() const { return rbegin(); }
+ const_reverse_iterator crend() const { return rend(); }
+
+ // Get a mutable pointer to elements inside this array.
+ // This method used to mutate arrays of structs followed by a @p Mutate
+ // operation. For primitive types use @p Mutate directly.
+ // @warning Assignments and reads to/from the dereferenced pointer are not
+ // automatically converted to the correct endianness.
+ typename flatbuffers::conditional<scalar_tag::value, void, T *>::type
+ GetMutablePointer(uoffset_t i) const {
+ FLATBUFFERS_ASSERT(i < size());
+ return const_cast<T *>(&data()[i]);
+ }
+
+ // Change elements if you have a non-const pointer to this object.
+ void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); }
+
+ // The raw data in little endian format. Use with care.
+ const uint8_t *Data() const { return data_; }
+
+ uint8_t *Data() { return data_; }
+
+ // Similarly, but typed, much like std::vector::data
+ const T *data() const { return reinterpret_cast<const T *>(Data()); }
+ T *data() { return reinterpret_cast<T *>(Data()); }
+
+ protected:
+ void MutateImpl(flatbuffers::integral_constant<bool, true>, uoffset_t i,
+ const T &val) {
+ FLATBUFFERS_ASSERT(i < size());
+ WriteScalar(data() + i, val);
+ }
+
+ void MutateImpl(flatbuffers::integral_constant<bool, false>, uoffset_t i,
+ const T &val) {
+ *(GetMutablePointer(i)) = val;
+ }
+
+ // This class is only used to access pre-existing data. Don't ever
+ // try to construct these manually.
+ // 'constexpr' allows us to use 'size()' at compile time.
+ // @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on
+ // a constructor.
+#if defined(__cpp_constexpr)
+ constexpr Array();
+#else
+ Array();
+#endif
+
+ uint8_t data_[length * sizeof(T)];
+
+ private:
+ // This class is a pointer. Copying will therefore create an invalid object.
+ // Private and unimplemented copy constructor.
+ Array(const Array &);
+ Array &operator=(const Array &);
+};
+
+// Specialization for Array[struct] with access using Offset<void> pointer.
+// This specialization used by idl_gen_text.cpp.
+template<typename T, uint16_t length> class Array<Offset<T>, length> {
+ static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
+
+ public:
+ typedef const void *return_type;
+
+ const uint8_t *Data() const { return data_; }
+
+ // Make idl_gen_text.cpp::PrintContainer happy.
+ return_type operator[](uoffset_t) const {
+ FLATBUFFERS_ASSERT(false);
+ return nullptr;
+ }
+
+ private:
+ // This class is only used to access pre-existing data.
+ Array();
+ Array(const Array &);
+ Array &operator=(const Array &);
+
+ uint8_t data_[1];
+};
+
// Lexicographically compare two strings (possibly containing nulls), and
// return true if the first is less than the second.
static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
@@ -420,13 +571,13 @@ struct String : public Vector<char> {
// Convenience function to get std::string from a String returning an empty
// string on null pointer.
-static inline std::string GetString(const String * str) {
+static inline std::string GetString(const String *str) {
return str ? str->str() : "";
}
// Convenience function to get char* from a String returning an empty string on
// null pointer.
-static inline const char * GetCstring(const String * str) {
+static inline const char *GetCstring(const String *str) {
return str ? str->c_str() : "";
}
@@ -463,9 +614,9 @@ class Allocator {
// to `new_p` of `new_size`. Only memory of size `in_use_front` and
// `in_use_back` will be copied from the front and back of the old memory
// allocation.
- void memcpy_downward(uint8_t *old_p, size_t old_size,
- uint8_t *new_p, size_t new_size,
- size_t in_use_back, size_t in_use_front) {
+ void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
+ size_t new_size, size_t in_use_back,
+ size_t in_use_front) {
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
in_use_back);
memcpy(new_p, old_p, in_use_front);
@@ -479,13 +630,9 @@ class DefaultAllocator : public Allocator {
return new uint8_t[size];
}
- void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE {
- delete[] p;
- }
+ void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
- static void dealloc(void *p, size_t) {
- delete[] static_cast<uint8_t *>(p);
- }
+ static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
};
// These functions allow for a null allocator to mean use the default allocator,
@@ -498,18 +645,19 @@ inline uint8_t *Allocate(Allocator *allocator, size_t size) {
}
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
- if (allocator) allocator->deallocate(p, size);
- else DefaultAllocator().deallocate(p, size);
+ if (allocator)
+ allocator->deallocate(p, size);
+ else
+ DefaultAllocator().deallocate(p, size);
}
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
size_t old_size, size_t new_size,
size_t in_use_back, size_t in_use_front) {
- return allocator
- ? allocator->reallocate_downward(old_p, old_size, new_size,
- in_use_back, in_use_front)
- : DefaultAllocator().reallocate_downward(old_p, old_size, new_size,
- in_use_back, in_use_front);
+ return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
+ in_use_back, in_use_front)
+ : DefaultAllocator().reallocate_downward(
+ old_p, old_size, new_size, in_use_back, in_use_front);
}
// DetachedBuffer is a finished flatbuffer memory region, detached from its
@@ -554,6 +702,8 @@ class DetachedBuffer {
#if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
DetachedBuffer &operator=(DetachedBuffer &&other) {
+ if (this == &other) return *this;
+
destroy();
allocator_ = other.allocator_;
@@ -610,7 +760,7 @@ class DetachedBuffer {
#endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
-protected:
+ protected:
Allocator *allocator_;
bool own_allocator_;
uint8_t *buf_;
@@ -642,10 +792,8 @@ protected:
// Essentially, this supports 2 std::vectors in a single buffer.
class vector_downward {
public:
- explicit vector_downward(size_t initial_size,
- Allocator *allocator,
- bool own_allocator,
- size_t buffer_minalign)
+ explicit vector_downward(size_t initial_size, Allocator *allocator,
+ bool own_allocator, size_t buffer_minalign)
: allocator_(allocator),
own_allocator_(own_allocator),
initial_size_(initial_size),
@@ -661,15 +809,15 @@ class vector_downward {
#else
vector_downward(vector_downward &other)
#endif // defined(FLATBUFFERS_CPP98_STL)
- // clang-format on
- : allocator_(other.allocator_),
- own_allocator_(other.own_allocator_),
- initial_size_(other.initial_size_),
- buffer_minalign_(other.buffer_minalign_),
- reserved_(other.reserved_),
- buf_(other.buf_),
- cur_(other.cur_),
- scratch_(other.scratch_) {
+ // clang-format on
+ : allocator_(other.allocator_),
+ own_allocator_(other.own_allocator_),
+ initial_size_(other.initial_size_),
+ buffer_minalign_(other.buffer_minalign_),
+ reserved_(other.reserved_),
+ buf_(other.buf_),
+ cur_(other.cur_),
+ scratch_(other.scratch_) {
// No change in other.allocator_
// No change in other.initial_size_
// No change in other.buffer_minalign_
@@ -713,9 +861,7 @@ class vector_downward {
clear_scratch();
}
- void clear_scratch() {
- scratch_ = buf_;
- }
+ void clear_scratch() { scratch_ = buf_; }
void clear_allocator() {
if (own_allocator_ && allocator_) { delete allocator_; }
@@ -801,7 +947,7 @@ class vector_downward {
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
void push(const uint8_t *bytes, size_t num) {
- memcpy(make_space(num), bytes, num);
+ if (num > 0) { memcpy(make_space(num), bytes, num); }
}
// Specialized version of push() that avoids memcpy call for small data.
@@ -824,6 +970,7 @@ class vector_downward {
}
// Version for when we know the size is larger.
+ // Precondition: zero_pad_bytes > 0
void fill_big(size_t zero_pad_bytes) {
memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
}
@@ -867,8 +1014,8 @@ class vector_downward {
auto old_reserved = reserved_;
auto old_size = size();
auto old_scratch_size = scratch_size();
- reserved_ += (std::max)(len,
- old_reserved ? old_reserved / 2 : initial_size_);
+ reserved_ +=
+ (std::max)(len, old_reserved ? old_reserved / 2 : initial_size_);
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
if (buf_) {
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
@@ -890,10 +1037,16 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
template<typename T, typename Alloc>
const T *data(const std::vector<T, Alloc> &v) {
- return v.empty() ? nullptr : &v.front();
+ // Eventually the returned pointer gets passed down to memcpy, so
+ // we need it to be non-null to avoid undefined behavior.
+ static uint8_t t;
+ return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
}
template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
- return v.empty() ? nullptr : &v.front();
+ // Eventually the returned pointer gets passed down to memcpy, so
+ // we need it to be non-null to avoid undefined behavior.
+ static uint8_t t;
+ return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
}
/// @endcond
@@ -920,11 +1073,10 @@ class FlatBufferBuilder {
/// minimum alignment upon reallocation. Only needed if you intend to store
/// types with custom alignment AND you wish to read the buffer in-place
/// directly after creation.
- explicit FlatBufferBuilder(size_t initial_size = 1024,
- Allocator *allocator = nullptr,
- bool own_allocator = false,
- size_t buffer_minalign =
- AlignOf<largest_scalar_t>())
+ explicit FlatBufferBuilder(
+ size_t initial_size = 1024, Allocator *allocator = nullptr,
+ bool own_allocator = false,
+ size_t buffer_minalign = AlignOf<largest_scalar_t>())
: buf_(initial_size, allocator, own_allocator, buffer_minalign),
num_field_loc(0),
max_voffset_(0),
@@ -1027,8 +1179,8 @@ class FlatBufferBuilder {
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
/// @return A `FlatBuffer` that owns the buffer and its allocator and
/// behaves similar to a `unique_ptr` with a deleter.
- FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer
- ReleaseBufferPointer() {
+ FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead"))
+ DetachedBuffer ReleaseBufferPointer() {
Finished();
return buf_.release();
}
@@ -1041,13 +1193,14 @@ class FlatBufferBuilder {
}
/// @brief Get the released pointer to the serialized buffer.
- /// @param The size of the memory block containing
+ /// @param size The size of the memory block containing
/// the serialized `FlatBuffer`.
- /// @param The offset from the released pointer where the finished
+ /// @param offset The offset from the released pointer where the finished
/// `FlatBuffer` starts.
/// @return A raw pointer to the start of the memory block containing
/// the serialized `FlatBuffer`.
- /// @remark If the allocator is owned, it gets deleted when the destructor is called..
+ /// @remark If the allocator is owned, it gets deleted when the destructor is
+ /// called..
uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
Finished();
return buf_.release_raw(size, offset);
@@ -1076,12 +1229,13 @@ class FlatBufferBuilder {
/// @brief In order to save space, fields that are set to their default value
/// don't get serialized into the buffer.
- /// @param[in] bool fd When set to `true`, always serializes default values that are set.
- /// Optional fields which are not set explicitly, will still not be serialized.
+ /// @param[in] fd When set to `true`, always serializes default values that
+ /// are set. Optional fields which are not set explicitly, will still not be
+ /// serialized.
void ForceDefaults(bool fd) { force_defaults_ = fd; }
/// @brief By default vtables are deduped in order to save space.
- /// @param[in] bool dedup When set to `true`, dedup vtables.
+ /// @param[in] dedup When set to `true`, dedup vtables.
void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
/// @cond FLATBUFFERS_INTERNAL
@@ -1235,7 +1389,7 @@ class FlatBufferBuilder {
it += sizeof(uoffset_t)) {
auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
- auto vt2_size = *vt2;
+ auto vt2_size = ReadScalar<voffset_t>(vt2);
if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
vt_use = *vt_offset_ptr;
buf_.pop(GetSize() - vtableoffsetloc);
@@ -1562,17 +1716,16 @@ class FlatBufferBuilder {
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
size_t len) {
extern T Pack(const S &);
- typedef T (*Pack_t)(const S &);
std::vector<T> vv(len);
- std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack));
- return CreateVectorOfStructs<T>(vv.data(), vv.size());
+ std::transform(v, v + len, vv.begin(), Pack);
+ return CreateVectorOfStructs<T>(data(vv), vv.size());
}
// clang-format off
#ifndef FLATBUFFERS_CPP98_STL
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
/// @tparam T The data type of the struct array elements.
- /// @param[in] f A function that takes the current iteration 0..vector_size-1
+ /// @param[in] filler A function that takes the current iteration 0..vector_size-1
/// and a pointer to the struct that must be filled.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1612,7 +1765,7 @@ class FlatBufferBuilder {
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
/// @tparam T The data type of the `std::vector` struct elements.
- /// @param[in]] v A const reference to the `std::vector` of structs to
+ /// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1626,7 +1779,7 @@ class FlatBufferBuilder {
/// `vector`.
/// @tparam T The data type of the `std::vector` struct elements.
/// @tparam S The data type of the `std::vector` native struct elements.
- /// @param[in]] v A const reference to the `std::vector` of structs to
+ /// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1650,7 +1803,7 @@ class FlatBufferBuilder {
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`
/// in sorted order.
/// @tparam T The data type of the `std::vector` struct elements.
- /// @param[in]] v A const reference to the `std::vector` of structs to
+ /// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1663,7 +1816,7 @@ class FlatBufferBuilder {
/// `vector` in sorted order.
/// @tparam T The data type of the `std::vector` struct elements.
/// @tparam S The data type of the `std::vector` native struct elements.
- /// @param[in]] v A const reference to the `std::vector` of structs to
+ /// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1702,13 +1855,14 @@ class FlatBufferBuilder {
extern T Pack(const S &);
typedef T (*Pack_t)(const S &);
std::vector<T> vv(len);
- std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack));
+ std::transform(v, v + len, vv.begin(), static_cast<Pack_t &>(Pack));
return CreateVectorOfSortedStructs<T>(vv, len);
}
/// @cond FLATBUFFERS_INTERNAL
template<typename T> struct TableKeyComparator {
TableKeyComparator(vector_downward &buf) : buf_(buf) {}
+ TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {}
bool operator()(const Offset<T> &a, const Offset<T> &b) const {
auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
@@ -1717,7 +1871,10 @@ class FlatBufferBuilder {
vector_downward &buf_;
private:
- TableKeyComparator &operator=(const TableKeyComparator &);
+ TableKeyComparator &operator=(const TableKeyComparator &other) {
+ buf_ = other.buf_;
+ return *this;
+ }
};
/// @endcond
@@ -1783,12 +1940,12 @@ class FlatBufferBuilder {
}
template<typename T>
- Offset<Vector<const T*>> CreateUninitializedVectorOfStructs(size_t len, T **buf) {
+ Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
+ T **buf) {
return CreateUninitializedVector(len, sizeof(T),
reinterpret_cast<uint8_t **>(buf));
}
-
// @brief Create a vector of scalar type T given as input a vector of scalar
// type U, useful with e.g. pre "enum class" enums, or any existing scalar
// data of the wrong type.
@@ -1837,8 +1994,7 @@ class FlatBufferBuilder {
buf_.swap_allocator(other.buf_);
}
-protected:
-
+ protected:
// You shouldn't really be copying instances of this class.
FlatBufferBuilder(const FlatBufferBuilder &);
FlatBufferBuilder &operator=(const FlatBufferBuilder &);
@@ -1891,8 +2047,8 @@ protected:
bool operator()(const Offset<String> &a, const Offset<String> &b) const {
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
- return StringLessThan(stra->data(), stra->size(),
- strb->data(), strb->size());
+ return StringLessThan(stra->data(), stra->size(), strb->data(),
+ strb->size());
}
const vector_downward *buf_;
};
@@ -1956,13 +2112,15 @@ const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
/// This function is UNDEFINED for FlatBuffers whose schema does not include
/// a file_identifier (likely points at padding or the start of a the root
/// vtable).
-inline const char *GetBufferIdentifier(const void *buf, bool size_prefixed = false) {
+inline const char *GetBufferIdentifier(const void *buf,
+ bool size_prefixed = false) {
return reinterpret_cast<const char *>(buf) +
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
}
// Helper to see if the identifier in a buffer has the expected value.
-inline bool BufferHasIdentifier(const void *buf, const char *identifier, bool size_prefixed = false) {
+inline bool BufferHasIdentifier(const void *buf, const char *identifier,
+ bool size_prefixed = false) {
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
FlatBufferBuilder::kFileIdentifierLength) == 0;
}
@@ -1979,8 +2137,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
num_tables_(0),
max_tables_(_max_tables),
upper_bound_(0),
- check_alignment_(_check_alignment)
- {
+ check_alignment_(_check_alignment) {
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
}
@@ -2011,7 +2168,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
}
template<typename T> bool VerifyAlignment(size_t elem) const {
- return (elem & (sizeof(T) - 1)) == 0 || !check_alignment_;
+ return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_);
}
// Verify a range indicated by sizeof(T).
@@ -2019,13 +2176,18 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T));
}
+ bool VerifyFromPointer(const uint8_t *p, size_t len) {
+ auto o = static_cast<size_t>(p - buf_);
+ return Verify(o, len);
+ }
+
// Verify relative to a known-good base pointer.
bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
}
- template<typename T> bool Verify(const uint8_t *base, voffset_t elem_off)
- const {
+ template<typename T>
+ bool Verify(const uint8_t *base, voffset_t elem_off) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
}
@@ -2048,16 +2210,15 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
// Verify a pointer (may be NULL) to string.
bool VerifyString(const String *str) const {
size_t end;
- return !str ||
- (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
- 1, &end) &&
- Verify(end, 1) && // Must have terminator
- Check(buf_[end] == '\0')); // Terminating byte must be 0.
+ return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
+ 1, &end) &&
+ Verify(end, 1) && // Must have terminator
+ Check(buf_[end] == '\0')); // Terminating byte must be 0.
}
// Common code between vectors and strings.
bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size,
- size_t *end = nullptr) const {
+ size_t *end = nullptr) const {
auto veco = static_cast<size_t>(vec - buf_);
// Check we can read the size field.
if (!Verify<uoffset_t>(veco)) return false;
@@ -2092,11 +2253,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return true;
}
- bool VerifyTableStart(const uint8_t *table) {
+ __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
+ const uint8_t *table) {
// Check the vtable offset.
auto tableo = static_cast<size_t>(table - buf_);
if (!Verify<soffset_t>(tableo)) return false;
- // This offset may be signed, but doing the substraction unsigned always
+ // This offset may be signed, but doing the subtraction unsigned always
// gives the result we want.
auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
// Check the vtable size field, then check vtable fits in its entirety.
@@ -2107,9 +2269,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
template<typename T>
bool VerifyBufferFromStart(const char *identifier, size_t start) {
- if (identifier &&
- (size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
- !BufferHasIdentifier(buf_ + start, identifier))) {
+ if (identifier && (size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
+ !BufferHasIdentifier(buf_ + start, identifier))) {
return false;
}
@@ -2241,6 +2402,12 @@ class Struct FLATBUFFERS_FINAL_CLASS {
uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
private:
+ // private constructor & copy constructor: you obtain instances of this
+ // class by pointing to existing data only
+ Struct();
+ Struct(const Struct &);
+ Struct &operator=(const Struct &);
+
uint8_t data_[1];
};
@@ -2353,12 +2520,13 @@ class Table {
// class by pointing to existing data only
Table();
Table(const Table &other);
+ Table &operator=(const Table &);
uint8_t data_[1];
};
-template<typename T> void FlatBufferBuilder::Required(Offset<T> table,
- voffset_t field) {
+template<typename T>
+void FlatBufferBuilder::Required(Offset<T> table, voffset_t field) {
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
// If this fails, the caller will show what field needs to be set.
@@ -2405,7 +2573,9 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
}
/// @brief This return the prefixed size of a FlatBuffer.
-inline uoffset_t GetPrefixedSize(const uint8_t* buf){ return ReadScalar<uoffset_t>(buf); }
+inline uoffset_t GetPrefixedSize(const uint8_t *buf) {
+ return ReadScalar<uoffset_t>(buf);
+}
// Base class for native objects (FlatBuffer data de-serialized into native
// C++ data structures).
@@ -2473,7 +2643,7 @@ inline int LookupEnum(const char **names, const char *name) {
#define FLATBUFFERS_STRUCT_END(name, size) \
__pragma(pack()) \
static_assert(sizeof(name) == size, "compiler breaks packing rules")
-#elif defined(__GNUC__) || defined(__clang__)
+#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
#define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
_Pragma("pack(1)") \
struct __attribute__((aligned(alignment)))
@@ -2548,10 +2718,10 @@ typedef const TypeTable *(*TypeFunction)();
struct TypeTable {
SequenceType st;
size_t num_elems; // of type_codes, values, names (but not type_refs).
- const TypeCode *type_codes; // num_elems count
+ const TypeCode *type_codes; // num_elems count
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
const int64_t *values; // Only set for non-consecutive enum/union or structs.
- const char * const *names; // Only set if compiled with --reflect-names.
+ const char *const *names; // Only set if compiled with --reflect-names.
};
// String which identifies the current version of FlatBuffers.
diff --git a/include/flatbuffers/flatc.h b/include/flatbuffers/flatc.h
index f2765d23..5e2709e7 100644
--- a/include/flatbuffers/flatc.h
+++ b/include/flatbuffers/flatc.h
@@ -14,18 +14,22 @@
* limitations under the License.
*/
+#ifndef FLATBUFFERS_FLATC_H_
+#define FLATBUFFERS_FLATC_H_
+
#include <functional>
#include <limits>
#include <string>
+
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-#ifndef FLATC_H_
-# define FLATC_H_
-
namespace flatbuffers {
+extern void LogCompilerWarn(const std::string &warn);
+extern void LogCompilerError(const std::string &err);
+
class FlatCompiler {
public:
// Output generator for the various programming languages and formats we
@@ -93,4 +97,4 @@ class FlatCompiler {
} // namespace flatbuffers
-#endif // FLATC_H_
+#endif // FLATBUFFERS_FLATC_H_
diff --git a/include/flatbuffers/flexbuffers.h b/include/flatbuffers/flexbuffers.h
index 7cba5b75..dceaa3b4 100644
--- a/include/flatbuffers/flexbuffers.h
+++ b/include/flatbuffers/flexbuffers.h
@@ -65,7 +65,9 @@ enum Type {
FBT_VECTOR_UINT = 12,
FBT_VECTOR_FLOAT = 13,
FBT_VECTOR_KEY = 14,
- FBT_VECTOR_STRING = 15,
+ // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead.
+ // Read test.cpp/FlexBuffersDeprecatedTest() for details on why.
+ FBT_VECTOR_STRING_DEPRECATED = 15,
FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field).
FBT_VECTOR_UINT2 = 17,
FBT_VECTOR_FLOAT2 = 18,
@@ -88,7 +90,7 @@ inline bool IsTypedVectorElementType(Type t) {
}
inline bool IsTypedVector(Type t) {
- return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING) ||
+ return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING_DEPRECATED) ||
t == FBT_VECTOR_BOOL;
}
@@ -212,26 +214,40 @@ class Object {
uint8_t byte_width_;
};
-// Stores size in `byte_width_` bytes before data_ pointer.
+// Object that has a size, obtained either from size prefix, or elsewhere.
class Sized : public Object {
public:
- Sized(const uint8_t *data, uint8_t byte_width) : Object(data, byte_width) {}
- size_t size() const {
+ // Size prefix.
+ Sized(const uint8_t *data, uint8_t byte_width)
+ : Object(data, byte_width), size_(read_size()) {}
+ // Manual size.
+ Sized(const uint8_t *data, uint8_t byte_width, size_t sz)
+ : Object(data, byte_width), size_(sz) {}
+ size_t size() const { return size_; }
+ // Access size stored in `byte_width_` bytes before data_ pointer.
+ size_t read_size() const {
return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
}
+
+ protected:
+ size_t size_;
};
class String : public Sized {
public:
+ // Size prefix.
String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
+ // Manual size.
+ String(const uint8_t *data, uint8_t byte_width, size_t sz)
+ : Sized(data, byte_width, sz) {}
size_t length() const { return size(); }
const char *c_str() const { return reinterpret_cast<const char *>(data_); }
- std::string str() const { return std::string(c_str(), length()); }
+ std::string str() const { return std::string(c_str(), size()); }
static String EmptyString() {
- static const uint8_t empty_string[] = { 0 /*len*/, 0 /*terminator*/ };
- return String(empty_string + 1, 1);
+ static const char *empty_string = "";
+ return String(reinterpret_cast<const uint8_t *>(empty_string), 1, 0);
}
bool IsTheEmptyString() const { return data_ == EmptyString().data_; }
};
@@ -279,6 +295,8 @@ class TypedVector : public Sized {
Type ElementType() { return type_; }
+ friend Reference;
+
private:
Type type_;
@@ -339,16 +357,22 @@ class Map : public Vector {
template<typename T>
void AppendToString(std::string &s, T &&v, bool keys_quoted) {
- s += "[ ";
- for (size_t i = 0; i < v.size(); i++) {
- if (i) s += ", ";
- v[i].ToString(true, keys_quoted, s);
- }
- s += " ]";
+ s += "[ ";
+ for (size_t i = 0; i < v.size(); i++) {
+ if (i) s += ", ";
+ v[i].ToString(true, keys_quoted, s);
+ }
+ s += " ]";
}
class Reference {
public:
+ Reference()
+ : data_(nullptr),
+ parent_width_(0),
+ byte_width_(BIT_WIDTH_8),
+ type_(FBT_NULL) {}
+
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
Type type)
: data_(data),
@@ -378,15 +402,19 @@ class Reference {
bool IsString() const { return type_ == FBT_STRING; }
bool IsKey() const { return type_ == FBT_KEY; }
bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
+ bool IsUntypedVector() const { return type_ == FBT_VECTOR; }
bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
- bool IsFixedTypedVector() const { return flexbuffers::IsFixedTypedVector(type_); }
- bool IsAnyVector() const { return (IsTypedVector() || IsFixedTypedVector() || IsVector());}
+ bool IsFixedTypedVector() const {
+ return flexbuffers::IsFixedTypedVector(type_);
+ }
+ bool IsAnyVector() const {
+ return (IsTypedVector() || IsFixedTypedVector() || IsVector());
+ }
bool IsMap() const { return type_ == FBT_MAP; }
bool IsBlob() const { return type_ == FBT_BLOB; }
-
bool AsBool() const {
return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_)
- : AsUInt64()) != 0;
+ : AsUInt64()) != 0;
}
// Reads any type as a int64_t. Never fails, does most sensible conversion.
@@ -464,7 +492,11 @@ class Reference {
case FBT_INDIRECT_UINT:
return static_cast<double>(ReadUInt64(Indirect(), byte_width_));
case FBT_NULL: return 0.0;
- case FBT_STRING: return strtod(AsString().c_str(), nullptr);
+ case FBT_STRING: {
+ double d;
+ flatbuffers::StringToNumber(AsString().c_str(), &d);
+ return d;
+ }
case FBT_VECTOR: return static_cast<double>(AsVector().size());
case FBT_BOOL:
return static_cast<double>(ReadUInt64(data_, parent_width_));
@@ -477,17 +509,22 @@ class Reference {
float AsFloat() const { return static_cast<float>(AsDouble()); }
const char *AsKey() const {
- if (type_ == FBT_KEY) {
+ if (type_ == FBT_KEY || type_ == FBT_STRING) {
return reinterpret_cast<const char *>(Indirect());
} else {
return "";
}
}
- // This function returns the empty string if you try to read a not-string.
+ // This function returns the empty string if you try to read something that
+ // is not a string or key.
String AsString() const {
if (type_ == FBT_STRING) {
return String(Indirect(), byte_width_);
+ } else if (type_ == FBT_KEY) {
+ auto key = Indirect();
+ return String(key, byte_width_,
+ strlen(reinterpret_cast<const char *>(key)));
} else {
return String::EmptyString();
}
@@ -549,7 +586,8 @@ class Reference {
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
} else if (IsBlob()) {
auto blob = AsBlob();
- flatbuffers::EscapeString(reinterpret_cast<const char*>(blob.data()), blob.size(), &s, true, false);
+ flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
+ blob.size(), &s, true, false);
} else {
s += "(?)";
}
@@ -577,8 +615,18 @@ class Reference {
TypedVector AsTypedVector() const {
if (IsTypedVector()) {
- return TypedVector(Indirect(), byte_width_,
- ToTypedVectorElementType(type_));
+ auto tv =
+ TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_));
+ if (tv.type_ == FBT_STRING) {
+ // These can't be accessed as strings, since we don't know the bit-width
+ // of the size field, see the declaration of
+ // FBT_VECTOR_STRING_DEPRECATED above for details.
+ // We change the type here to be keys, which are a subtype of strings,
+ // and will ignore the size field. This will truncate strings with
+ // embedded nulls.
+ tv.type_ = FBT_KEY;
+ }
+ return tv;
} else {
return TypedVector::EmptyTypedVector();
}
@@ -723,9 +771,15 @@ template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); }
template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
-template<> inline uint16_t Reference::As<uint16_t>() const { return AsUInt16(); }
-template<> inline uint32_t Reference::As<uint32_t>() const { return AsUInt32(); }
-template<> inline uint64_t Reference::As<uint64_t>() const { return AsUInt64(); }
+template<> inline uint16_t Reference::As<uint16_t>() const {
+ return AsUInt16();
+}
+template<> inline uint32_t Reference::As<uint32_t>() const {
+ return AsUInt32();
+}
+template<> inline uint64_t Reference::As<uint64_t>() const {
+ return AsUInt64();
+}
template<> inline double Reference::As<double>() const { return AsDouble(); }
template<> inline float Reference::As<float>() const { return AsFloat(); }
@@ -1046,7 +1100,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
for (auto key = start; key < stack_.size(); key += 2) {
FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY);
}
- // Now sort values, so later we can do a binary seach lookup.
+ // Now sort values, so later we can do a binary search lookup.
// We want to sort 2 array elements at a time.
struct TwoValue {
Value key;
@@ -1194,6 +1248,24 @@ class Builder FLATBUFFERS_FINAL_CLASS {
EndMap(start);
}
+ // If you wish to share a value explicitly (a value not shared automatically
+ // through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these
+ // functions. Or if you wish to turn those flags off for performance reasons
+ // and still do some explicit sharing. For example:
+ // builder.IndirectDouble(M_PI);
+ // auto id = builder.LastValue(); // Remember where we stored it.
+ // .. more code goes here ..
+ // builder.ReuseValue(id); // Refers to same double by offset.
+ // LastValue works regardless of wether the value has a key or not.
+ // Works on any data type.
+ struct Value;
+ Value LastValue() { return stack_.back(); }
+ void ReuseValue(Value v) { stack_.push_back(v); }
+ void ReuseValue(const char *key, Value v) {
+ Key(key);
+ ReuseValue(v);
+ }
+
// Overloaded Add that tries to call the correct function above.
void Add(int8_t i) { Int(i); }
void Add(int16_t i) { Int(i); }
@@ -1319,6 +1391,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
: FBT_INT);
}
+ public:
+ // This was really intended to be private, except for LastValue/ReuseValue.
struct Value {
union {
int64_t i_;
@@ -1388,6 +1462,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
}
};
+ private:
void WriteAny(const Value &val, uint8_t byte_width) {
switch (val.type_) {
case FBT_NULL:
@@ -1420,6 +1495,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// TODO: instead of asserting, could write vector with larger elements
// instead, though that would be wasteful.
FLATBUFFERS_ASSERT(WidthU(len) <= bit_width);
+ Align(bit_width);
if (!fixed) Write<uint64_t>(len, byte_width);
auto vloc = buf_.size();
for (size_t i = 0; i < len; i++) Write(elems[i], byte_width);
@@ -1431,7 +1507,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
bool fixed, const Value *keys = nullptr) {
- FLATBUFFERS_ASSERT(!fixed || typed); // typed=false, fixed=true combination is not supported.
+ FLATBUFFERS_ASSERT(
+ !fixed ||
+ typed); // typed=false, fixed=true combination is not supported.
// Figure out smallest bit width we can store this vector with.
auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
auto prefix_elems = 1;
@@ -1511,7 +1589,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
typedef std::pair<size_t, size_t> StringOffset;
struct StringOffsetCompare {
- explicit StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
+ explicit StringOffsetCompare(const std::vector<uint8_t> &buf)
+ : buf_(&buf) {}
bool operator()(const StringOffset &a, const StringOffset &b) const {
auto stra = reinterpret_cast<const char *>(
flatbuffers::vector_data(*buf_) + a.first);
@@ -1531,8 +1610,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
} // namespace flexbuffers
-# if defined(_MSC_VER)
-# pragma warning(pop)
-# endif
+#if defined(_MSC_VER)
+# pragma warning(pop)
+#endif
#endif // FLATBUFFERS_FLEXBUFFERS_H_
diff --git a/include/flatbuffers/grpc.h b/include/flatbuffers/grpc.h
index a75b67c7..bd24c501 100644
--- a/include/flatbuffers/grpc.h
+++ b/include/flatbuffers/grpc.h
@@ -88,8 +88,7 @@ class SliceAllocator : public Allocator {
SliceAllocator(const SliceAllocator &other) = delete;
SliceAllocator &operator=(const SliceAllocator &other) = delete;
- SliceAllocator(SliceAllocator &&other)
- : slice_(grpc_empty_slice()) {
+ SliceAllocator(SliceAllocator &&other) : slice_(grpc_empty_slice()) {
// default-construct and swap idiom
swap(other);
}
@@ -164,34 +163,36 @@ class MessageBuilder : private detail::SliceAllocatorMember,
public FlatBufferBuilder {
public:
explicit MessageBuilder(uoffset_t initial_size = 1024)
- : FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
+ : FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
MessageBuilder(const MessageBuilder &other) = delete;
MessageBuilder &operator=(const MessageBuilder &other) = delete;
MessageBuilder(MessageBuilder &&other)
- : FlatBufferBuilder(1024, &slice_allocator_, false) {
+ : FlatBufferBuilder(1024, &slice_allocator_, false) {
// Default construct and swap idiom.
Swap(other);
}
/// Create a MessageBuilder from a FlatBufferBuilder.
- explicit MessageBuilder(FlatBufferBuilder &&src, void (*dealloc)(void*, size_t) = &DefaultAllocator::dealloc)
- : FlatBufferBuilder(1024, &slice_allocator_, false) {
+ explicit MessageBuilder(FlatBufferBuilder &&src,
+ void (*dealloc)(void *,
+ size_t) = &DefaultAllocator::dealloc)
+ : FlatBufferBuilder(1024, &slice_allocator_, false) {
src.Swap(*this);
src.SwapBufAllocator(*this);
if (buf_.capacity()) {
- uint8_t *buf = buf_.scratch_data(); // pointer to memory
- size_t capacity = buf_.capacity(); // size of memory
+ uint8_t *buf = buf_.scratch_data(); // pointer to memory
+ size_t capacity = buf_.capacity(); // size of memory
slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
- }
- else {
+ } else {
slice_allocator_.slice_ = grpc_empty_slice();
}
}
/// Move-assign a FlatBufferBuilder to a MessageBuilder.
- /// Only FlatBufferBuilder with default allocator (basically, nullptr) is supported.
+ /// Only FlatBufferBuilder with default allocator (basically, nullptr) is
+ /// supported.
MessageBuilder &operator=(FlatBufferBuilder &&src) {
// Move construct a temporary and swap
MessageBuilder temp(std::move(src));
@@ -209,10 +210,11 @@ class MessageBuilder : private detail::SliceAllocatorMember,
void Swap(MessageBuilder &other) {
slice_allocator_.swap(other.slice_allocator_);
FlatBufferBuilder::Swap(other);
- // After swapping the FlatBufferBuilder, we swap back the allocator, which restores
- // the original allocator back in place. This is necessary because MessageBuilder's
- // allocator is its own member (SliceAllocatorMember). The allocator passed to
- // FlatBufferBuilder::vector_downward must point to this member.
+ // After swapping the FlatBufferBuilder, we swap back the allocator, which
+ // restores the original allocator back in place. This is necessary because
+ // MessageBuilder's allocator is its own member (SliceAllocatorMember). The
+ // allocator passed to FlatBufferBuilder::vector_downward must point to this
+ // member.
buf_.swap_allocator(other.buf_);
}
@@ -232,10 +234,10 @@ class MessageBuilder : private detail::SliceAllocatorMember,
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
// ownership.
template<class T> Message<T> GetMessage() {
- auto buf_data = buf_.scratch_data(); // pointer to memory
- auto buf_size = buf_.capacity(); // size of memory
- auto msg_data = buf_.data(); // pointer to msg
- auto msg_size = buf_.size(); // size of msg
+ auto buf_data = buf_.scratch_data(); // pointer to memory
+ auto buf_size = buf_.capacity(); // size of memory
+ auto msg_data = buf_.data(); // pointer to msg
+ auto msg_size = buf_.size(); // size of msg
// Do some sanity checks on data/size
FLATBUFFERS_ASSERT(msg_data);
FLATBUFFERS_ASSERT(msg_size);
@@ -274,7 +276,7 @@ template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
grpc_byte_buffer **buffer, bool *own_buffer) {
// We are passed in a `Message<T>`, which is a wrapper around a
// `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast
- // is necesary because the `grpc_raw_byte_buffer_create` func expects
+ // is necessary because the `grpc_raw_byte_buffer_create` func expects
// non-const slices in order to increment their refcounts.
grpc_slice *slice = const_cast<grpc_slice *>(&msg.BorrowSlice());
// Now use `grpc_raw_byte_buffer_create` to package the single slice into a
@@ -306,7 +308,7 @@ template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
grpc_byte_buffer_reader_init(&reader, buffer);
grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
grpc_byte_buffer_reader_destroy(&reader);
- // We wrap a `Message<T>` around the slice, but dont increment refcount
+ // We wrap a `Message<T>` around the slice, but don't increment refcount
*msg = flatbuffers::grpc::Message<T>(slice, false);
}
grpc_byte_buffer_destroy(buffer);
diff --git a/include/flatbuffers/hash.h b/include/flatbuffers/hash.h
index 16536cb4..aebf0713 100644
--- a/include/flatbuffers/hash.h
+++ b/include/flatbuffers/hash.h
@@ -57,17 +57,17 @@ template<typename T> T HashFnv1a(const char *input) {
return hash;
}
-template <> inline uint16_t HashFnv1<uint16_t>(const char *input) {
+template<> inline uint16_t HashFnv1<uint16_t>(const char *input) {
uint32_t hash = HashFnv1<uint32_t>(input);
return (hash >> 16) ^ (hash & 0xffff);
}
-template <> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
+template<> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
uint32_t hash = HashFnv1a<uint32_t>(input);
return (hash >> 16) ^ (hash & 0xffff);
}
-template <typename T> struct NamedHashFunction {
+template<typename T> struct NamedHashFunction {
const char *name;
typedef T (*HashFunction)(const char *);
@@ -75,7 +75,7 @@ template <typename T> struct NamedHashFunction {
};
const NamedHashFunction<uint16_t> kHashFunctions16[] = {
- { "fnv1_16", HashFnv1<uint16_t> },
+ { "fnv1_16", HashFnv1<uint16_t> },
{ "fnv1a_16", HashFnv1a<uint16_t> },
};
diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h
index 8299fe0c..12b2b142 100644
--- a/include/flatbuffers/idl.h
+++ b/include/flatbuffers/idl.h
@@ -47,25 +47,26 @@ namespace flatbuffers {
// of type tokens.
// clang-format off
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
- TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8) \
- TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8) /* begin scalar/int */ \
- TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool) \
- TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8) \
- TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8) \
- TD(SHORT, "short", int16_t, short, int16, short, int16, i16) \
- TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16) \
- TD(INT, "int", int32_t, int, int32, int, int32, i32) \
- TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32) \
- TD(LONG, "long", int64_t, long, int64, long, int64, i64) \
- TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64) /* end int */ \
- TD(FLOAT, "float", float, float, float32, float, float32, f32) /* begin float */ \
- TD(DOUBLE, "double", double, double, float64, double, float64, f64) /* end float/scalar */
+ TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \
+ TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) /* begin scalar/int */ \
+ TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean, Bool) \
+ TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte, Int8) \
+ TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \
+ TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short, Int16) \
+ TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort, UInt16) \
+ TD(INT, "int", int32_t, int, int32, int, int32, i32, Int, Int32) \
+ TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt, UInt32) \
+ TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long, Int64) \
+ TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong, UInt64) /* end int */ \
+ TD(FLOAT, "float", float, float, float32, float, float32, f32, Float, Float32) /* begin float */ \
+ TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double, Double) /* end float/scalar */
#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
- TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused) \
- TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused) \
- TD(STRUCT, "", Offset<void>, int, int, int, int, unused) \
- TD(UNION, "", Offset<void>, int, int, int, int, unused)
-
+ TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int, Offset<String>) \
+ TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>) \
+ TD(STRUCT, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>) \
+ TD(UNION, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>)
+#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \
+ TD(ARRAY, "", int, int, int, int, int, unused, Int, Offset<UOffset>)
// The fields are:
// - enum
// - FlatBuffers schema type.
@@ -75,13 +76,28 @@ namespace flatbuffers {
// - C# / .Net type.
// - Python type.
// - Rust type.
+// - Kotlin type.
// using these macros, we can now write code dealing with types just once, e.g.
/*
switch (type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
- RTYPE) \
+ RTYPE, KTYPE) \
+ case BASE_TYPE_ ## ENUM: \
+ // do something specific to CTYPE here
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+}
+*/
+
+// If not all FLATBUFFERS_GEN_() arguments are necessary for implementation
+// of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed).
+// In the above example, only CTYPE is used to generate the code, it can be rewritten:
+
+/*
+switch (type) {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
case BASE_TYPE_ ## ENUM: \
// do something specific to CTYPE here
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
@@ -91,24 +107,23 @@ switch (type) {
#define FLATBUFFERS_GEN_TYPES(TD) \
FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
- FLATBUFFERS_GEN_TYPES_POINTER(TD)
+ FLATBUFFERS_GEN_TYPES_POINTER(TD) \
+ FLATBUFFERS_GEN_TYPE_ARRAY(TD)
// Create an enum for all the types above.
#ifdef __GNUC__
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
#endif
enum BaseType {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
- RTYPE) \
- BASE_TYPE_ ## ENUM,
+ #define FLATBUFFERS_TD(ENUM, ...) \
+ BASE_TYPE_ ## ENUM,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
};
-#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
- RTYPE) \
- static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
- "define largest_scalar_t as " #CTYPE);
+#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
+ "define largest_scalar_t as " #CTYPE);
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
@@ -123,6 +138,13 @@ inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; }
inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE &&
t <= BASE_TYPE_UCHAR; }
+
+inline bool IsUnsigned(BaseType t) {
+ return (t == BASE_TYPE_UTYPE) || (t == BASE_TYPE_UCHAR) ||
+ (t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT) ||
+ (t == BASE_TYPE_ULONG);
+}
+
// clang-format on
extern const char *const kTypeNames[];
@@ -138,18 +160,21 @@ class Parser;
// and additional information for vectors/structs_.
struct Type {
explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
- EnumDef *_ed = nullptr)
+ EnumDef *_ed = nullptr, uint16_t _fixed_length = 0)
: base_type(_base_type),
element(BASE_TYPE_NONE),
struct_def(_sd),
- enum_def(_ed) {}
+ enum_def(_ed),
+ fixed_length(_fixed_length) {}
bool operator==(const Type &o) {
return base_type == o.base_type && element == o.element &&
struct_def == o.struct_def && enum_def == o.enum_def;
}
- Type VectorType() const { return Type(element, struct_def, enum_def); }
+ Type VectorType() const {
+ return Type(element, struct_def, enum_def, fixed_length);
+ }
Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;
@@ -160,6 +185,7 @@ struct Type {
StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT
EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
// or for an integral type derived from an enum.
+ uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY
};
// Represents a parsed scalar value, it's type, and field offset.
@@ -224,6 +250,15 @@ struct Namespace {
size_t from_table; // Part of the namespace corresponds to a message/table.
};
+inline bool operator<(const Namespace &a, const Namespace &b) {
+ size_t min_size = std::min(a.components.size(), b.components.size());
+ for (size_t i = 0; i < min_size; ++i) {
+ if (a.components[i] != b.components[i])
+ return a.components[i] < b.components[i];
+ }
+ return a.components.size() < b.components.size();
+}
+
// Base class for all definition types (fields, structs_, enums_).
struct Definition {
Definition()
@@ -315,64 +350,138 @@ struct StructDef : public Definition {
flatbuffers::unique_ptr<std::string> original_location;
};
-inline bool IsStruct(const Type &type) {
- return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
-}
-
-inline size_t InlineSize(const Type &type) {
- return IsStruct(type) ? type.struct_def->bytesize : SizeOf(type.base_type);
-}
-
-inline size_t InlineAlignment(const Type &type) {
- return IsStruct(type) ? type.struct_def->minalign : SizeOf(type.base_type);
-}
+struct EnumDef;
+struct EnumValBuilder;
struct EnumVal {
- EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
- EnumVal() : value(0) {}
-
- Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
+ Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
+ const Parser &parser) const;
bool Deserialize(const Parser &parser, const reflection::EnumVal *val);
+
+ uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); }
+ int64_t GetAsInt64() const { return value; }
bool IsZero() const { return 0 == value; }
bool IsNonZero() const { return !IsZero(); }
std::string name;
std::vector<std::string> doc_comment;
- int64_t value;
Type union_type;
+
+ private:
+ friend EnumDef;
+ friend EnumValBuilder;
+ friend bool operator==(const EnumVal &lhs, const EnumVal &rhs);
+
+ EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
+ EnumVal() : value(0) {}
+
+ int64_t value;
};
struct EnumDef : public Definition {
EnumDef() : is_union(false), uses_multiple_type_instances(false) {}
- EnumVal *ReverseLookup(int64_t enum_idx, bool skip_union_default = true) {
- for (auto it = Vals().begin() +
- static_cast<int>(is_union && skip_union_default);
- it != Vals().end(); ++it) {
- if ((*it)->value == enum_idx) { return *it; }
- }
- return nullptr;
- }
-
- Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
+ Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
+ const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::Enum *values);
+ template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val);
+ void SortByValue();
+ void RemoveDuplicates();
+
+ std::string AllFlags() const;
+ const EnumVal *MinValue() const;
+ const EnumVal *MaxValue() const;
+ // Returns the number of integer steps from v1 to v2.
+ uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const;
+ // Returns the number of integer steps from Min to Max.
+ uint64_t Distance() const { return Distance(MinValue(), MaxValue()); }
+
+ EnumVal *ReverseLookup(int64_t enum_idx,
+ bool skip_union_default = false) const;
+ EnumVal *FindByValue(const std::string &constant) const;
+
+ std::string ToString(const EnumVal &ev) const {
+ return IsUInt64() ? NumToString(ev.GetAsUInt64())
+ : NumToString(ev.GetAsInt64());
+ }
+
size_t size() const { return vals.vec.size(); }
const std::vector<EnumVal *> &Vals() const {
return vals.vec;
}
- SymbolTable<EnumVal> vals;
+ const EnumVal *Lookup(const std::string &enum_name) const {
+ return vals.Lookup(enum_name);
+ }
+
bool is_union;
// Type is a union which uses type aliases where at least one type is
// available under two different names.
bool uses_multiple_type_instances;
Type underlying_type;
+
+ private:
+ bool IsUInt64() const {
+ return (BASE_TYPE_ULONG == underlying_type.base_type);
+ }
+
+ friend EnumValBuilder;
+ SymbolTable<EnumVal> vals;
};
+inline bool IsStruct(const Type &type) {
+ return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
+}
+
+inline bool IsUnion(const Type &type) {
+ return type.enum_def != nullptr && type.enum_def->is_union;
+}
+
+inline bool IsVector(const Type &type) {
+ return type.base_type == BASE_TYPE_VECTOR;
+}
+
+inline bool IsArray(const Type &type) {
+ return type.base_type == BASE_TYPE_ARRAY;
+}
+
+inline bool IsSeries(const Type &type) {
+ return IsVector(type) || IsArray(type);
+}
+
+inline bool IsEnum(const Type &type) {
+ return type.enum_def != nullptr && IsInteger(type.base_type);
+}
+
+inline size_t InlineSize(const Type &type) {
+ return IsStruct(type)
+ ? type.struct_def->bytesize
+ : (IsArray(type)
+ ? InlineSize(type.VectorType()) * type.fixed_length
+ : SizeOf(type.base_type));
+}
+
+inline size_t InlineAlignment(const Type &type) {
+ if (IsStruct(type)) {
+ return type.struct_def->minalign;
+ } else if (IsArray(type)) {
+ return IsStruct(type.VectorType()) ? type.struct_def->minalign
+ : SizeOf(type.element);
+ } else {
+ return SizeOf(type.base_type);
+ }
+}
+inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) {
+ return lhs.value == rhs.value;
+}
+inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) {
+ return !(lhs == rhs);
+}
+
inline bool EqualByName(const Type &a, const Type &b) {
return a.base_type == b.base_type && a.element == b.element &&
(a.struct_def == b.struct_def ||
@@ -381,7 +490,8 @@ inline bool EqualByName(const Type &a, const Type &b) {
}
struct RPCCall : public Definition {
- Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
+ Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
+ const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::RPCCall *call);
@@ -389,7 +499,8 @@ struct RPCCall : public Definition {
};
struct ServiceDef : public Definition {
- Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
+ Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
+ const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::Service *service);
SymbolTable<RPCCall> calls;
@@ -397,6 +508,8 @@ struct ServiceDef : public Definition {
// Container of options that may apply to any of the source/text generators.
struct IDLOptions {
+ // Use flexbuffers instead for binary and text generation
+ bool use_flexbuffers;
bool strict_json;
bool skip_js_exports;
bool use_goog_js_export_format;
@@ -420,6 +533,7 @@ struct IDLOptions {
std::string cpp_object_api_string_type;
bool cpp_object_api_string_flexible_constructor;
bool gen_nullable;
+ bool java_checkerframework;
bool gen_generated;
std::string object_prefix;
std::string object_suffix;
@@ -430,6 +544,7 @@ struct IDLOptions {
bool keep_include_path;
bool binary_schema_comments;
bool binary_schema_builtins;
+ bool binary_schema_gen_embed;
bool skip_flatbuffers_import;
std::string go_import;
std::string go_namespace;
@@ -439,6 +554,13 @@ struct IDLOptions {
bool size_prefixed;
std::string root_type;
bool force_defaults;
+ bool java_primitive_has_method;
+ bool cs_gen_json_serializer;
+ std::vector<std::string> cpp_includes;
+ std::string cpp_std;
+ std::string proto_namespace_suffix;
+ std::string filename_suffix;
+ std::string filename_extension;
// Possible options for the more general generator below.
enum Language {
@@ -457,6 +579,8 @@ struct IDLOptions {
kLua = 1 << 12,
kLobster = 1 << 13,
kRust = 1 << 14,
+ kKotlin = 1 << 15,
+ kSwift = 1 << 16,
kMAX
};
@@ -470,12 +594,17 @@ struct IDLOptions {
// for code generation.
unsigned long lang_to_generate;
- // If set (default behavior), empty string and vector fields will be set to
- // nullptr to make the flatbuffer more compact.
- bool set_empty_to_null;
+ // If set (default behavior), empty string fields will be set to nullptr to
+ // make the flatbuffer more compact.
+ bool set_empty_strings_to_null;
+
+ // If set (default behavior), empty vector fields will be set to nullptr to
+ // make the flatbuffer more compact.
+ bool set_empty_vectors_to_null;
IDLOptions()
- : strict_json(false),
+ : use_flexbuffers(false),
+ strict_json(false),
skip_js_exports(false),
use_goog_js_export_format(false),
use_ES6_js_export_format(false),
@@ -497,6 +626,7 @@ struct IDLOptions {
cpp_object_api_pointer_type("std::unique_ptr"),
cpp_object_api_string_flexible_constructor(false),
gen_nullable(false),
+ java_checkerframework(false),
gen_generated(false),
object_suffix("T"),
union_value_namespacing(true),
@@ -505,16 +635,22 @@ struct IDLOptions {
keep_include_path(false),
binary_schema_comments(false),
binary_schema_builtins(false),
+ binary_schema_gen_embed(false),
skip_flatbuffers_import(false),
reexport_ts_modules(true),
js_ts_short_names(false),
protobuf_ascii_alike(false),
size_prefixed(false),
force_defaults(false),
+ java_primitive_has_method(false),
+ cs_gen_json_serializer(false),
+ filename_suffix("_generated"),
+ filename_extension(),
lang(IDLOptions::kJava),
mini_reflect(IDLOptions::kNone),
lang_to_generate(0),
- set_empty_to_null(true) {}
+ set_empty_strings_to_null(true),
+ set_empty_vectors_to_null(true) {}
};
// This encapsulates where the parser is in the current source file.
@@ -607,15 +743,14 @@ class Parser : public ParserState {
explicit Parser(const IDLOptions &options = IDLOptions())
: current_namespace_(nullptr),
empty_namespace_(nullptr),
+ flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL),
root_struct_def_(nullptr),
opts(options),
uses_flexbuffers_(false),
source_(nullptr),
anonymous_counter(0),
recurse_protection_counter(0) {
- if (opts.force_defaults) {
- builder_.ForceDefaults(true);
- }
+ if (opts.force_defaults) { builder_.ForceDefaults(true); }
// Start out with the empty namespace being current.
empty_namespace_ = new Namespace();
namespaces_.push_back(empty_namespace_);
@@ -686,9 +821,9 @@ class Parser : public ParserState {
// Fills internal structure as if the schema passed had been loaded by parsing
// with Parse except that included filenames will not be populated.
- bool Deserialize(const reflection::Schema* schema);
+ bool Deserialize(const reflection::Schema *schema);
- Type* DeserializeType(const reflection::Type* type);
+ Type *DeserializeType(const reflection::Type *type);
// Checks that the schema represented by this parser is a safe evolution
// of the schema provided. Returns non-empty error on any problems.
@@ -701,7 +836,7 @@ class Parser : public ParserState {
StructDef *LookupStruct(const std::string &id) const;
- std::string UnqualifiedName(std::string fullQualifiedName);
+ std::string UnqualifiedName(const std::string &fullQualifiedName);
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
@@ -738,20 +873,26 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
std::string *value, uoffset_t *ovalue);
void SerializeStruct(const StructDef &struct_def, const Value &val);
+ void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def,
+ const Value &val);
template<typename F>
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body);
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
FieldDef *field, size_t fieldn);
- FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field,
- size_t fieldn,
- const StructDef *parent_struct_def);
+ FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
+ FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
+ Value &val, FieldDef *field, size_t fieldn,
+ const StructDef *parent_struct_def);
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
- FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, bool check, Value &e,
- BaseType req, bool *destmatch);
- FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
+ FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
+ bool check, Value &e, BaseType req,
+ bool *destmatch);
+ FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field);
FLATBUFFERS_CHECKED_ERROR TokenError();
- FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, bool check_now);
- FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, std::string *result);
+ FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
+ bool check_now);
+ FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
+ std::string *result);
StructDef *LookupCreateStruct(const std::string &name,
bool create_if_new = true,
bool definition = false);
@@ -759,8 +900,7 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR ParseNamespace();
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
StructDef **dest);
- FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name,
- bool is_union,
+ FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
EnumDef **dest);
FLATBUFFERS_CHECKED_ERROR ParseDecl();
FLATBUFFERS_CHECKED_ERROR ParseService();
@@ -776,18 +916,18 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
const char *source_filename);
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
- const char **include_paths,
- const char *source_filename);
+ const char **include_paths,
+ const char *source_filename);
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
- const char **include_paths,
- const char *source_filename,
- const char *include_filename);
- FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
+ const char **include_paths,
+ const char *source_filename,
+ const char *include_filename);
+ FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
StructDef *struct_def,
- const char *suffix,
- BaseType baseType);
+ const char *suffix, BaseType baseType);
bool SupportsAdvancedUnionFeatures() const;
+ bool SupportsAdvancedArrayFeatures() const;
Namespace *UniqueNamespace(Namespace *ns);
FLATBUFFERS_CHECKED_ERROR RecurseError();
@@ -801,9 +941,11 @@ class Parser : public ParserState {
std::vector<Namespace *> namespaces_;
Namespace *current_namespace_;
Namespace *empty_namespace_;
- std::string error_; // User readable error_ if Parse() == false
+ std::string error_; // User readable error_ if Parse() == false
FlatBufferBuilder builder_; // any data contained in the file
+ flexbuffers::Builder flex_builder_;
+ flexbuffers::Reference flex_root_;
StructDef *root_struct_def_;
std::string file_identifier_;
std::string file_extension_;
@@ -832,6 +974,8 @@ class Parser : public ParserState {
extern std::string MakeCamel(const std::string &in, bool first = true);
+extern std::string MakeScreamingCamel(const std::string &in);
+
// Generate text (JSON) from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// If ident_step is 0, no indentation will be generated. Additionally,
@@ -840,156 +984,154 @@ extern std::string MakeCamel(const std::string &in, bool first = true);
// strict_json adds "quotes" around field names if true.
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
// byte arrays in String values), returns false.
-extern bool GenerateTextFromTable(const Parser &parser,
- const void *table,
+extern bool GenerateTextFromTable(const Parser &parser, const void *table,
const std::string &tablename,
std::string *text);
-extern bool GenerateText(const Parser &parser,
- const void *flatbuffer,
+extern bool GenerateText(const Parser &parser, const void *flatbuffer,
std::string *text);
-extern bool GenerateTextFile(const Parser &parser,
- const std::string &path,
+extern bool GenerateTextFile(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate binary files from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
-// See idl_gen_general.cpp.
-extern bool GenerateBinary(const Parser &parser,
- const std::string &path,
+// See code_generators.cpp.
+extern bool GenerateBinary(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a C++ header from the definitions in the Parser object.
// See idl_gen_cpp.
-extern bool GenerateCPP(const Parser &parser,
- const std::string &path,
+extern bool GenerateCPP(const Parser &parser, const std::string &path,
const std::string &file_name);
-extern bool GenerateDart(const Parser &parser,
- const std::string &path,
+// Generate C# files from the definitions in the Parser object.
+// See idl_gen_csharp.cpp.
+extern bool GenerateCSharp(const Parser &parser, const std::string &path,
+ const std::string &file_name);
+
+extern bool GenerateDart(const Parser &parser, const std::string &path,
const std::string &file_name);
-// Generate JavaScript or TypeScript code from the definitions in the Parser object.
-// See idl_gen_js.
-extern bool GenerateJSTS(const Parser &parser,
- const std::string &path,
- const std::string &file_name);
+// Generate Java files from the definitions in the Parser object.
+// See idl_gen_java.cpp.
+extern bool GenerateJava(const Parser &parser, const std::string &path,
+ const std::string &file_name);
+
+// Generate JavaScript or TypeScript code from the definitions in the Parser
+// object. See idl_gen_js.
+extern bool GenerateJSTS(const Parser &parser, const std::string &path,
+ const std::string &file_name);
// Generate Go files from the definitions in the Parser object.
// See idl_gen_go.cpp.
-extern bool GenerateGo(const Parser &parser,
- const std::string &path,
+extern bool GenerateGo(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Php code from the definitions in the Parser object.
// See idl_gen_php.
-extern bool GeneratePhp(const Parser &parser,
- const std::string &path,
+extern bool GeneratePhp(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Python files from the definitions in the Parser object.
// See idl_gen_python.cpp.
-extern bool GeneratePython(const Parser &parser,
- const std::string &path,
+extern bool GeneratePython(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Lobster files from the definitions in the Parser object.
// See idl_gen_lobster.cpp.
-extern bool GenerateLobster(const Parser &parser,
- const std::string &path,
+extern bool GenerateLobster(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Lua files from the definitions in the Parser object.
// See idl_gen_lua.cpp.
-extern bool GenerateLua(const Parser &parser,
- const std::string &path,
- const std::string &file_name);
+extern bool GenerateLua(const Parser &parser, const std::string &path,
+ const std::string &file_name);
// Generate Rust files from the definitions in the Parser object.
// See idl_gen_rust.cpp.
-extern bool GenerateRust(const Parser &parser,
- const std::string &path,
+extern bool GenerateRust(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Json schema file
// See idl_gen_json_schema.cpp.
-extern bool GenerateJsonSchema(const Parser &parser,
- const std::string &path,
+extern bool GenerateJsonSchema(const Parser &parser, const std::string &path,
+ const std::string &file_name);
+
+extern bool GenerateKotlin(const Parser &parser, const std::string &path,
const std::string &file_name);
-// Generate Java/C#/.. files from the definitions in the Parser object.
-// See idl_gen_general.cpp.
-extern bool GenerateGeneral(const Parser &parser,
- const std::string &path,
- const std::string &file_name);
+// Generate Swift classes.
+// See idl_gen_swift.cpp
+extern bool GenerateSwift(const Parser &parser, const std::string &path,
+ const std::string &file_name);
// Generate a schema file from the internal representation, useful after
// parsing a .proto schema.
extern std::string GenerateFBS(const Parser &parser,
const std::string &file_name);
-extern bool GenerateFBS(const Parser &parser,
- const std::string &path,
+extern bool GenerateFBS(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated JavaScript or TypeScript code.
// See idl_gen_js.cpp.
-extern std::string JSTSMakeRule(const Parser &parser,
- const std::string &path,
- const std::string &file_name);
+extern std::string JSTSMakeRule(const Parser &parser, const std::string &path,
+ const std::string &file_name);
// Generate a make rule for the generated C++ header.
// See idl_gen_cpp.cpp.
-extern std::string CPPMakeRule(const Parser &parser,
- const std::string &path,
+extern std::string CPPMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated Dart code
// see idl_gen_dart.cpp
-extern std::string DartMakeRule(const Parser &parser,
- const std::string &path,
+extern std::string DartMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated Rust code.
// See idl_gen_rust.cpp.
-extern std::string RustMakeRule(const Parser &parser,
- const std::string &path,
+extern std::string RustMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
-// Generate a make rule for the generated Java/C#/... files.
-// See idl_gen_general.cpp.
-extern std::string GeneralMakeRule(const Parser &parser,
- const std::string &path,
- const std::string &file_name);
+// Generate a make rule for generated Java or C# files.
+// See code_generators.cpp.
+extern std::string JavaCSharpMakeRule(const Parser &parser,
+ const std::string &path,
+ const std::string &file_name);
// Generate a make rule for the generated text (JSON) files.
// See idl_gen_text.cpp.
-extern std::string TextMakeRule(const Parser &parser,
- const std::string &path,
+extern std::string TextMakeRule(const Parser &parser, const std::string &path,
const std::string &file_names);
// Generate a make rule for the generated binary files.
-// See idl_gen_general.cpp.
-extern std::string BinaryMakeRule(const Parser &parser,
- const std::string &path,
+// See code_generators.cpp.
+extern std::string BinaryMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate GRPC Cpp interfaces.
// See idl_gen_grpc.cpp.
-bool GenerateCppGRPC(const Parser &parser,
- const std::string &path,
+bool GenerateCppGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate GRPC Go interfaces.
// See idl_gen_grpc.cpp.
-bool GenerateGoGRPC(const Parser &parser,
- const std::string &path,
+bool GenerateGoGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate GRPC Java classes.
// See idl_gen_grpc.cpp
-bool GenerateJavaGRPC(const Parser &parser,
- const std::string &path,
+bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
+// Generate GRPC Python interfaces.
+// See idl_gen_grpc.cpp.
+bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
+ const std::string &file_name);
+
+// Generate GRPC Swift interfaces.
+// See idl_gen_grpc.cpp.
+extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
+ const std::string &file_name);
+
} // namespace flatbuffers
#endif // FLATBUFFERS_IDL_H_
diff --git a/include/flatbuffers/minireflect.h b/include/flatbuffers/minireflect.h
index 9d648ec0..67a79a93 100644
--- a/include/flatbuffers/minireflect.h
+++ b/include/flatbuffers/minireflect.h
@@ -88,7 +88,8 @@ inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
switch (type_table->st) {
case ST_TABLE:
case ST_UNION: return 4;
- case ST_STRUCT: return static_cast<size_t>(type_table->values[type_table->num_elems]);
+ case ST_STRUCT:
+ return static_cast<size_t>(type_table->values[type_table->num_elems]);
default: FLATBUFFERS_ASSERT(false); return 1;
}
default: FLATBUFFERS_ASSERT(false); return 1;
diff --git a/include/flatbuffers/reflection.h b/include/flatbuffers/reflection.h
index 580ae624..052e6d92 100644
--- a/include/flatbuffers/reflection.h
+++ b/include/flatbuffers/reflection.h
@@ -228,7 +228,7 @@ inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
template<typename T>
T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
- return reinterpret_cast<T*>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
+ return reinterpret_cast<T *>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
}
// Get the inline-address of a vector element. Useful for Structs (pass Struct
diff --git a/include/flatbuffers/reflection_generated.h b/include/flatbuffers/reflection_generated.h
index 869a9f3f..e7237ff2 100644
--- a/include/flatbuffers/reflection_generated.h
+++ b/include/flatbuffers/reflection_generated.h
@@ -9,22 +9,31 @@
namespace reflection {
struct Type;
+struct TypeBuilder;
struct KeyValue;
+struct KeyValueBuilder;
struct EnumVal;
+struct EnumValBuilder;
struct Enum;
+struct EnumBuilder;
struct Field;
+struct FieldBuilder;
struct Object;
+struct ObjectBuilder;
struct RPCCall;
+struct RPCCallBuilder;
struct Service;
+struct ServiceBuilder;
struct Schema;
+struct SchemaBuilder;
enum BaseType {
None = 0,
@@ -43,10 +52,11 @@ enum BaseType {
String = 13,
Vector = 14,
Obj = 15,
- Union = 16
+ Union = 16,
+ Array = 17
};
-inline const BaseType (&EnumValuesBaseType())[17] {
+inline const BaseType (&EnumValuesBaseType())[18] {
static const BaseType values[] = {
None,
UType,
@@ -64,13 +74,14 @@ inline const BaseType (&EnumValuesBaseType())[17] {
String,
Vector,
Obj,
- Union
+ Union,
+ Array
};
return values;
}
inline const char * const *EnumNamesBaseType() {
- static const char * const names[] = {
+ static const char * const names[19] = {
"None",
"UType",
"Bool",
@@ -88,53 +99,64 @@ inline const char * const *EnumNamesBaseType() {
"Vector",
"Obj",
"Union",
+ "Array",
nullptr
};
return names;
}
inline const char *EnumNameBaseType(BaseType e) {
- if (e < None || e > Union) return "";
+ if (flatbuffers::IsOutRange(e, None, Array)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesBaseType()[index];
}
struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef TypeBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_BASE_TYPE = 4,
VT_ELEMENT = 6,
- VT_INDEX = 8
+ VT_INDEX = 8,
+ VT_FIXED_LENGTH = 10
};
- BaseType base_type() const {
- return static_cast<BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
+ reflection::BaseType base_type() const {
+ return static_cast<reflection::BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
}
- BaseType element() const {
- return static_cast<BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
+ reflection::BaseType element() const {
+ return static_cast<reflection::BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
}
int32_t index() const {
return GetField<int32_t>(VT_INDEX, -1);
}
+ uint16_t fixed_length() const {
+ return GetField<uint16_t>(VT_FIXED_LENGTH, 0);
+ }
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int8_t>(verifier, VT_BASE_TYPE) &&
VerifyField<int8_t>(verifier, VT_ELEMENT) &&
VerifyField<int32_t>(verifier, VT_INDEX) &&
+ VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) &&
verifier.EndTable();
}
};
struct TypeBuilder {
+ typedef Type Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
- void add_base_type(BaseType base_type) {
+ void add_base_type(reflection::BaseType base_type) {
fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0);
}
- void add_element(BaseType element) {
+ void add_element(reflection::BaseType element) {
fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0);
}
void add_index(int32_t index) {
fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1);
}
+ void add_fixed_length(uint16_t fixed_length) {
+ fbb_.AddElement<uint16_t>(Type::VT_FIXED_LENGTH, fixed_length, 0);
+ }
explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
@@ -149,17 +171,20 @@ struct TypeBuilder {
inline flatbuffers::Offset<Type> CreateType(
flatbuffers::FlatBufferBuilder &_fbb,
- BaseType base_type = None,
- BaseType element = None,
- int32_t index = -1) {
+ reflection::BaseType base_type = reflection::None,
+ reflection::BaseType element = reflection::None,
+ int32_t index = -1,
+ uint16_t fixed_length = 0) {
TypeBuilder builder_(_fbb);
builder_.add_index(index);
+ builder_.add_fixed_length(fixed_length);
builder_.add_element(element);
builder_.add_base_type(base_type);
return builder_.Finish();
}
struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef KeyValueBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_KEY = 4,
VT_VALUE = 6
@@ -187,6 +212,7 @@ struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct KeyValueBuilder {
+ typedef KeyValue Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_key(flatbuffers::Offset<flatbuffers::String> key) {
@@ -231,6 +257,7 @@ inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
}
struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef EnumValBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_VALUE = 6,
@@ -250,11 +277,11 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(int64_t val) const {
return static_cast<int>(value() > val) - static_cast<int>(value() < val);
}
- const Object *object() const {
- return GetPointer<const Object *>(VT_OBJECT);
+ const reflection::Object *object() const {
+ return GetPointer<const reflection::Object *>(VT_OBJECT);
}
- const Type *union_type() const {
- return GetPointer<const Type *>(VT_UNION_TYPE);
+ const reflection::Type *union_type() const {
+ return GetPointer<const reflection::Type *>(VT_UNION_TYPE);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -276,6 +303,7 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct EnumValBuilder {
+ typedef EnumVal Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
@@ -284,10 +312,10 @@ struct EnumValBuilder {
void add_value(int64_t value) {
fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0);
}
- void add_object(flatbuffers::Offset<Object> object) {
+ void add_object(flatbuffers::Offset<reflection::Object> object) {
fbb_.AddOffset(EnumVal::VT_OBJECT, object);
}
- void add_union_type(flatbuffers::Offset<Type> union_type) {
+ void add_union_type(flatbuffers::Offset<reflection::Type> union_type) {
fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -310,8 +338,8 @@ inline flatbuffers::Offset<EnumVal> CreateEnumVal(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
int64_t value = 0,
- flatbuffers::Offset<Object> object = 0,
- flatbuffers::Offset<Type> union_type = 0,
+ flatbuffers::Offset<reflection::Object> object = 0,
+ flatbuffers::Offset<reflection::Type> union_type = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
EnumValBuilder builder_(_fbb);
builder_.add_value(value);
@@ -326,8 +354,8 @@ inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
int64_t value = 0,
- flatbuffers::Offset<Object> object = 0,
- flatbuffers::Offset<Type> union_type = 0,
+ flatbuffers::Offset<reflection::Object> object = 0,
+ flatbuffers::Offset<reflection::Type> union_type = 0,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
@@ -341,6 +369,7 @@ inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
}
struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef EnumBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_VALUES = 6,
@@ -358,17 +387,17 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
- const flatbuffers::Vector<flatbuffers::Offset<EnumVal>> *values() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<EnumVal>> *>(VT_VALUES);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES);
}
bool is_union() const {
return GetField<uint8_t>(VT_IS_UNION, 0) != 0;
}
- const Type *underlying_type() const {
- return GetPointer<const Type *>(VT_UNDERLYING_TYPE);
+ const reflection::Type *underlying_type() const {
+ return GetPointer<const reflection::Type *>(VT_UNDERLYING_TYPE);
}
- const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -394,21 +423,22 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct EnumBuilder {
+ typedef Enum Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(Enum::VT_NAME, name);
}
- void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<EnumVal>>> values) {
+ void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values) {
fbb_.AddOffset(Enum::VT_VALUES, values);
}
void add_is_union(bool is_union) {
fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0);
}
- void add_underlying_type(flatbuffers::Offset<Type> underlying_type) {
+ void add_underlying_type(flatbuffers::Offset<reflection::Type> underlying_type) {
fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type);
}
- void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -432,10 +462,10 @@ struct EnumBuilder {
inline flatbuffers::Offset<Enum> CreateEnum(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<EnumVal>>> values = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values = 0,
bool is_union = false,
- flatbuffers::Offset<Type> underlying_type = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
+ flatbuffers::Offset<reflection::Type> underlying_type = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
EnumBuilder builder_(_fbb);
builder_.add_documentation(documentation);
@@ -450,14 +480,14 @@ inline flatbuffers::Offset<Enum> CreateEnum(
inline flatbuffers::Offset<Enum> CreateEnumDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
- const std::vector<flatbuffers::Offset<EnumVal>> *values = nullptr,
+ std::vector<flatbuffers::Offset<reflection::EnumVal>> *values = nullptr,
bool is_union = false,
- flatbuffers::Offset<Type> underlying_type = 0,
- const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
+ flatbuffers::Offset<reflection::Type> underlying_type = 0,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
- auto values__ = values ? _fbb.CreateVector<flatbuffers::Offset<EnumVal>>(*values) : 0;
- auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
+ auto values__ = values ? _fbb.CreateVectorOfSortedTables<reflection::EnumVal>(values) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateEnum(
_fbb,
@@ -470,6 +500,7 @@ inline flatbuffers::Offset<Enum> CreateEnumDirect(
}
struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef FieldBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_TYPE = 6,
@@ -492,8 +523,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
- const Type *type() const {
- return GetPointer<const Type *>(VT_TYPE);
+ const reflection::Type *type() const {
+ return GetPointer<const reflection::Type *>(VT_TYPE);
}
uint16_t id() const {
return GetField<uint16_t>(VT_ID, 0);
@@ -516,8 +547,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool key() const {
return GetField<uint8_t>(VT_KEY, 0) != 0;
}
- const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -546,12 +577,13 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct FieldBuilder {
+ typedef Field Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(Field::VT_NAME, name);
}
- void add_type(flatbuffers::Offset<Type> type) {
+ void add_type(flatbuffers::Offset<reflection::Type> type) {
fbb_.AddOffset(Field::VT_TYPE, type);
}
void add_id(uint16_t id) {
@@ -575,7 +607,7 @@ struct FieldBuilder {
void add_key(bool key) {
fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0);
}
- void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -598,7 +630,7 @@ struct FieldBuilder {
inline flatbuffers::Offset<Field> CreateField(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
- flatbuffers::Offset<Type> type = 0,
+ flatbuffers::Offset<reflection::Type> type = 0,
uint16_t id = 0,
uint16_t offset = 0,
int64_t default_integer = 0,
@@ -606,7 +638,7 @@ inline flatbuffers::Offset<Field> CreateField(
bool deprecated = false,
bool required = false,
bool key = false,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
FieldBuilder builder_(_fbb);
builder_.add_default_real(default_real);
@@ -626,7 +658,7 @@ inline flatbuffers::Offset<Field> CreateField(
inline flatbuffers::Offset<Field> CreateFieldDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
- flatbuffers::Offset<Type> type = 0,
+ flatbuffers::Offset<reflection::Type> type = 0,
uint16_t id = 0,
uint16_t offset = 0,
int64_t default_integer = 0,
@@ -634,10 +666,10 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
bool deprecated = false,
bool required = false,
bool key = false,
- const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
- auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateField(
_fbb,
@@ -655,6 +687,7 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
}
struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef ObjectBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_FIELDS = 6,
@@ -673,8 +706,8 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
- const flatbuffers::Vector<flatbuffers::Offset<Field>> *fields() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Field>> *>(VT_FIELDS);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS);
}
bool is_struct() const {
return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0;
@@ -685,8 +718,8 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int32_t bytesize() const {
return GetField<int32_t>(VT_BYTESIZE, 0);
}
- const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -712,12 +745,13 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct ObjectBuilder {
+ typedef Object Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(Object::VT_NAME, name);
}
- void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Field>>> fields) {
+ void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields) {
fbb_.AddOffset(Object::VT_FIELDS, fields);
}
void add_is_struct(bool is_struct) {
@@ -729,7 +763,7 @@ struct ObjectBuilder {
void add_bytesize(int32_t bytesize) {
fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0);
}
- void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -752,11 +786,11 @@ struct ObjectBuilder {
inline flatbuffers::Offset<Object> CreateObject(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Field>>> fields = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields = 0,
bool is_struct = false,
int32_t minalign = 0,
int32_t bytesize = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
ObjectBuilder builder_(_fbb);
builder_.add_documentation(documentation);
@@ -772,15 +806,15 @@ inline flatbuffers::Offset<Object> CreateObject(
inline flatbuffers::Offset<Object> CreateObjectDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
- const std::vector<flatbuffers::Offset<Field>> *fields = nullptr,
+ std::vector<flatbuffers::Offset<reflection::Field>> *fields = nullptr,
bool is_struct = false,
int32_t minalign = 0,
int32_t bytesize = 0,
- const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
- auto fields__ = fields ? _fbb.CreateVector<flatbuffers::Offset<Field>>(*fields) : 0;
- auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
+ auto fields__ = fields ? _fbb.CreateVectorOfSortedTables<reflection::Field>(fields) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateObject(
_fbb,
@@ -794,6 +828,7 @@ inline flatbuffers::Offset<Object> CreateObjectDirect(
}
struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef RPCCallBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_REQUEST = 6,
@@ -810,14 +845,14 @@ struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
- const Object *request() const {
- return GetPointer<const Object *>(VT_REQUEST);
+ const reflection::Object *request() const {
+ return GetPointer<const reflection::Object *>(VT_REQUEST);
}
- const Object *response() const {
- return GetPointer<const Object *>(VT_RESPONSE);
+ const reflection::Object *response() const {
+ return GetPointer<const reflection::Object *>(VT_RESPONSE);
}
- const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -841,18 +876,19 @@ struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct RPCCallBuilder {
+ typedef RPCCall Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(RPCCall::VT_NAME, name);
}
- void add_request(flatbuffers::Offset<Object> request) {
+ void add_request(flatbuffers::Offset<reflection::Object> request) {
fbb_.AddOffset(RPCCall::VT_REQUEST, request);
}
- void add_response(flatbuffers::Offset<Object> response) {
+ void add_response(flatbuffers::Offset<reflection::Object> response) {
fbb_.AddOffset(RPCCall::VT_RESPONSE, response);
}
- void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -876,9 +912,9 @@ struct RPCCallBuilder {
inline flatbuffers::Offset<RPCCall> CreateRPCCall(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
- flatbuffers::Offset<Object> request = 0,
- flatbuffers::Offset<Object> response = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
+ flatbuffers::Offset<reflection::Object> request = 0,
+ flatbuffers::Offset<reflection::Object> response = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
RPCCallBuilder builder_(_fbb);
builder_.add_documentation(documentation);
@@ -892,12 +928,12 @@ inline flatbuffers::Offset<RPCCall> CreateRPCCall(
inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
- flatbuffers::Offset<Object> request = 0,
- flatbuffers::Offset<Object> response = 0,
- const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
+ flatbuffers::Offset<reflection::Object> request = 0,
+ flatbuffers::Offset<reflection::Object> response = 0,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
- auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateRPCCall(
_fbb,
@@ -909,6 +945,7 @@ inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
}
struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef ServiceBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_CALLS = 6,
@@ -924,11 +961,11 @@ struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
- const flatbuffers::Vector<flatbuffers::Offset<RPCCall>> *calls() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<RPCCall>> *>(VT_CALLS);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS);
}
- const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -951,15 +988,16 @@ struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct ServiceBuilder {
+ typedef Service Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(Service::VT_NAME, name);
}
- void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<RPCCall>>> calls) {
+ void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls) {
fbb_.AddOffset(Service::VT_CALLS, calls);
}
- void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
+ void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -981,8 +1019,8 @@ struct ServiceBuilder {
inline flatbuffers::Offset<Service> CreateService(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<RPCCall>>> calls = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
ServiceBuilder builder_(_fbb);
builder_.add_documentation(documentation);
@@ -995,12 +1033,12 @@ inline flatbuffers::Offset<Service> CreateService(
inline flatbuffers::Offset<Service> CreateServiceDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
- const std::vector<flatbuffers::Offset<RPCCall>> *calls = nullptr,
- const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
+ std::vector<flatbuffers::Offset<reflection::RPCCall>> *calls = nullptr,
+ std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
- auto calls__ = calls ? _fbb.CreateVector<flatbuffers::Offset<RPCCall>>(*calls) : 0;
- auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
+ auto calls__ = calls ? _fbb.CreateVectorOfSortedTables<reflection::RPCCall>(calls) : 0;
+ auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateService(
_fbb,
@@ -1011,6 +1049,7 @@ inline flatbuffers::Offset<Service> CreateServiceDirect(
}
struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef SchemaBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_OBJECTS = 4,
VT_ENUMS = 6,
@@ -1019,11 +1058,11 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_ROOT_TABLE = 12,
VT_SERVICES = 14
};
- const flatbuffers::Vector<flatbuffers::Offset<Object>> *objects() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Object>> *>(VT_OBJECTS);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS);
}
- const flatbuffers::Vector<flatbuffers::Offset<Enum>> *enums() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Enum>> *>(VT_ENUMS);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *enums() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *>(VT_ENUMS);
}
const flatbuffers::String *file_ident() const {
return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT);
@@ -1031,11 +1070,11 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const flatbuffers::String *file_ext() const {
return GetPointer<const flatbuffers::String *>(VT_FILE_EXT);
}
- const Object *root_table() const {
- return GetPointer<const Object *>(VT_ROOT_TABLE);
+ const reflection::Object *root_table() const {
+ return GetPointer<const reflection::Object *>(VT_ROOT_TABLE);
}
- const flatbuffers::Vector<flatbuffers::Offset<Service>> *services() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Service>> *>(VT_SERVICES);
+ const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
@@ -1059,12 +1098,13 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct SchemaBuilder {
+ typedef Schema Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
- void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Object>>> objects) {
+ void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects) {
fbb_.AddOffset(Schema::VT_OBJECTS, objects);
}
- void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Enum>>> enums) {
+ void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums) {
fbb_.AddOffset(Schema::VT_ENUMS, enums);
}
void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) {
@@ -1073,10 +1113,10 @@ struct SchemaBuilder {
void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) {
fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext);
}
- void add_root_table(flatbuffers::Offset<Object> root_table) {
+ void add_root_table(flatbuffers::Offset<reflection::Object> root_table) {
fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table);
}
- void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Service>>> services) {
+ void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) {
fbb_.AddOffset(Schema::VT_SERVICES, services);
}
explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
@@ -1095,12 +1135,12 @@ struct SchemaBuilder {
inline flatbuffers::Offset<Schema> CreateSchema(
flatbuffers::FlatBufferBuilder &_fbb,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Object>>> objects = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Enum>>> enums = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums = 0,
flatbuffers::Offset<flatbuffers::String> file_ident = 0,
flatbuffers::Offset<flatbuffers::String> file_ext = 0,
- flatbuffers::Offset<Object> root_table = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Service>>> services = 0) {
+ flatbuffers::Offset<reflection::Object> root_table = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0) {
SchemaBuilder builder_(_fbb);
builder_.add_services(services);
builder_.add_root_table(root_table);
@@ -1113,17 +1153,17 @@ inline flatbuffers::Offset<Schema> CreateSchema(
inline flatbuffers::Offset<Schema> CreateSchemaDirect(
flatbuffers::FlatBufferBuilder &_fbb,
- const std::vector<flatbuffers::Offset<Object>> *objects = nullptr,
- const std::vector<flatbuffers::Offset<Enum>> *enums = nullptr,
+ std::vector<flatbuffers::Offset<reflection::Object>> *objects = nullptr,
+ std::vector<flatbuffers::Offset<reflection::Enum>> *enums = nullptr,
const char *file_ident = nullptr,
const char *file_ext = nullptr,
- flatbuffers::Offset<Object> root_table = 0,
- const std::vector<flatbuffers::Offset<Service>> *services = nullptr) {
- auto objects__ = objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0;
- auto enums__ = enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0;
+ flatbuffers::Offset<reflection::Object> root_table = 0,
+ std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr) {
+ auto objects__ = objects ? _fbb.CreateVectorOfSortedTables<reflection::Object>(objects) : 0;
+ auto enums__ = enums ? _fbb.CreateVectorOfSortedTables<reflection::Enum>(enums) : 0;
auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0;
auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0;
- auto services__ = services ? _fbb.CreateVector<flatbuffers::Offset<Service>>(*services) : 0;
+ auto services__ = services ? _fbb.CreateVectorOfSortedTables<reflection::Service>(services) : 0;
return reflection::CreateSchema(
_fbb,
objects__,
diff --git a/include/flatbuffers/stl_emulation.h b/include/flatbuffers/stl_emulation.h
index 6f6e7664..8bae61bf 100644
--- a/include/flatbuffers/stl_emulation.h
+++ b/include/flatbuffers/stl_emulation.h
@@ -96,13 +96,13 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
}
};
- template <> class numeric_limits<float> :
+ template <> class numeric_limits<float> :
public std::numeric_limits<float> {
public:
static float lowest() { return -FLT_MAX; }
};
- template <> class numeric_limits<double> :
+ template <> class numeric_limits<double> :
public std::numeric_limits<double> {
public:
static double lowest() { return -DBL_MAX; }
@@ -138,7 +138,12 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <typename T, typename U> using is_same = std::is_same<T,U>;
template <typename T> using is_floating_point = std::is_floating_point<T>;
template <typename T> using is_unsigned = std::is_unsigned<T>;
+ template <typename T> using is_enum = std::is_enum<T>;
template <typename T> using make_unsigned = std::make_unsigned<T>;
+ template<bool B, class T, class F>
+ using conditional = std::conditional<B, T, F>;
+ template<class T, T v>
+ using integral_constant = std::integral_constant<T, v>;
#else
// Map C++ TR1 templates defined by stlport.
template <typename T> using is_scalar = std::tr1::is_scalar<T>;
@@ -146,6 +151,7 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <typename T> using is_floating_point =
std::tr1::is_floating_point<T>;
template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
+ template <typename T> using is_enum = std::tr1::is_enum<T>;
// Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned.
template<typename T> struct make_unsigned {
static_assert(is_unsigned<T>::value, "Specialization not implemented!");
@@ -157,6 +163,10 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template<> struct make_unsigned<long> { using type = unsigned long; };
template<>
struct make_unsigned<long long> { using type = unsigned long long; };
+ template<bool B, class T, class F>
+ using conditional = std::tr1::conditional<B, T, F>;
+ template<class T, T v>
+ using integral_constant = std::tr1::integral_constant<T, v>;
#endif // !FLATBUFFERS_CPP98_STL
#else
// MSVC 2010 doesn't support C++11 aliases.
@@ -165,7 +175,12 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <typename T> struct is_floating_point :
public std::is_floating_point<T> {};
template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
+ template <typename T> struct is_enum : public std::is_enum<T> {};
template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
+ template<bool B, class T, class F>
+ struct conditional : public std::conditional<B, T, F> {};
+ template<class T, T v>
+ struct integral_constant : public std::integral_constant<T, v> {};
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#ifndef FLATBUFFERS_CPP98_STL
@@ -268,6 +283,23 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
return reinterpret_cast<intptr_t>(x.get()) == y;
}
+
+ template <class T> bool operator!=(const unique_ptr<T>& x, decltype(nullptr)) {
+ return !!x;
+ }
+
+ template <class T> bool operator!=(decltype(nullptr), const unique_ptr<T>& x) {
+ return !!x;
+ }
+
+ template <class T> bool operator==(const unique_ptr<T>& x, decltype(nullptr)) {
+ return !x;
+ }
+
+ template <class T> bool operator==(decltype(nullptr), const unique_ptr<T>& x) {
+ return !x;
+ }
+
#endif // !FLATBUFFERS_CPP98_STL
} // namespace flatbuffers
diff --git a/include/flatbuffers/util.h b/include/flatbuffers/util.h
index 4367bbec..a13fc5da 100644
--- a/include/flatbuffers/util.h
+++ b/include/flatbuffers/util.h
@@ -17,10 +17,10 @@
#ifndef FLATBUFFERS_UTIL_H_
#define FLATBUFFERS_UTIL_H_
-#include "flatbuffers/base.h"
-
#include <errno.h>
+#include "flatbuffers/base.h"
+
#ifndef FLATBUFFERS_PREFER_PRINTF
# include <sstream>
#else // FLATBUFFERS_PREFER_PRINTF
@@ -102,7 +102,7 @@ std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) {
size_t string_width = NumToStringWidth(t, precision);
std::string s(string_width, 0x00);
// Allow snprintf to use std::string trailing null to detect buffer overflow
- snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, precision, t);
+ snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, string_width, t);
return s;
}
#endif // FLATBUFFERS_PREFER_PRINTF
@@ -327,7 +327,7 @@ template<typename T> inline bool StringToNumber(const char *s, T *val) {
int64_t i64;
// The errno check isn't needed, will return MAX/MIN on overflow.
if (StringToIntegerImpl(&i64, s, 0, false)) {
- const int64_t max = flatbuffers::numeric_limits<T>::max();
+ const int64_t max = (flatbuffers::numeric_limits<T>::max)();
const int64_t min = flatbuffers::numeric_limits<T>::lowest();
if (i64 > max) {
*val = static_cast<T>(max);
@@ -365,7 +365,7 @@ inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) {
if (*s == '-') {
// For unsigned types return the max to distinguish from
// "no conversion can be performed".
- *val = flatbuffers::numeric_limits<uint64_t>::max();
+ *val = (flatbuffers::numeric_limits<uint64_t>::max)();
return false;
}
}
@@ -636,6 +636,32 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
return true;
}
+inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
+ size_t max_length,
+ const std::string &wrapped_line_prefix,
+ const std::string &wrapped_line_suffix) {
+ std::string text = wrapped_line_prefix;
+ size_t start_offset = 0;
+ const char *s = reinterpret_cast<const char *>(buffer);
+ for (size_t i = 0; s && i < buffer_size; i++) {
+ // Last iteration or do we have more?
+ bool have_more = i + 1 < buffer_size;
+ text += "0x";
+ text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
+ if (have_more) { text += ','; }
+ // If we have more to process and we reached max_length
+ if (have_more &&
+ text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
+ text += wrapped_line_suffix;
+ text += '\n';
+ start_offset = text.size();
+ text += wrapped_line_prefix;
+ }
+ }
+ text += wrapped_line_suffix;
+ return text;
+}
+
// Remove paired quotes in a string: "text"|'text' -> text.
std::string RemoveStringQuotes(const std::string &s);
@@ -649,6 +675,9 @@ bool SetGlobalTestLocale(const char *locale_name,
bool ReadEnvironmentVariable(const char *var_name,
std::string *_value = nullptr);
+// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs.
+void SetupDefaultCRTReportMode();
+
} // namespace flatbuffers
#endif // FLATBUFFERS_UTIL_H_
diff --git a/java/com/google/flatbuffers/ArrayReadWriteBuf.java b/java/com/google/flatbuffers/ArrayReadWriteBuf.java
new file mode 100644
index 00000000..00517747
--- /dev/null
+++ b/java/com/google/flatbuffers/ArrayReadWriteBuf.java
@@ -0,0 +1,241 @@
+package com.google.flatbuffers;
+
+import java.util.Arrays;
+
+/**
+ * Implements {@code ReadBuf} using an array of bytes
+ * as a backing storage. Using array of bytes are
+ * usually faster than {@code ByteBuffer}.
+ *
+ * This class is not thread-safe, meaning that
+ * it must operate on a single thread. Operating from
+ * multiple thread leads into a undefined behavior
+ */
+public class ArrayReadWriteBuf implements ReadWriteBuf {
+
+ private byte[] buffer;
+ private int writePos;
+
+ public ArrayReadWriteBuf() {
+ this(10);
+ }
+
+ public ArrayReadWriteBuf(int initialCapacity) {
+ this(new byte[initialCapacity]);
+ }
+
+ public ArrayReadWriteBuf(byte[] buffer) {
+ this.buffer = buffer;
+ this.writePos = 0;
+ }
+
+ public ArrayReadWriteBuf(byte[] buffer, int startPos) {
+ this.buffer = buffer;
+ this.writePos = startPos;
+ }
+
+ @Override
+ public boolean getBoolean(int index) {
+ return buffer[index] != 0;
+ }
+
+ @Override
+ public byte get(int index) {
+ return buffer[index];
+ }
+
+ @Override
+ public short getShort(int index) {
+ return (short) ((buffer[index+ 1] << 8) | (buffer[index] & 0xff));
+ }
+
+ @Override
+ public int getInt(int index) {
+ return (((buffer[index + 3]) << 24) |
+ ((buffer[index + 2] & 0xff) << 16) |
+ ((buffer[index + 1] & 0xff) << 8) |
+ ((buffer[index] & 0xff)));
+ }
+
+ @Override
+ public long getLong(int index) {
+ return ((((long) buffer[index++] & 0xff)) |
+ (((long) buffer[index++] & 0xff) << 8) |
+ (((long) buffer[index++] & 0xff) << 16) |
+ (((long) buffer[index++] & 0xff) << 24) |
+ (((long) buffer[index++] & 0xff) << 32) |
+ (((long) buffer[index++] & 0xff) << 40) |
+ (((long) buffer[index++] & 0xff) << 48) |
+ (((long) buffer[index]) << 56));
+ }
+
+ @Override
+ public float getFloat(int index) {
+ return Float.intBitsToFloat(getInt(index));
+ }
+
+ @Override
+ public double getDouble(int index) {
+ return Double.longBitsToDouble(getLong(index));
+ }
+
+ @Override
+ public String getString(int start, int size) {
+ return Utf8Safe.decodeUtf8Array(buffer, start, size);
+ }
+
+ @Override
+ public byte[] data() {
+ return buffer;
+ }
+
+
+ @Override
+ public void putBoolean(boolean value) {
+ setBoolean(writePos, value);
+ writePos++;
+ }
+
+ @Override
+ public void put(byte[] value, int start, int length) {
+ set(writePos, value, start, length);
+ writePos+=length;
+ }
+
+ @Override
+ public void put(byte value) {
+ set(writePos, value);
+ writePos++;
+ }
+
+ @Override
+ public void putShort(short value) {
+ setShort(writePos, value);
+ writePos +=2;
+ }
+
+ @Override
+ public void putInt(int value) {
+ setInt(writePos, value);
+ writePos +=4;
+ }
+
+ @Override
+ public void putLong(long value) {
+ setLong(writePos, value);
+ writePos +=8;
+ }
+
+ @Override
+ public void putFloat(float value) {
+ setFloat(writePos, value);
+ writePos +=4;
+ }
+
+ @Override
+ public void putDouble(double value) {
+ setDouble(writePos, value);
+ writePos +=8;
+ }
+
+ @Override
+ public void setBoolean(int index, boolean value) {
+ set(index, value ? (byte)1 : (byte)0);
+ }
+
+ @Override
+ public void set(int index, byte value) {
+ requestCapacity(index + 1);
+ buffer[index] = value;
+ }
+
+ @Override
+ public void set(int index, byte[] toCopy, int start, int length) {
+ requestCapacity(index + (length - start));
+ System.arraycopy(toCopy, start, buffer, index, length);
+ }
+
+ @Override
+ public void setShort(int index, short value) {
+ requestCapacity(index + 2);
+
+ buffer[index++] = (byte) ((value) & 0xff);
+ buffer[index ] = (byte) ((value >> 8) & 0xff);
+ }
+
+ @Override
+ public void setInt(int index, int value) {
+ requestCapacity(index + 4);
+
+ buffer[index++] = (byte) ((value) & 0xff);
+ buffer[index++] = (byte) ((value >> 8) & 0xff);
+ buffer[index++] = (byte) ((value >> 16) & 0xff);
+ buffer[index ] = (byte) ((value >> 24) & 0xff);
+ }
+
+ @Override
+ public void setLong(int index, long value) {
+ requestCapacity(index + 8);
+
+ int i = (int) value;
+ buffer[index++] = (byte) ((i) & 0xff);
+ buffer[index++] = (byte) ((i >> 8) & 0xff);
+ buffer[index++] = (byte) ((i >> 16) & 0xff);
+ buffer[index++] = (byte) ((i >> 24) & 0xff);
+ i = (int) (value >> 32);
+ buffer[index++] = (byte) ((i) & 0xff);
+ buffer[index++] = (byte) ((i >> 8) & 0xff);
+ buffer[index++] = (byte) ((i >> 16) & 0xff);
+ buffer[index ] = (byte) ((i >> 24) & 0xff);
+ }
+
+ @Override
+ public void setFloat(int index, float value) {
+ requestCapacity(index + 4);
+
+ int iValue = Float.floatToRawIntBits(value);
+ buffer[index++] = (byte) ((iValue) & 0xff);
+ buffer[index++] = (byte) ((iValue >> 8) & 0xff);
+ buffer[index++] = (byte) ((iValue >> 16) & 0xff);
+ buffer[index ] = (byte) ((iValue >> 24) & 0xff);
+ }
+
+ @Override
+ public void setDouble(int index, double value) {
+ requestCapacity(index + 8);
+
+ long lValue = Double.doubleToRawLongBits(value);
+ int i = (int) lValue;
+ buffer[index++] = (byte) ((i) & 0xff);
+ buffer[index++] = (byte) ((i >> 8) & 0xff);
+ buffer[index++] = (byte) ((i >> 16) & 0xff);
+ buffer[index++] = (byte) ((i >> 24) & 0xff);
+ i = (int) (lValue >> 32);
+ buffer[index++] = (byte) ((i) & 0xff);
+ buffer[index++] = (byte) ((i >> 8) & 0xff);
+ buffer[index++] = (byte) ((i >> 16) & 0xff);
+ buffer[index ] = (byte) ((i >> 24) & 0xff);
+ }
+
+ @Override
+ public int limit() {
+ return writePos;
+ }
+
+ @Override
+ public int writePosition() {
+ return writePos;
+ }
+
+ @Override
+ public boolean requestCapacity(int capacity) {
+ if (buffer.length > capacity) {
+ return true;
+ }
+ // implemented in the same growing fashion as ArrayList
+ int oldCapacity = buffer.length;
+ int newCapacity = oldCapacity + (oldCapacity >> 1);
+ buffer = Arrays.copyOf(buffer, newCapacity);
+ return true;
+ }
+}
diff --git a/java/com/google/flatbuffers/BaseVector.java b/java/com/google/flatbuffers/BaseVector.java
new file mode 100644
index 00000000..9230da79
--- /dev/null
+++ b/java/com/google/flatbuffers/BaseVector.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+
+/// @cond FLATBUFFERS_INTERNAL
+
+/**
+ * All vector access objects derive from this class, and add their own accessors.
+ */
+public class BaseVector {
+ /** Used to hold the vector data position. */
+ private int vector;
+ /** Used to hold the vector size. */
+ private int length;
+ /** Used to hold the vector element size in table. */
+ private int element_size;
+ /** The underlying ByteBuffer to hold the data of the vector. */
+ protected ByteBuffer bb;
+
+ /**
+ * Get the start data of a vector.
+ *
+ * @return Returns the start of the vector data.
+ */
+ protected int __vector() {
+ return vector;
+ }
+
+ /**
+ * Gets the element position in vector's ByteBuffer.
+ *
+ * @param j An `int` index of element into a vector.
+ * @return Returns the position of the vector element in a ByteBuffer.
+ */
+ protected int __element(int j) {
+ return vector + j * element_size;
+ }
+
+ /**
+ * Re-init the internal state with an external buffer {@code ByteBuffer}, an offset within and
+ * element size.
+ *
+ * This method exists primarily to allow recycling vector instances without risking memory leaks
+ * due to {@code ByteBuffer} references.
+ */
+ protected void __reset(int _vector, int _element_size, ByteBuffer _bb) {
+ bb = _bb;
+ if (bb != null) {
+ vector = _vector;
+ length = bb.getInt(_vector - Constants.SIZEOF_INT);
+ element_size = _element_size;
+ } else {
+ vector = 0;
+ length = 0;
+ element_size = 0;
+ }
+ }
+
+ /**
+ * Resets the internal state with a null {@code ByteBuffer} and a zero position.
+ *
+ * This method exists primarily to allow recycling vector instances without risking memory leaks
+ * due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
+ * again to a {@code ByteBuffer}.
+ */
+ public void reset() {
+ __reset(0, 0, null);
+ }
+
+ /**
+ * Get the length of a vector.
+ *
+ * @return Returns the length of the vector.
+ */
+ public int length() {
+ return length;
+ }
+}
+
+/// @endcond
diff --git a/java/com/google/flatbuffers/BooleanVector.java b/java/com/google/flatbuffers/BooleanVector.java
new file mode 100644
index 00000000..1c2a4cda
--- /dev/null
+++ b/java/com/google/flatbuffers/BooleanVector.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of booleans.
+ */
+public final class BooleanVector extends BaseVector {
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param _vector Start data of a vector.
+ * @param _bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public BooleanVector __assign(int _vector, ByteBuffer _bb) {
+ __reset(_vector, Constants.SIZEOF_BYTE, _bb); return this;
+ }
+
+ /**
+ * Reads the boolean at the given index.
+ *
+ * @param j The index from which the boolean will be read.
+ * @return the boolean value at the given index.
+ */
+ public boolean get(int j) {
+ return 0 != bb.get(__element(j));
+ }
+}
diff --git a/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java b/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
new file mode 100644
index 00000000..79ad7bbb
--- /dev/null
+++ b/java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
@@ -0,0 +1,165 @@
+package com.google.flatbuffers;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+public class ByteBufferReadWriteBuf implements ReadWriteBuf {
+
+ private final ByteBuffer buffer;
+
+ public ByteBufferReadWriteBuf(ByteBuffer bb) {
+ this.buffer = bb;
+ this.buffer.order(ByteOrder.LITTLE_ENDIAN);
+ }
+
+ @Override
+ public boolean getBoolean(int index) {
+ return get(index) != 0;
+ }
+
+ @Override
+ public byte get(int index) {
+ return buffer.get(index);
+ }
+
+ @Override
+ public short getShort(int index) {
+ return buffer.getShort(index);
+ }
+
+ @Override
+ public int getInt(int index) {
+ return buffer.getInt(index);
+ }
+
+ @Override
+ public long getLong(int index) {
+ return buffer.getLong(index);
+ }
+
+ @Override
+ public float getFloat(int index) {
+ return buffer.getFloat(index);
+ }
+
+ @Override
+ public double getDouble(int index) {
+ return buffer.getDouble(index);
+ }
+
+ @Override
+ public String getString(int start, int size) {
+ return Utf8Safe.decodeUtf8Buffer(buffer, start, size);
+ }
+
+ @Override
+ public byte[] data() {
+ return buffer.array();
+ }
+
+ @Override
+ public void putBoolean(boolean value) {
+ buffer.put(value ? (byte)1 : (byte)0);
+ }
+
+ @Override
+ public void put(byte[] value, int start, int length) {
+ buffer.put(value, start, length);
+ }
+
+ @Override
+ public void put(byte value) {
+ buffer.put(value);
+ }
+
+ @Override
+ public void putShort(short value) {
+ buffer.putShort(value);
+ }
+
+ @Override
+ public void putInt(int value) {
+ buffer.putInt(value);
+ }
+
+ @Override
+ public void putLong(long value) {
+ buffer.putLong(value);
+ }
+
+ @Override
+ public void putFloat(float value) {
+ buffer.putFloat(value);
+ }
+
+ @Override
+ public void putDouble(double value) {
+ buffer.putDouble(value);
+ }
+
+ @Override
+ public void setBoolean(int index, boolean value) {
+ set(index, value ? (byte)1 : (byte)0);
+ }
+
+ @Override
+ public void set(int index, byte value) {
+ requestCapacity(index + 1);
+ buffer.put(index, value);
+ }
+
+ @Override
+ public void set(int index, byte[] value, int start, int length) {
+ requestCapacity(index + (length - start));
+ int curPos = buffer.position();
+ buffer.position(index);
+ buffer.put(value, start, length);
+ buffer.position(curPos);
+ }
+
+ @Override
+ public void setShort(int index, short value) {
+ requestCapacity(index + 2);
+ buffer.putShort(index, value);
+ }
+
+ @Override
+ public void setInt(int index, int value) {
+ requestCapacity(index + 4);
+ buffer.putInt(index, value);
+ }
+
+ @Override
+ public void setLong(int index, long value) {
+ requestCapacity(index + 8);
+ buffer.putLong(index, value);
+ }
+
+ @Override
+ public void setFloat(int index, float value) {
+ requestCapacity(index + 4);
+ buffer.putFloat(index, value);
+ }
+
+ @Override
+ public void setDouble(int index, double value) {
+ requestCapacity(index + 8);
+ buffer.putDouble(index, value);
+ }
+
+ @Override
+ public int writePosition() {
+ return buffer.position();
+ }
+
+ @Override
+ public int limit() {
+ return buffer.limit();
+ }
+
+ @Override
+ public boolean requestCapacity(int capacity) {
+ return capacity <= buffer.limit();
+ }
+
+}
diff --git a/java/com/google/flatbuffers/ByteVector.java b/java/com/google/flatbuffers/ByteVector.java
new file mode 100644
index 00000000..8bc715b3
--- /dev/null
+++ b/java/com/google/flatbuffers/ByteVector.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of signed or unsigned 8-bit values.
+ */
+public final class ByteVector extends BaseVector {
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param vector Start data of a vector.
+ * @param bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public ByteVector __assign(int vector, ByteBuffer bb) {
+ __reset(vector, Constants.SIZEOF_BYTE, bb); return this;
+ }
+
+ /**
+ * Reads the byte at the given index.
+ *
+ * @param j The index from which the byte will be read.
+ * @return the 8-bit value at the given index.
+ */
+ public byte get(int j) {
+ return bb.get(__element(j));
+ }
+
+ /**
+ * Reads the byte at the given index, zero-extends it to type int, and returns the result,
+ * which is therefore in the range 0 through 255.
+ *
+ * @param j The index from which the byte will be read.
+ * @return the unsigned 8-bit at the given index.
+ */
+ public int getAsUnsigned(int j) {
+ return (int) get(j) & 0xFF;
+ }
+}
diff --git a/java/com/google/flatbuffers/Constants.java b/java/com/google/flatbuffers/Constants.java
index 751f4a65..0623b942 100644
--- a/java/com/google/flatbuffers/Constants.java
+++ b/java/com/google/flatbuffers/Constants.java
@@ -39,6 +39,14 @@ public class Constants {
static final int FILE_IDENTIFIER_LENGTH = 4;
/** The number of bytes in a size prefix. */
public static final int SIZE_PREFIX_LENGTH = 4;
+ /** A version identifier to force a compile error if someone
+ accidentally tries to build generated code with a runtime of
+ two mismatched version. Versions need to always match, as
+ the runtime and generated code are modified in sync.
+ Changes to the Java implementation need to be sure to change
+ the version here and in the code generator on every possible
+ incompatible change */
+ public static void FLATBUFFERS_1_12_0() {}
}
/// @endcond
diff --git a/java/com/google/flatbuffers/DoubleVector.java b/java/com/google/flatbuffers/DoubleVector.java
new file mode 100644
index 00000000..fd4a3a48
--- /dev/null
+++ b/java/com/google/flatbuffers/DoubleVector.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of double values.
+ */
+public final class DoubleVector extends BaseVector {
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param _vector Start data of a vector.
+ * @param _bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public DoubleVector __assign(int _vector, ByteBuffer _bb) {
+ __reset(_vector, Constants.SIZEOF_DOUBLE, _bb); return this;
+ }
+
+ /**
+ * Reads the double value at the given index.
+ *
+ * @param j The index from which the double value will be read.
+ * @return the double value at the given index.
+ */
+ public double get(int j) {
+ return bb.getDouble(__element(j));
+ }
+}
diff --git a/java/com/google/flatbuffers/FlatBufferBuilder.java b/java/com/google/flatbuffers/FlatBufferBuilder.java
index 9f3ae20e..e5e3967a 100644
--- a/java/com/google/flatbuffers/FlatBufferBuilder.java
+++ b/java/com/google/flatbuffers/FlatBufferBuilder.java
@@ -72,7 +72,6 @@ public class FlatBufferBuilder {
if (initial_size <= 0) {
initial_size = 1;
}
- space = initial_size;
this.bb_factory = bb_factory;
if (existing_bb != null) {
bb = existing_bb;
@@ -82,6 +81,7 @@ public class FlatBufferBuilder {
bb = bb_factory.newByteBuffer(initial_size);
}
this.utf8 = utf8;
+ space = bb.capacity();
}
/**
@@ -199,6 +199,17 @@ public class FlatBufferBuilder {
}
}
+ /**
+ * Helper function to test if a field is present in the table
+ *
+ * @param table Flatbuffer table
+ * @param offset virtual table offset
+ * @return true if the filed is present
+ */
+ public static boolean isFieldPresent(Table table, int offset) {
+ return table.__offset(offset) != 0;
+ }
+
/**
* Reset the FlatBufferBuilder by purging all data that it holds.
*/
@@ -231,6 +242,7 @@ public class FlatBufferBuilder {
int new_buf_size = old_buf_size == 0 ? 1 : old_buf_size << 1;
bb.position(0);
ByteBuffer nbb = bb_factory.newByteBuffer(new_buf_size);
+ new_buf_size = nbb.clear().capacity(); // Ensure the returned buffer is treated as empty
nbb.position(new_buf_size - old_buf_size);
nbb.put(bb);
return nbb;
@@ -560,6 +572,38 @@ public class FlatBufferBuilder {
return endVector();
}
+ /**
+ * Create a byte array in the buffer.
+ *
+ * @param arr a source array with data.
+ * @param offset the offset in the source array to start copying from.
+ * @param length the number of bytes to copy from the source array.
+ * @return The offset in the buffer where the encoded array starts.
+ */
+ public int createByteVector(byte[] arr, int offset, int length) {
+ startVector(1, length, 1);
+ bb.position(space -= length);
+ bb.put(arr, offset, length);
+ return endVector();
+ }
+
+ /**
+ * Create a byte array in the buffer.
+ *
+ * The source {@link ByteBuffer} position is advanced by {@link ByteBuffer#remaining()} places
+ * after this call.
+ *
+ * @param byteBuffer A source {@link ByteBuffer} with data.
+ * @return The offset in the buffer where the encoded array starts.
+ */
+ public int createByteVector(ByteBuffer byteBuffer) {
+ int length = byteBuffer.remaining();
+ startVector(1, length, 1);
+ bb.position(space -= length);
+ bb.put(byteBuffer);
+ return endVector();
+ }
+
/// @cond FLATBUFFERS_INTERNAL
/**
* Should not be accessing the final buffer before it is finished.
@@ -632,7 +676,7 @@ public class FlatBufferBuilder {
*
* @param numfields The number of fields found in this object.
*/
- public void startObject(int numfields) {
+ public void startTable(int numfields) {
notNested();
if (vtable == null || vtable.length < numfields) vtable = new int[numfields];
vtable_in_use = numfields;
@@ -757,11 +801,11 @@ public class FlatBufferBuilder {
* Finish off writing the object that is under construction.
*
* @return The offset to the object inside {@link #dataBuffer()}.
- * @see #startObject(int)
+ * @see #startTable(int)
*/
- public int endObject() {
+ public int endTable() {
if (vtable == null || !nested)
- throw new AssertionError("FlatBuffers: endObject called without startObject");
+ throw new AssertionError("FlatBuffers: endTable called without startTable");
addInt(0);
int vtableloc = offset();
// Write out the current vtable.
diff --git a/java/com/google/flatbuffers/FlexBuffers.java b/java/com/google/flatbuffers/FlexBuffers.java
new file mode 100644
index 00000000..d7df08c1
--- /dev/null
+++ b/java/com/google/flatbuffers/FlexBuffers.java
@@ -0,0 +1,1102 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+
+import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+
+/// @file
+/// @addtogroup flatbuffers_java_api
+/// @{
+
+/**
+ * This class can be used to parse FlexBuffer messages.
+ * <p>
+ * For generating FlexBuffer messages, use {@link FlexBuffersBuilder}.
+ * <p>
+ * Example of usage:
+ * <pre>
+ * ReadBuf bb = ... // load message from file or network
+ * FlexBuffers.Reference r = FlexBuffers.getRoot(bb); // Reads the root element
+ * FlexBuffers.Map map = r.asMap(); // We assumed root object is a map
+ * System.out.println(map.get("name").asString()); // prints element with key "name"
+ * </pre>
+ */
+public class FlexBuffers {
+
+ // These are used as the upper 6 bits of a type field to indicate the actual
+ // type.
+ /** Represent a null type */
+ public static final int FBT_NULL = 0;
+ /** Represent a signed integer type */
+ public static final int FBT_INT = 1;
+ /** Represent a unsigned type */
+ public static final int FBT_UINT = 2;
+ /** Represent a float type */
+ public static final int FBT_FLOAT = 3; // Types above stored inline, types below store an offset.
+ /** Represent a key to a map type */
+ public static final int FBT_KEY = 4;
+ /** Represent a string type */
+ public static final int FBT_STRING = 5;
+ /** Represent a indirect signed integer type */
+ public static final int FBT_INDIRECT_INT = 6;
+ /** Represent a indirect unsigned integer type */
+ public static final int FBT_INDIRECT_UINT = 7;
+ /** Represent a indirect float type */
+ public static final int FBT_INDIRECT_FLOAT = 8;
+ /** Represent a map type */
+ public static final int FBT_MAP = 9;
+ /** Represent a vector type */
+ public static final int FBT_VECTOR = 10; // Untyped.
+ /** Represent a vector of signed integers type */
+ public static final int FBT_VECTOR_INT = 11; // Typed any size = stores no type table).
+ /** Represent a vector of unsigned integers type */
+ public static final int FBT_VECTOR_UINT = 12;
+ /** Represent a vector of floats type */
+ public static final int FBT_VECTOR_FLOAT = 13;
+ /** Represent a vector of keys type */
+ public static final int FBT_VECTOR_KEY = 14;
+ /** Represent a vector of strings type */
+ // DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead.
+ // more info on thttps://github.com/google/flatbuffers/issues/5627.
+ public static final int FBT_VECTOR_STRING_DEPRECATED = 15;
+
+ /// @cond FLATBUFFERS_INTERNAL
+ public static final int FBT_VECTOR_INT2 = 16; // Typed tuple = no type table; no size field).
+ public static final int FBT_VECTOR_UINT2 = 17;
+ public static final int FBT_VECTOR_FLOAT2 = 18;
+ public static final int FBT_VECTOR_INT3 = 19; // Typed triple = no type table; no size field).
+ public static final int FBT_VECTOR_UINT3 = 20;
+ public static final int FBT_VECTOR_FLOAT3 = 21;
+ public static final int FBT_VECTOR_INT4 = 22; // Typed quad = no type table; no size field).
+ public static final int FBT_VECTOR_UINT4 = 23;
+ public static final int FBT_VECTOR_FLOAT4 = 24;
+ /// @endcond FLATBUFFERS_INTERNAL
+
+ /** Represent a blob type */
+ public static final int FBT_BLOB = 25;
+ /** Represent a boolean type */
+ public static final int FBT_BOOL = 26;
+ /** Represent a vector of booleans type */
+ public static final int FBT_VECTOR_BOOL = 36; // To Allow the same type of conversion of type to vector type
+
+ private static final ReadBuf EMPTY_BB = new ArrayReadWriteBuf(new byte[] {0}, 1);
+
+ /**
+ * Checks where a type is a typed vector
+ *
+ * @param type type to be checked
+ * @return true if typed vector
+ */
+ static boolean isTypedVector(int type) {
+ return (type >= FBT_VECTOR_INT && type <= FBT_VECTOR_STRING_DEPRECATED) || type == FBT_VECTOR_BOOL;
+ }
+
+ /**
+ * Check whether you can access type directly (no indirection) or not.
+ *
+ * @param type type to be checked
+ * @return true if inline type
+ */
+ static boolean isTypeInline(int type) {
+ return type <= FBT_FLOAT || type == FBT_BOOL;
+ }
+
+ static int toTypedVectorElementType(int original_type) {
+ return original_type - FBT_VECTOR_INT + FBT_INT;
+ }
+
+ /**
+ * Return a vector type our of a original element type
+ *
+ * @param type element type
+ * @param fixedLength size of element
+ * @return typed vector type
+ */
+ static int toTypedVector(int type, int fixedLength) {
+ assert (isTypedVectorElementType(type));
+ switch (fixedLength) {
+ case 0: return type - FBT_INT + FBT_VECTOR_INT;
+ case 2: return type - FBT_INT + FBT_VECTOR_INT2;
+ case 3: return type - FBT_INT + FBT_VECTOR_INT3;
+ case 4: return type - FBT_INT + FBT_VECTOR_INT4;
+ default:
+ assert (false);
+ return FBT_NULL;
+ }
+ }
+
+ static boolean isTypedVectorElementType(int type) {
+ return (type >= FBT_INT && type <= FBT_KEY) || type == FBT_BOOL;
+ }
+
+ // return position of the element that the offset is pointing to
+ private static int indirect(ReadBuf bb, int offset, int byteWidth) {
+ // we assume all offset fits on a int, since ReadBuf operates with that assumption
+ return (int) (offset - readUInt(bb, offset, byteWidth));
+ }
+
+ // read unsigned int with size byteWidth and return as a 64-bit integer
+ private static long readUInt(ReadBuf buff, int end, int byteWidth) {
+ switch (byteWidth) {
+ case 1: return byteToUnsignedInt(buff.get(end));
+ case 2: return shortToUnsignedInt(buff.getShort(end));
+ case 4: return intToUnsignedLong(buff.getInt(end));
+ case 8: return buff.getLong(end); // We are passing signed long here. Losing information (user should know)
+ default: return -1; // we should never reach here
+ }
+ }
+
+ // read signed int of size byteWidth and return as 32-bit int
+ private static int readInt(ReadBuf buff, int end, int byteWidth) {
+ return (int) readLong(buff, end, byteWidth);
+ }
+
+ // read signed int of size byteWidth and return as 64-bit int
+ private static long readLong(ReadBuf buff, int end, int byteWidth) {
+ switch (byteWidth) {
+ case 1: return buff.get(end);
+ case 2: return buff.getShort(end);
+ case 4: return buff.getInt(end);
+ case 8: return buff.getLong(end);
+ default: return -1; // we should never reach here
+ }
+ }
+
+ private static double readDouble(ReadBuf buff, int end, int byteWidth) {
+ switch (byteWidth) {
+ case 4: return buff.getFloat(end);
+ case 8: return buff.getDouble(end);
+ default: return -1; // we should never reach here
+ }
+ }
+
+ /**
+ * Reads a FlexBuffer message in ReadBuf and returns {@link Reference} to
+ * the root element.
+ * @param buffer ReadBuf containing FlexBuffer message
+ * @return {@link Reference} to the root object
+ */
+ @Deprecated
+ public static Reference getRoot(ByteBuffer buffer) {
+ return getRoot( buffer.hasArray() ? new ArrayReadWriteBuf(buffer.array(), buffer.limit()) : new ByteBufferReadWriteBuf(buffer));
+ }
+
+ /**
+ * Reads a FlexBuffer message in ReadBuf and returns {@link Reference} to
+ * the root element.
+ * @param buffer ReadBuf containing FlexBuffer message
+ * @return {@link Reference} to the root object
+ */
+ public static Reference getRoot(ReadBuf buffer) {
+ // See Finish() below for the serialization counterpart of this.
+ // The root ends at the end of the buffer, so we parse backwards from there.
+ int end = buffer.limit();
+ int byteWidth = buffer.get(--end);
+ int packetType = byteToUnsignedInt(buffer.get(--end));
+ end -= byteWidth; // The root data item.
+ return new Reference(buffer, end, byteWidth, packetType);
+ }
+
+ /**
+ * Represents an generic element in the buffer.
+ */
+ public static class Reference {
+
+ private static final Reference NULL_REFERENCE = new Reference(EMPTY_BB, 0, 1, 0);
+ private ReadBuf bb;
+ private int end;
+ private int parentWidth;
+ private int byteWidth;
+ private int type;
+
+ Reference(ReadBuf bb, int end, int parentWidth, int packedType) {
+ this(bb, end, parentWidth, (1 << (packedType & 3)), packedType >> 2);
+ }
+
+ Reference(ReadBuf bb, int end, int parentWidth, int byteWidth, int type) {
+ this.bb = bb;
+ this.end = end;
+ this.parentWidth = parentWidth;
+ this.byteWidth = byteWidth;
+ this.type = type;
+ }
+
+ /**
+ * Return element type
+ * @return element type as integer
+ */
+ public int getType() {
+ return type;
+ }
+
+ /**
+ * Checks whether the element is null type
+ * @return true if null type
+ */
+ public boolean isNull() {
+ return type == FBT_NULL;
+ }
+
+ /**
+ * Checks whether the element is boolean type
+ * @return true if boolean type
+ */
+ public boolean isBoolean() {
+ return type == FBT_BOOL;
+ }
+
+ /**
+ * Checks whether the element type is numeric (signed/unsigned integers and floats)
+ * @return true if numeric type
+ */
+ public boolean isNumeric() {
+ return isIntOrUInt() || isFloat();
+ }
+
+ /**
+ * Checks whether the element type is signed or unsigned integers
+ * @return true if an integer type
+ */
+ public boolean isIntOrUInt() {
+ return isInt() || isUInt();
+ }
+
+ /**
+ * Checks whether the element type is float
+ * @return true if a float type
+ */
+ public boolean isFloat() {
+ return type == FBT_FLOAT || type == FBT_INDIRECT_FLOAT;
+ }
+
+ /**
+ * Checks whether the element type is signed integer
+ * @return true if a signed integer type
+ */
+ public boolean isInt() {
+ return type == FBT_INT || type == FBT_INDIRECT_INT;
+ }
+
+ /**
+ * Checks whether the element type is signed integer
+ * @return true if a signed integer type
+ */
+ public boolean isUInt() {
+ return type == FBT_UINT || type == FBT_INDIRECT_UINT;
+ }
+
+ /**
+ * Checks whether the element type is string
+ * @return true if a string type
+ */
+ public boolean isString() {
+ return type == FBT_STRING;
+ }
+
+ /**
+ * Checks whether the element type is key
+ * @return true if a key type
+ */
+ public boolean isKey() {
+ return type == FBT_KEY;
+ }
+
+ /**
+ * Checks whether the element type is vector
+ * @return true if a vector type
+ */
+ public boolean isVector() {
+ return type == FBT_VECTOR || type == FBT_MAP;
+ }
+
+ /**
+ * Checks whether the element type is typed vector
+ * @return true if a typed vector type
+ */
+ public boolean isTypedVector() {
+ return FlexBuffers.isTypedVector(type);
+ }
+
+ /**
+ * Checks whether the element type is a map
+ * @return true if a map type
+ */
+ public boolean isMap() {
+ return type == FBT_MAP;
+ }
+
+ /**
+ * Checks whether the element type is a blob
+ * @return true if a blob type
+ */
+ public boolean isBlob() {
+ return type == FBT_BLOB;
+ }
+
+ /**
+ * Returns element as 32-bit integer.
+ * <p> For vector element, it will return size of the vector</p>
+ * <p> For String element, it will type to be parsed as integer</p>
+ * <p> Unsigned elements will become negative</p>
+ * <p> Float elements will be casted to integer </p>
+ * @return 32-bit integer or 0 if fail to convert element to integer.
+ */
+ public int asInt() {
+ if (type == FBT_INT) {
+ // A fast path for the common case.
+ return readInt(bb, end, parentWidth);
+ } else
+ switch (type) {
+ case FBT_INDIRECT_INT: return readInt(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_UINT: return (int) readUInt(bb, end, parentWidth);
+ case FBT_INDIRECT_UINT: return (int) readUInt(bb, indirect(bb, end, parentWidth), parentWidth);
+ case FBT_FLOAT: return (int) readDouble(bb, end, parentWidth);
+ case FBT_INDIRECT_FLOAT: return (int) readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_NULL: return 0;
+ case FBT_STRING: return Integer.parseInt(asString());
+ case FBT_VECTOR: return asVector().size();
+ case FBT_BOOL: return readInt(bb, end, parentWidth);
+ default:
+ // Convert other things to int.
+ return 0;
+ }
+ }
+
+ /**
+ * Returns element as unsigned 64-bit integer.
+ * <p> For vector element, it will return size of the vector</p>
+ * <p> For String element, it will type to be parsed as integer</p>
+ * <p> Negative signed elements will become unsigned counterpart</p>
+ * <p> Float elements will be casted to integer </p>
+ * @return 64-bit integer or 0 if fail to convert element to integer.
+ */
+ public long asUInt() {
+ if (type == FBT_UINT) {
+ // A fast path for the common case.
+ return readUInt(bb, end, parentWidth);
+ } else
+ switch (type) {
+ case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_INT: return readLong(bb, end, parentWidth);
+ case FBT_INDIRECT_INT: return readLong(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_FLOAT: return (long) readDouble(bb, end, parentWidth);
+ case FBT_INDIRECT_FLOAT: return (long) readDouble(bb, indirect(bb, end, parentWidth), parentWidth);
+ case FBT_NULL: return 0;
+ case FBT_STRING: return Long.parseLong(asString());
+ case FBT_VECTOR: return asVector().size();
+ case FBT_BOOL: return readInt(bb, end, parentWidth);
+ default:
+ // Convert other things to uint.
+ return 0;
+ }
+ }
+
+ /**
+ * Returns element as 64-bit integer.
+ * <p> For vector element, it will return size of the vector</p>
+ * <p> For String element, it will type to be parsed as integer</p>
+ * <p> Unsigned elements will become negative</p>
+ * <p> Float elements will be casted to integer </p>
+ * @return 64-bit integer or 0 if fail to convert element to long.
+ */
+ public long asLong() {
+ if (type == FBT_INT) {
+ // A fast path for the common case.
+ return readLong(bb, end, parentWidth);
+ } else
+ switch (type) {
+ case FBT_INDIRECT_INT: return readLong(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_UINT: return readUInt(bb, end, parentWidth);
+ case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), parentWidth);
+ case FBT_FLOAT: return (long) readDouble(bb, end, parentWidth);
+ case FBT_INDIRECT_FLOAT: return (long) readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_NULL: return 0;
+ case FBT_STRING: {
+ try {
+ return Long.parseLong(asString());
+ } catch (NumberFormatException nfe) {
+ return 0; //same as C++ implementation
+ }
+ }
+ case FBT_VECTOR: return asVector().size();
+ case FBT_BOOL: return readInt(bb, end, parentWidth);
+ default:
+ // Convert other things to int.
+ return 0;
+ }
+ }
+
+ /**
+ * Returns element as 64-bit integer.
+ * <p> For vector element, it will return size of the vector</p>
+ * <p> For String element, it will type to be parsed as integer</p>
+ * @return 64-bit integer or 0 if fail to convert element to long.
+ */
+ public double asFloat() {
+ if (type == FBT_FLOAT) {
+ // A fast path for the common case.
+ return readDouble(bb, end, parentWidth);
+ } else
+ switch (type) {
+ case FBT_INDIRECT_FLOAT: return readDouble(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_INT: return readInt(bb, end, parentWidth);
+ case FBT_UINT:
+ case FBT_BOOL:
+ return readUInt(bb, end, parentWidth);
+ case FBT_INDIRECT_INT: return readInt(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_INDIRECT_UINT: return readUInt(bb, indirect(bb, end, parentWidth), byteWidth);
+ case FBT_NULL: return 0.0;
+ case FBT_STRING: return Double.parseDouble(asString());
+ case FBT_VECTOR: return asVector().size();
+ default:
+ // Convert strings and other things to float.
+ return 0;
+ }
+ }
+
+ /**
+ * Returns element as a {@link Key}
+ * @return key or {@link Key#empty()} if element is not a key
+ */
+ public Key asKey() {
+ if (isKey()) {
+ return new Key(bb, indirect(bb, end, parentWidth), byteWidth);
+ } else {
+ return Key.empty();
+ }
+ }
+
+ /**
+ * Returns element as a `String`
+ * @return element as `String` or empty `String` if fail
+ */
+ public String asString() {
+ if (isString()) {
+ int start = indirect(bb, end, parentWidth);
+ int size = (int) readUInt(bb, start - byteWidth, byteWidth);
+ return bb.getString(start, size);
+ }
+ else if (isKey()){
+ int start = indirect(bb, end, byteWidth);
+ for (int i = start; ; i++) {
+ if (bb.get(i) == 0) {
+ return bb.getString(start, i - start);
+ }
+ }
+ } else {
+ return "";
+ }
+ }
+
+ /**
+ * Returns element as a {@link Map}
+ * @return element as {@link Map} or empty {@link Map} if fail
+ */
+ public Map asMap() {
+ if (isMap()) {
+ return new Map(bb, indirect(bb, end, parentWidth), byteWidth);
+ } else {
+ return Map.empty();
+ }
+ }
+
+ /**
+ * Returns element as a {@link Vector}
+ * @return element as {@link Vector} or empty {@link Vector} if fail
+ */
+ public Vector asVector() {
+ if (isVector()) {
+ return new Vector(bb, indirect(bb, end, parentWidth), byteWidth);
+ } else if(type == FlexBuffers.FBT_VECTOR_STRING_DEPRECATED) {
+ // deprecated. Should be treated as key vector
+ return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.FBT_KEY);
+ } else if (FlexBuffers.isTypedVector(type)) {
+ return new TypedVector(bb, indirect(bb, end, parentWidth), byteWidth, FlexBuffers.toTypedVectorElementType(type));
+ } else {
+ return Vector.empty();
+ }
+ }
+
+ /**
+ * Returns element as a {@link Blob}
+ * @return element as {@link Blob} or empty {@link Blob} if fail
+ */
+ public Blob asBlob() {
+ if (isBlob() || isString()) {
+ return new Blob(bb, indirect(bb, end, parentWidth), byteWidth);
+ } else {
+ return Blob.empty();
+ }
+ }
+
+ /**
+ * Returns element as a boolean
+ * <p>If element type is not boolean, it will be casted to integer and compared against 0</p>
+ * @return element as boolean
+ */
+ public boolean asBoolean() {
+ if (isBoolean()) {
+ return bb.get(end) != 0;
+ }
+ return asUInt() != 0;
+ }
+
+ /**
+ * Returns text representation of the element (JSON)
+ * @return String containing text representation of the element
+ */
+ @Override
+ public String toString() {
+ return toString(new StringBuilder(128)).toString();
+ }
+
+ /**
+ * Appends a text(JSON) representation to a `StringBuilder`
+ */
+ StringBuilder toString(StringBuilder sb) {
+ //TODO: Original C++ implementation escape strings.
+ // probably we should do it as well.
+ switch (type) {
+ case FBT_NULL:
+ return sb.append("null");
+ case FBT_INT:
+ case FBT_INDIRECT_INT:
+ return sb.append(asLong());
+ case FBT_UINT:
+ case FBT_INDIRECT_UINT:
+ return sb.append(asUInt());
+ case FBT_INDIRECT_FLOAT:
+ case FBT_FLOAT:
+ return sb.append(asFloat());
+ case FBT_KEY:
+ return asKey().toString(sb.append('"')).append('"');
+ case FBT_STRING:
+ return sb.append('"').append(asString()).append('"');
+ case FBT_MAP:
+ return asMap().toString(sb);
+ case FBT_VECTOR:
+ return asVector().toString(sb);
+ case FBT_BLOB:
+ return asBlob().toString(sb);
+ case FBT_BOOL:
+ return sb.append(asBoolean());
+ case FBT_VECTOR_INT:
+ case FBT_VECTOR_UINT:
+ case FBT_VECTOR_FLOAT:
+ case FBT_VECTOR_KEY:
+ case FBT_VECTOR_STRING_DEPRECATED:
+ case FBT_VECTOR_BOOL:
+ return sb.append(asVector());
+ case FBT_VECTOR_INT2:
+ case FBT_VECTOR_UINT2:
+ case FBT_VECTOR_FLOAT2:
+ case FBT_VECTOR_INT3:
+ case FBT_VECTOR_UINT3:
+ case FBT_VECTOR_FLOAT3:
+ case FBT_VECTOR_INT4:
+ case FBT_VECTOR_UINT4:
+ case FBT_VECTOR_FLOAT4:
+
+ throw new FlexBufferException("not_implemented:" + type);
+ default:
+ return sb;
+ }
+ }
+ }
+
+ /**
+ * Base class of all types below.
+ * Points into the data buffer and allows access to one type.
+ */
+ private static abstract class Object {
+ ReadBuf bb;
+ int end;
+ int byteWidth;
+
+ Object(ReadBuf buff, int end, int byteWidth) {
+ this.bb = buff;
+ this.end = end;
+ this.byteWidth = byteWidth;
+ }
+
+ @Override
+ public String toString() {
+ return toString(new StringBuilder(128)).toString();
+ }
+
+ public abstract StringBuilder toString(StringBuilder sb);
+ }
+
+ // Stores size in `byte_width_` bytes before end position.
+ private static abstract class Sized extends Object {
+
+ protected final int size;
+
+ Sized(ReadBuf buff, int end, int byteWidth) {
+ super(buff, end, byteWidth);
+ size = readInt(bb, end - byteWidth, byteWidth);
+ }
+
+ public int size() {
+ return size;
+ }
+ }
+
+ /**
+ * Represents a array of bytes element in the buffer
+ *
+ * <p>It can be converted to `ReadBuf` using {@link data()},
+ * copied into a byte[] using {@link getBytes()} or
+ * have individual bytes accessed individually using {@link get(int)}</p>
+ */
+ public static class Blob extends Sized {
+ static final Blob EMPTY = new Blob(EMPTY_BB, 1, 1);
+
+ Blob(ReadBuf buff, int end, int byteWidth) {
+ super(buff, end, byteWidth);
+ }
+
+ /** Return an empty {@link Blob} */
+ public static Blob empty() {
+ return EMPTY;
+ }
+
+ /**
+ * Return {@link Blob} as `ReadBuf`
+ * @return blob as `ReadBuf`
+ */
+ public ByteBuffer data() {
+ ByteBuffer dup = ByteBuffer.wrap(bb.data());
+ dup.position(end);
+ dup.limit(end + size());
+ return dup.asReadOnlyBuffer().slice();
+ }
+
+ /**
+ * Copy blob into a byte[]
+ * @return blob as a byte[]
+ */
+ public byte[] getBytes() {
+ int size = size();
+ byte[] result = new byte[size];
+ for (int i = 0; i < size; i++) {
+ result[i] = bb.get(end + i);
+ }
+ return result;
+ }
+
+ /**
+ * Return individual byte at a given position
+ * @param pos position of the byte to be read
+ */
+ public byte get(int pos) {
+ assert pos >=0 && pos <= size();
+ return bb.get(end + pos);
+ }
+
+ /**
+ * Returns a text(JSON) representation of the {@link Blob}
+ */
+ @Override
+ public String toString() {
+ return bb.getString(end, size());
+ }
+
+ /**
+ * Append a text(JSON) representation of the {@link Blob} into a `StringBuilder`
+ */
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append('"');
+ sb.append(bb.getString(end, size()));
+ return sb.append('"');
+ }
+ }
+
+ /**
+ * Represents a key element in the buffer. Keys are
+ * used to reference objects in a {@link Map}
+ */
+ public static class Key extends Object {
+
+ private static final Key EMPTY = new Key(EMPTY_BB, 0, 0);
+
+ Key(ReadBuf buff, int end, int byteWidth) {
+ super(buff, end, byteWidth);
+ }
+
+ /**
+ * Return an empty {@link Key}
+ * @return empty {@link Key}
+ * */
+ public static Key empty() {
+ return Key.EMPTY;
+ }
+
+ /**
+ * Appends a text(JSON) representation to a `StringBuilder`
+ */
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ return sb.append(toString());
+ }
+
+ @Override
+ public String toString() {
+ int size;
+ for (int i = end; ; i++) {
+ if (bb.get(i) == 0) {
+ size = i - end;
+ break;
+ }
+ }
+ return bb.getString(end, size);
+ }
+
+ int compareTo(byte[] other) {
+ int ia = end;
+ int io = 0;
+ byte c1, c2;
+ do {
+ c1 = bb.get(ia);
+ c2 = other[io];
+ if (c1 == '\0')
+ return c1 - c2;
+ ia++;
+ io++;
+ if (io == other.length) {
+ // in our buffer we have an additional \0 byte
+ // but this does not exist in regular Java strings, so we return now
+ return c1 - c2;
+ }
+ }
+ while (c1 == c2);
+ return c1 - c2;
+ }
+
+ /**
+ * Compare keys
+ * @param obj other key to compare
+ * @return true if keys are the same
+ */
+ @Override
+ public boolean equals(java.lang.Object obj) {
+ if (!(obj instanceof Key))
+ return false;
+
+ return ((Key) obj).end == end && ((Key) obj).byteWidth == byteWidth;
+ }
+
+ public int hashCode() {
+ return end ^ byteWidth;
+ }
+ }
+
+ /**
+ * Map object representing a set of key-value pairs.
+ */
+ public static class Map extends Vector {
+ private static final Map EMPTY_MAP = new Map(EMPTY_BB, 1, 1);
+
+ Map(ReadBuf bb, int end, int byteWidth) {
+ super(bb, end, byteWidth);
+ }
+
+ /**
+ * Returns an empty {@link Map}
+ * @return an empty {@link Map}
+ */
+ public static Map empty() {
+ return EMPTY_MAP;
+ }
+
+ /**
+ * @param key access key to element on map
+ * @return reference to value in map
+ */
+ public Reference get(String key) {
+ return get(key.getBytes(StandardCharsets.UTF_8));
+ }
+
+ /**
+ * @param key access key to element on map. Keys are assumed to be encoded in UTF-8
+ * @return reference to value in map
+ */
+ public Reference get(byte[] key) {
+ KeyVector keys = keys();
+ int size = keys.size();
+ int index = binarySearch(keys, key);
+ if (index >= 0 && index < size) {
+ return get(index);
+ }
+ return Reference.NULL_REFERENCE;
+ }
+
+ /**
+ * Get a vector or keys in the map
+ *
+ * @return vector of keys
+ */
+ public KeyVector keys() {
+ final int num_prefixed_fields = 3;
+ int keysOffset = end - (byteWidth * num_prefixed_fields);
+ return new KeyVector(new TypedVector(bb,
+ indirect(bb, keysOffset, byteWidth),
+ readInt(bb, keysOffset + byteWidth, byteWidth),
+ FBT_KEY));
+ }
+
+ /**
+ * @return {@code Vector} of values from map
+ */
+ public Vector values() {
+ return new Vector(bb, end, byteWidth);
+ }
+
+ /**
+ * Writes text (json) representation of map in a {@code StringBuilder}.
+ *
+ * @param builder {@code StringBuilder} to be appended to
+ * @return Same {@code StringBuilder} with appended text
+ */
+ public StringBuilder toString(StringBuilder builder) {
+ builder.append("{ ");
+ KeyVector keys = keys();
+ int size = size();
+ Vector vals = values();
+ for (int i = 0; i < size; i++) {
+ builder.append('"')
+ .append(keys.get(i).toString())
+ .append("\" : ");
+ builder.append(vals.get(i).toString());
+ if (i != size - 1)
+ builder.append(", ");
+ }
+ builder.append(" }");
+ return builder;
+ }
+
+ // Performs a binary search on a key vector and return index of the key in key vector
+ private int binarySearch(KeyVector keys, byte[] searchedKey) {
+ int low = 0;
+ int high = keys.size() - 1;
+
+ while (low <= high) {
+ int mid = (low + high) >>> 1;
+ Key k = keys.get(mid);
+ int cmp = k.compareTo(searchedKey);
+ if (cmp < 0)
+ low = mid + 1;
+ else if (cmp > 0)
+ high = mid - 1;
+ else
+ return mid; // key found
+ }
+ return -(low + 1); // key not found
+ }
+ }
+
+ /**
+ * Object that represents a set of elements in the buffer
+ */
+ public static class Vector extends Sized {
+
+ private static final Vector EMPTY_VECTOR = new Vector(EMPTY_BB, 1, 1);
+
+ Vector(ReadBuf bb, int end, int byteWidth) {
+ super(bb, end, byteWidth);
+ }
+
+ /**
+ * Returns an empty {@link Map}
+ * @return an empty {@link Map}
+ */
+ public static Vector empty() {
+ return EMPTY_VECTOR;
+ }
+
+ /**
+ * Checks if the vector is empty
+ * @return true if vector is empty
+ */
+ public boolean isEmpty() {
+ return this == EMPTY_VECTOR;
+ }
+
+ /**
+ * Appends a text(JSON) representation to a `StringBuilder`
+ */
+ @Override
+ public StringBuilder toString(StringBuilder sb) {
+ sb.append("[ ");
+ int size = size();
+ for (int i = 0; i < size; i++) {
+ get(i).toString(sb);
+ if (i != size - 1) {
+ sb.append(", ");
+ }
+ }
+ sb.append(" ]");
+ return sb;
+ }
+
+ /**
+ * Get a element in a vector by index
+ *
+ * @param index position of the element
+ * @return {@code Reference} to the element
+ */
+ public Reference get(int index) {
+ long len = size();
+ if (index >= len) {
+ return Reference.NULL_REFERENCE;
+ }
+ int packedType = byteToUnsignedInt(bb.get((int) (end + (len * byteWidth) + index)));
+ int obj_end = end + index * byteWidth;
+ return new Reference(bb, obj_end, byteWidth, packedType);
+ }
+ }
+
+ /**
+ * Object that represents a set of elements with the same type
+ */
+ public static class TypedVector extends Vector {
+
+ private static final TypedVector EMPTY_VECTOR = new TypedVector(EMPTY_BB, 1, 1, FBT_INT);
+
+ private final int elemType;
+
+ TypedVector(ReadBuf bb, int end, int byteWidth, int elemType) {
+ super(bb, end, byteWidth);
+ this.elemType = elemType;
+ }
+
+ public static TypedVector empty() {
+ return EMPTY_VECTOR;
+ }
+
+ /**
+ * Returns whether the vector is empty
+ *
+ * @return true if empty
+ */
+ public boolean isEmptyVector() {
+ return this == EMPTY_VECTOR;
+ }
+
+ /**
+ * Return element type for all elements in the vector
+ *
+ * @return element type
+ */
+ public int getElemType() {
+ return elemType;
+ }
+
+ /**
+ * Get reference to an object in the {@code Vector}
+ *
+ * @param pos position of the object in {@code Vector}
+ * @return reference to element
+ */
+ @Override
+ public Reference get(int pos) {
+ int len = size();
+ if (pos >= len) return Reference.NULL_REFERENCE;
+ int childPos = end + pos * byteWidth;
+ return new Reference(bb, childPos, byteWidth, 1, elemType);
+ }
+ }
+
+ /**
+ * Represent a vector of keys in a map
+ */
+ public static class KeyVector {
+
+ private final TypedVector vec;
+
+ KeyVector(TypedVector vec) {
+ this.vec = vec;
+ }
+
+ /**
+ * Return key
+ *
+ * @param pos position of the key in key vector
+ * @return key
+ */
+ public Key get(int pos) {
+ int len = size();
+ if (pos >= len) return Key.EMPTY;
+ int childPos = vec.end + pos * vec.byteWidth;
+ return new Key(vec.bb, indirect(vec.bb, childPos, vec.byteWidth), 1);
+ }
+
+ /**
+ * Returns size of key vector
+ *
+ * @return size
+ */
+ public int size() {
+ return vec.size();
+ }
+
+ /**
+ * Returns a text(JSON) representation
+ */
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append('[');
+ for (int i = 0; i < vec.size(); i++) {
+ vec.get(i).toString(b);
+ if (i != vec.size() - 1) {
+ b.append(", ");
+ }
+ }
+ return b.append("]").toString();
+ }
+ }
+
+ public static class FlexBufferException extends RuntimeException {
+ FlexBufferException(String msg) {
+ super(msg);
+ }
+ }
+
+ static class Unsigned {
+
+ static int byteToUnsignedInt(byte x) {
+ return ((int) x) & 0xff;
+ }
+
+ static int shortToUnsignedInt(short x) {
+ return ((int) x) & 0xffff;
+ }
+
+ static long intToUnsignedLong(int x) {
+ return ((long) x) & 0xffffffffL;
+ }
+ }
+}
+/// @}
diff --git a/java/com/google/flatbuffers/FlexBuffersBuilder.java b/java/com/google/flatbuffers/FlexBuffersBuilder.java
new file mode 100644
index 00000000..cb44492a
--- /dev/null
+++ b/java/com/google/flatbuffers/FlexBuffersBuilder.java
@@ -0,0 +1,770 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+
+import static com.google.flatbuffers.FlexBuffers.*;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
+import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
+
+/// @file
+/// @addtogroup flatbuffers_java_api
+/// @{
+
+/**
+ * Helper class that builds FlexBuffers
+ * <p> This class presents all necessary APIs to create FlexBuffers. A `ByteBuffer` will be used to store the
+ * data. It can be created internally, or passed down in the constructor.</p>
+ *
+ * <p>There are some limitations when compared to original implementation in C++. Most notably:
+ * <ul>
+ * <li><p> No support for mutations (might change in the future).</p></li>
+ * <li><p> Buffer size limited to {@link Integer#MAX_VALUE}</p></li>
+ * <li><p> Since Java does not support unsigned type, all unsigned operations accepts an immediate higher representation
+ * of similar type.</p></li>
+ * </ul>
+ * </p>
+ */
+public class FlexBuffersBuilder {
+
+ /**
+ * No keys or strings will be shared
+ */
+ public static final int BUILDER_FLAG_NONE = 0;
+ /**
+ * Keys will be shared between elements. Identical keys will only be serialized once, thus possibly saving space.
+ * But serialization performance might be slower and consumes more memory.
+ */
+ public static final int BUILDER_FLAG_SHARE_KEYS = 1;
+ /**
+ * Strings will be shared between elements. Identical strings will only be serialized once, thus possibly saving space.
+ * But serialization performance might be slower and consumes more memory. This is ideal if you expect many repeated
+ * strings on the message.
+ */
+ public static final int BUILDER_FLAG_SHARE_STRINGS = 2;
+ /**
+ * Strings and keys will be shared between elements.
+ */
+ public static final int BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3;
+ /**
+ * Reserved for the future.
+ */
+ public static final int BUILDER_FLAG_SHARE_KEY_VECTORS = 4;
+ /**
+ * Reserved for the future.
+ */
+ public static final int BUILDER_FLAG_SHARE_ALL = 7;
+
+ /// @cond FLATBUFFERS_INTERNAL
+ private static final int WIDTH_8 = 0;
+ private static final int WIDTH_16 = 1;
+ private static final int WIDTH_32 = 2;
+ private static final int WIDTH_64 = 3;
+ private final ReadWriteBuf bb;
+ private final ArrayList<Value> stack = new ArrayList<>();
+ private final HashMap<String, Integer> keyPool = new HashMap<>();
+ private final HashMap<String, Integer> stringPool = new HashMap<>();
+ private final int flags;
+ private boolean finished = false;
+
+ // A lambda to sort map keys
+ private Comparator<Value> keyComparator = new Comparator<Value>() {
+ @Override
+ public int compare(Value o1, Value o2) {
+ int ia = o1.key;
+ int io = o2.key;
+ byte c1, c2;
+ do {
+ c1 = bb.get(ia);
+ c2 = bb.get(io);
+ if (c1 == 0)
+ return c1 - c2;
+ ia++;
+ io++;
+ }
+ while (c1 == c2);
+ return c1 - c2;
+ }
+ };
+ /// @endcond
+
+ /**
+ * Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set.
+ * @param bufSize size of buffer in bytes.
+ */
+ public FlexBuffersBuilder(int bufSize) {
+ this(new ArrayReadWriteBuf(bufSize), BUILDER_FLAG_SHARE_KEYS);
+ }
+
+ /**
+ * Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set.
+ */
+ public FlexBuffersBuilder() {
+ this(256);
+ }
+
+ /**
+ * Constructs a newly allocated {@code FlexBuffersBuilder}.
+ *
+ * @param bb `ByteBuffer` that will hold the message
+ * @param flags Share flags
+ */
+ @Deprecated
+ public FlexBuffersBuilder(ByteBuffer bb, int flags) {
+ this(new ArrayReadWriteBuf(bb.array()), flags);
+ }
+
+ public FlexBuffersBuilder(ReadWriteBuf bb, int flags) {
+ this.bb = bb;
+ this.flags = flags;
+ }
+
+ /**
+ * Constructs a newly allocated {@code FlexBuffersBuilder}.
+ * By default same keys will be serialized only once
+ * @param bb `ByteBuffer` that will hold the message
+ */
+ public FlexBuffersBuilder(ByteBuffer bb) {
+ this(bb, BUILDER_FLAG_SHARE_KEYS);
+ }
+
+ /**
+ * Return `ByteBuffer` containing FlexBuffer message. {@code #finish()} must be called before calling this
+ * function otherwise an assert will trigger.
+ *
+ * @return `ByteBuffer` with finished message
+ */
+ public ReadWriteBuf getBuffer() {
+ assert (finished);
+ return bb;
+ }
+
+ /**
+ * Insert a single boolean into the buffer
+ * @param val true or false
+ */
+ public void putBoolean(boolean val) {
+ putBoolean(null, val);
+ }
+
+ /**
+ * Insert a single boolean into the buffer
+ * @param key key used to store element in map
+ * @param val true or false
+ */
+ public void putBoolean(String key, boolean val) {
+ stack.add(Value.bool(putKey(key), val));
+ }
+
+ private int putKey(String key) {
+ if (key == null) {
+ return -1;
+ }
+ int pos = bb.writePosition();
+ if ((flags & BUILDER_FLAG_SHARE_KEYS) != 0) {
+ Integer keyFromPool = keyPool.get(key);
+ if (keyFromPool == null) {
+ byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
+ bb.put(keyBytes, 0, keyBytes.length);
+ bb.put((byte) 0);
+ keyPool.put(key, pos);
+ } else {
+ pos = keyFromPool;
+ }
+ } else {
+ byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
+ bb.put(keyBytes, 0, keyBytes.length);
+ bb.put((byte) 0);
+ keyPool.put(key, pos);
+ }
+ return pos;
+ }
+
+ /**
+ * Adds a integer into the buff
+ * @param val integer
+ */
+ public void putInt(int val) {
+ putInt(null, val);
+ }
+
+ /**
+ * Adds a integer into the buff
+ * @param key key used to store element in map
+ * @param val integer
+ */
+ public void putInt(String key, int val) {
+ putInt(key, (long) val);
+ }
+
+ /**
+ * Adds a integer into the buff
+ * @param key key used to store element in map
+ * @param val 64-bit integer
+ */
+ public void putInt(String key, long val) {
+ int iKey = putKey(key);
+ if (Byte.MIN_VALUE <= val && val <= Byte.MAX_VALUE) {
+ stack.add(Value.int8(iKey, (int) val));
+ } else if (Short.MIN_VALUE <= val && val <= Short.MAX_VALUE) {
+ stack.add(Value.int16(iKey, (int) val));
+ } else if (Integer.MIN_VALUE <= val && val <= Integer.MAX_VALUE) {
+ stack.add(Value.int32(iKey, (int) val));
+ } else {
+ stack.add(Value.int64(iKey, val));
+ }
+ }
+
+ /**
+ * Adds a 64-bit integer into the buff
+ * @param value integer
+ */
+ public void putInt(long value) {
+ putInt(null, value);
+ }
+
+ /**
+ * Adds a unsigned integer into the buff.
+ * @param value integer representing unsigned value
+ */
+ public void putUInt(int value) {
+ putUInt(null, (long) value);
+ }
+
+ /**
+ * Adds a unsigned integer (stored in a signed 64-bit integer) into the buff.
+ * @param value integer representing unsigned value
+ */
+ public void putUInt(long value) {
+ putUInt(null, value);
+ }
+
+ /**
+ * Adds a 64-bit unsigned integer (stored as {@link BigInteger}) into the buff.
+ * Warning: This operation might be very slow.
+ * @param value integer representing unsigned value
+ */
+ public void putUInt64(BigInteger value) {
+ putUInt64(null, value.longValue());
+ }
+
+ private void putUInt64(String key, long value) {
+ stack.add(Value.uInt64(putKey(key), value));
+ }
+
+ private void putUInt(String key, long value) {
+ int iKey = putKey(key);
+ Value vVal;
+
+ int width = widthUInBits(value);
+
+ if (width == WIDTH_8) {
+ vVal = Value.uInt8(iKey, (int)value);
+ } else if (width == WIDTH_16) {
+ vVal = Value.uInt16(iKey, (int)value);
+ } else if (width == WIDTH_32) {
+ vVal = Value.uInt32(iKey, (int)value);
+ } else {
+ vVal = Value.uInt64(iKey, value);
+ }
+ stack.add(vVal);
+ }
+
+ /**
+ * Adds a 32-bit float into the buff.
+ * @param value float representing value
+ */
+ public void putFloat(float value) {
+ putFloat(null, value);
+ }
+
+ /**
+ * Adds a 32-bit float into the buff.
+ * @param key key used to store element in map
+ * @param value float representing value
+ */
+ public void putFloat(String key, float val) {
+ stack.add(Value.float32(putKey(key), val));
+ }
+
+ /**
+ * Adds a 64-bit float into the buff.
+ * @param value float representing value
+ */
+ public void putFloat(double value) {
+ putFloat(null, value);
+ }
+
+ /**
+ * Adds a 64-bit float into the buff.
+ * @param key key used to store element in map
+ * @param value float representing value
+ */
+ public void putFloat(String key, double val) {
+ stack.add(Value.float64(putKey(key), val));
+ }
+
+ /**
+ * Adds a String into the buffer
+ * @param value string
+ * @return start position of string in the buffer
+ */
+ public int putString(String value) {
+ return putString(null, value);
+ }
+
+ /**
+ * Adds a String into the buffer
+ * @param key key used to store element in map
+ * @param value string
+ * @return start position of string in the buffer
+ */
+ public int putString(String key, String val) {
+ int iKey = putKey(key);
+ if ((flags & FlexBuffersBuilder.BUILDER_FLAG_SHARE_STRINGS) != 0) {
+ Integer i = stringPool.get(val);
+ if (i == null) {
+ Value value = writeString(iKey, val);
+ stringPool.put(val, (int) value.iValue);
+ stack.add(value);
+ return (int) value.iValue;
+ } else {
+ int bitWidth = widthUInBits(val.length());
+ stack.add(Value.blob(iKey, i, FBT_STRING, bitWidth));
+ return i;
+ }
+ } else {
+ Value value = writeString(iKey, val);
+ stack.add(value);
+ return (int) value.iValue;
+ }
+ }
+
+ private Value writeString(int key, String s) {
+ return writeBlob(key, s.getBytes(StandardCharsets.UTF_8), FBT_STRING, true);
+ }
+
+ // in bits to fit a unsigned int
+ static int widthUInBits(long len) {
+ if (len <= byteToUnsignedInt((byte)0xff)) return WIDTH_8;
+ if (len <= shortToUnsignedInt((short)0xffff)) return WIDTH_16;
+ if (len <= intToUnsignedLong(0xffff_ffff)) return WIDTH_32;
+ return WIDTH_64;
+ }
+
+ private Value writeBlob(int key, byte[] blob, int type, boolean trailing) {
+ int bitWidth = widthUInBits(blob.length);
+ int byteWidth = align(bitWidth);
+ writeInt(blob.length, byteWidth);
+ int sloc = bb.writePosition();
+ bb.put(blob, 0, blob.length);
+ if (trailing) {
+ bb.put((byte) 0);
+ }
+ return Value.blob(key, sloc, type, bitWidth);
+ }
+
+ // Align to prepare for writing a scalar with a certain size.
+ private int align(int alignment) {
+ int byteWidth = 1 << alignment;
+ int padBytes = Value.paddingBytes(bb.writePosition(), byteWidth);
+ while (padBytes-- != 0) {
+ bb.put((byte) 0);
+ }
+ return byteWidth;
+ }
+
+ private void writeInt(long value, int byteWidth) {
+ switch (byteWidth) {
+ case 1: bb.put((byte) value); break;
+ case 2: bb.putShort((short) value); break;
+ case 4: bb.putInt((int) value); break;
+ case 8: bb.putLong(value); break;
+ }
+ }
+
+ /**
+ * Adds a byte array into the message
+ * @param value byte array
+ * @return position in buffer as the start of byte array
+ */
+ public int putBlob(byte[] value) {
+ return putBlob(null, value);
+ }
+
+ /**
+ * Adds a byte array into the message
+ * @param key key used to store element in map
+ * @param value byte array
+ * @return position in buffer as the start of byte array
+ */
+ public int putBlob(String key, byte[] val) {
+ int iKey = putKey(key);
+ Value value = writeBlob(iKey, val, FBT_BLOB, false);
+ stack.add(value);
+ return (int) value.iValue;
+ }
+
+ /**
+ * Start a new vector in the buffer.
+ * @return a reference indicating position of the vector in buffer. This
+ * reference must be passed along when the vector is finished using endVector()
+ */
+ public int startVector() {
+ return stack.size();
+ }
+
+ /**
+ * Finishes a vector, but writing the information in the buffer
+ * @param key key used to store element in map
+ * @param start reference for begining of the vector. Returned by {@link startVector()}
+ * @param typed boolean indicating wether vector is typed
+ * @param fixed boolean indicating wether vector is fixed
+ * @return Reference to the vector
+ */
+ public int endVector(String key, int start, boolean typed, boolean fixed) {
+ int iKey = putKey(key);
+ Value vec = createVector(iKey, start, stack.size() - start, typed, fixed, null);
+ // Remove temp elements and return vector.
+ while (stack.size() > start) {
+ stack.remove(stack.size() - 1);
+ }
+ stack.add(vec);
+ return (int) vec.iValue;
+ }
+
+ /**
+ * Finish writing the message into the buffer. After that no other element must
+ * be inserted into the buffer. Also, you must call this function before start using the
+ * FlexBuffer message
+ * @return `ByteBuffer` containing the FlexBuffer message
+ */
+ public ByteBuffer finish() {
+ // If you hit this assert, you likely have objects that were never included
+ // in a parent. You need to have exactly one root to finish a buffer.
+ // Check your Start/End calls are matched, and all objects are inside
+ // some other object.
+ assert (stack.size() == 1);
+ // Write root value.
+ int byteWidth = align(stack.get(0).elemWidth(bb.writePosition(), 0));
+ writeAny(stack.get(0), byteWidth);
+ // Write root type.
+ bb.put(stack.get(0).storedPackedType());
+ // Write root size. Normally determined by parent, but root has no parent :)
+ bb.put((byte) byteWidth);
+ this.finished = true;
+ return ByteBuffer.wrap(bb.data(), 0, bb.writePosition());
+ }
+
+ /*
+ * Create a vector based on the elements stored in the stack
+ *
+ * @param key reference to its key
+ * @param start element in the stack
+ * @param length size of the vector
+ * @param typed whether is TypedVector or not
+ * @param fixed whether is Fixed vector or not
+ * @param keys Value representing key vector
+ * @return Value representing the created vector
+ */
+ private Value createVector(int key, int start, int length, boolean typed, boolean fixed, Value keys) {
+ assert (!fixed || typed); // typed=false, fixed=true combination is not supported.
+ // Figure out smallest bit width we can store this vector with.
+ int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
+ int prefixElems = 1;
+ if (keys != null) {
+ // If this vector is part of a map, we will pre-fix an offset to the keys
+ // to this vector.
+ bitWidth = Math.max(bitWidth, keys.elemWidth(bb.writePosition(), 0));
+ prefixElems += 2;
+ }
+ int vectorType = FBT_KEY;
+ // Check bit widths and types for all elements.
+ for (int i = start; i < stack.size(); i++) {
+ int elemWidth = stack.get(i).elemWidth(bb.writePosition(), i + prefixElems);
+ bitWidth = Math.max(bitWidth, elemWidth);
+ if (typed) {
+ if (i == start) {
+ vectorType = stack.get(i).type;
+ if (!FlexBuffers.isTypedVectorElementType(vectorType)) {
+ throw new FlexBufferException("TypedVector does not support this element type");
+ }
+ } else {
+ // If you get this assert, you are writing a typed vector with
+ // elements that are not all the same type.
+ assert (vectorType == stack.get(i).type);
+ }
+ }
+ }
+ // If you get this assert, your fixed types are not one of:
+ // Int / UInt / Float / Key.
+ assert (!fixed || FlexBuffers.isTypedVectorElementType(vectorType));
+
+ int byteWidth = align(bitWidth);
+ // Write vector. First the keys width/offset if available, and size.
+ if (keys != null) {
+ writeOffset(keys.iValue, byteWidth);
+ writeInt(1L << keys.minBitWidth, byteWidth);
+ }
+ if (!fixed) {
+ writeInt(length, byteWidth);
+ }
+ // Then the actual data.
+ int vloc = bb.writePosition();
+ for (int i = start; i < stack.size(); i++) {
+ writeAny(stack.get(i), byteWidth);
+ }
+ // Then the types.
+ if (!typed) {
+ for (int i = start; i < stack.size(); i++) {
+ bb.put(stack.get(i).storedPackedType(bitWidth));
+ }
+ }
+ return new Value(key, keys != null ? FBT_MAP
+ : (typed ? FlexBuffers.toTypedVector(vectorType, fixed ? length : 0)
+ : FBT_VECTOR), bitWidth, vloc);
+ }
+
+ private void writeOffset(long val, int byteWidth) {
+ int reloff = (int) (bb.writePosition() - val);
+ assert (byteWidth == 8 || reloff < 1L << (byteWidth * 8));
+ writeInt(reloff, byteWidth);
+ }
+
+ private void writeAny(final Value val, int byteWidth) {
+ switch (val.type) {
+ case FBT_NULL:
+ case FBT_BOOL:
+ case FBT_INT:
+ case FBT_UINT:
+ writeInt(val.iValue, byteWidth);
+ break;
+ case FBT_FLOAT:
+ writeDouble(val.dValue, byteWidth);
+ break;
+ default:
+ writeOffset(val.iValue, byteWidth);
+ break;
+ }
+ }
+
+ private void writeDouble(double val, int byteWidth) {
+ if (byteWidth == 4) {
+ bb.putFloat((float) val);
+ } else if (byteWidth == 8) {
+ bb.putDouble(val);
+ }
+ }
+
+ /**
+ * Start a new map in the buffer.
+ * @return a reference indicating position of the map in buffer. This
+ * reference must be passed along when the map is finished using endMap()
+ */
+ public int startMap() {
+ return stack.size();
+ }
+
+ /**
+ * Finishes a map, but writing the information in the buffer
+ * @param key key used to store element in map
+ * @param start reference for begining of the map. Returned by {@link startMap()}
+ * @return Reference to the map
+ */
+ public int endMap(String key, int start) {
+ int iKey = putKey(key);
+
+ Collections.sort(stack.subList(start, stack.size()), keyComparator);
+
+ Value keys = createKeyVector(start, stack.size() - start);
+ Value vec = createVector(iKey, start, stack.size() - start, false, false, keys);
+ // Remove temp elements and return map.
+ while (stack.size() > start) {
+ stack.remove(stack.size() - 1);
+ }
+ stack.add(vec);
+ return (int) vec.iValue;
+ }
+
+ private Value createKeyVector(int start, int length) {
+ // Figure out smallest bit width we can store this vector with.
+ int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
+ int prefixElems = 1;
+ // Check bit widths and types for all elements.
+ for (int i = start; i < stack.size(); i++) {
+ int elemWidth = Value.elemWidth(FBT_KEY, WIDTH_8, stack.get(i).key, bb.writePosition(), i + prefixElems);
+ bitWidth = Math.max(bitWidth, elemWidth);
+ }
+
+ int byteWidth = align(bitWidth);
+ // Write vector. First the keys width/offset if available, and size.
+ writeInt(length, byteWidth);
+ // Then the actual data.
+ int vloc = bb.writePosition();
+ for (int i = start; i < stack.size(); i++) {
+ int pos = stack.get(i).key;
+ assert(pos != -1);
+ writeOffset(stack.get(i).key, byteWidth);
+ }
+ // Then the types.
+ return new Value(-1, FlexBuffers.toTypedVector(FBT_KEY,0), bitWidth, vloc);
+ }
+
+ private static class Value {
+ final int type;
+ // for scalars, represents scalar size in bytes
+ // for vectors, represents the size
+ // for string, length
+ final int minBitWidth;
+ // float value
+ final double dValue;
+ // integer value
+ long iValue;
+ // position of the key associated with this value in buffer
+ int key;
+
+ Value(int key, int type, int bitWidth, long iValue) {
+ this.key = key;
+ this.type = type;
+ this.minBitWidth = bitWidth;
+ this.iValue = iValue;
+ this.dValue = Double.MIN_VALUE;
+ }
+
+ Value(int key, int type, int bitWidth, double dValue) {
+ this.key = key;
+ this.type = type;
+ this.minBitWidth = bitWidth;
+ this.dValue = dValue;
+ this.iValue = Long.MIN_VALUE;
+ }
+
+ static Value bool(int key, boolean b) {
+ return new Value(key, FBT_BOOL, WIDTH_8, b ? 1 : 0);
+ }
+
+ static Value blob(int key, int position, int type, int bitWidth) {
+ return new Value(key, type, bitWidth, position);
+ }
+
+ static Value int8(int key, int value) {
+ return new Value(key, FBT_INT, WIDTH_8, value);
+ }
+
+ static Value int16(int key, int value) {
+ return new Value(key, FBT_INT, WIDTH_16, value);
+ }
+
+ static Value int32(int key, int value) {
+ return new Value(key, FBT_INT, WIDTH_32, value);
+ }
+
+ static Value int64(int key, long value) {
+ return new Value(key, FBT_INT, WIDTH_64, value);
+ }
+
+ static Value uInt8(int key, int value) {
+ return new Value(key, FBT_UINT, WIDTH_8, value);
+ }
+
+ static Value uInt16(int key, int value) {
+ return new Value(key, FBT_UINT, WIDTH_16, value);
+ }
+
+ static Value uInt32(int key, int value) {
+ return new Value(key, FBT_UINT, WIDTH_32, value);
+ }
+
+ static Value uInt64(int key, long value) {
+ return new Value(key, FBT_UINT, WIDTH_64, value);
+ }
+
+ static Value float32(int key, float value) {
+ return new Value(key, FBT_FLOAT, WIDTH_32, value);
+ }
+
+ static Value float64(int key, double value) {
+ return new Value(key, FBT_FLOAT, WIDTH_64, value);
+ }
+
+ private byte storedPackedType() {
+ return storedPackedType(WIDTH_8);
+ }
+
+ private byte storedPackedType(int parentBitWidth) {
+ return packedType(storedWidth(parentBitWidth), type);
+ }
+
+ private static byte packedType(int bitWidth, int type) {
+ return (byte) (bitWidth | (type << 2));
+ }
+
+ private int storedWidth(int parentBitWidth) {
+ if (FlexBuffers.isTypeInline(type)) {
+ return Math.max(minBitWidth, parentBitWidth);
+ } else {
+ return minBitWidth;
+ }
+ }
+
+ private int elemWidth(int bufSize, int elemIndex) {
+ return elemWidth(type, minBitWidth, iValue, bufSize, elemIndex);
+ }
+
+ private static int elemWidth(int type, int minBitWidth, long iValue, int bufSize, int elemIndex) {
+ if (FlexBuffers.isTypeInline(type)) {
+ return minBitWidth;
+ } else {
+ // We have an absolute offset, but want to store a relative offset
+ // elem_index elements beyond the current buffer end. Since whether
+ // the relative offset fits in a certain byte_width depends on
+ // the size of the elements before it (and their alignment), we have
+ // to test for each size in turn.
+
+ // Original implementation checks for largest scalar
+ // which is long unsigned int
+ for (int byteWidth = 1; byteWidth <= 32; byteWidth *= 2) {
+ // Where are we going to write this offset?
+ int offsetLoc = bufSize + paddingBytes(bufSize, byteWidth) + (elemIndex * byteWidth);
+ // Compute relative offset.
+ long offset = offsetLoc - iValue;
+ // Does it fit?
+ int bitWidth = widthUInBits((int) offset);
+ if (((1L) << bitWidth) == byteWidth)
+ return bitWidth;
+ }
+ assert (false); // Must match one of the sizes above.
+ return WIDTH_64;
+ }
+ }
+
+ private static int paddingBytes(int bufSize, int scalarSize) {
+ return ((~bufSize) + 1) & (scalarSize - 1);
+ }
+ }
+}
+
+/// @}
diff --git a/java/com/google/flatbuffers/FloatVector.java b/java/com/google/flatbuffers/FloatVector.java
new file mode 100644
index 00000000..5c505ba8
--- /dev/null
+++ b/java/com/google/flatbuffers/FloatVector.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of float values.
+ */
+public final class FloatVector extends BaseVector {
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param _vector Start data of a vector.
+ * @param _bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public FloatVector __assign(int _vector, ByteBuffer _bb) {
+ __reset(_vector, Constants.SIZEOF_FLOAT, _bb); return this;
+ }
+
+ /**
+ * Reads the float value at the given index.
+ *
+ * @param j The index from which the float value will be read.
+ * @return the float value at the given index.
+ */
+ public float get(int j) {
+ return bb.getFloat(__element(j));
+ }
+}
diff --git a/java/com/google/flatbuffers/IntVector.java b/java/com/google/flatbuffers/IntVector.java
new file mode 100644
index 00000000..85549f41
--- /dev/null
+++ b/java/com/google/flatbuffers/IntVector.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of signed or unsigned 32-bit values.
+ */
+public final class IntVector extends BaseVector {
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param _vector Start data of a vector.
+ * @param _bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public IntVector __assign(int _vector, ByteBuffer _bb) {
+ __reset(_vector, Constants.SIZEOF_INT, _bb); return this;
+ }
+
+ /**
+ * Reads the integer at the given index.
+ *
+ * @param j The index from which the integer will be read.
+ * @return the 32-bit value at the given index.
+ */
+ public int get(int j) {
+ return bb.getInt(__element(j));
+ }
+
+ /**
+ * Reads the integer at the given index, zero-extends it to type long, and returns the result,
+ * which is therefore in the range 0 through 4294967295.
+ *
+ * @param j The index from which the integer will be read.
+ * @return the unsigned 32-bit at the given index.
+ */
+ public long getAsUnsigned(int j) {
+ return (long) get(j) & 0xFFFFFFFFL;
+ }
+}
diff --git a/java/com/google/flatbuffers/LongVector.java b/java/com/google/flatbuffers/LongVector.java
new file mode 100644
index 00000000..0ca5ab82
--- /dev/null
+++ b/java/com/google/flatbuffers/LongVector.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of long values.
+ */
+public final class LongVector extends BaseVector {
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param _vector Start data of a vector.
+ * @param _bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public LongVector __assign(int _vector, ByteBuffer _bb) {
+ __reset(_vector, Constants.SIZEOF_LONG, _bb); return this;
+ }
+
+ /**
+ * Reads the long value at the given index.
+ *
+ * @param j The index from which the long value will be read.
+ * @return the signed 64-bit value at the given index.
+ */
+ public long get(int j) {
+ return bb.getLong(__element(j));
+ }
+}
diff --git a/java/com/google/flatbuffers/ReadBuf.java b/java/com/google/flatbuffers/ReadBuf.java
new file mode 100644
index 00000000..dbb4e733
--- /dev/null
+++ b/java/com/google/flatbuffers/ReadBuf.java
@@ -0,0 +1,81 @@
+package com.google.flatbuffers;
+
+/**
+ * Represent a chunk of data, where FlexBuffers will read from.
+ */
+interface ReadBuf {
+
+ /**
+ * Read boolean from data. Booleans as stored as single byte
+ * @param index position of the element in ReadBuf
+ * @return boolean element
+ */
+ boolean getBoolean(int index);
+
+ /**
+ * Read a byte from data.
+ * @param index position of the element in ReadBuf
+ * @return a byte
+ */
+ byte get(int index);
+
+ /**
+ * Read a short from data.
+ * @param index position of the element in ReadBuf
+ * @return a short
+ */
+ short getShort(int index);
+
+ /**
+ * Read a 32-bit int from data.
+ * @param index position of the element in ReadBuf
+ * @return an int
+ */
+ int getInt(int index);
+
+ /**
+ * Read a 64-bit long from data.
+ * @param index position of the element in ReadBuf
+ * @return a long
+ */
+ long getLong(int index);
+
+ /**
+ * Read a 32-bit float from data.
+ * @param index position of the element in ReadBuf
+ * @return a float
+ */
+ float getFloat(int index);
+
+ /**
+ * Read a 64-bit float from data.
+ * @param index position of the element in ReadBuf
+ * @return a double
+ */
+ double getDouble(int index);
+
+ /**
+ * Read an UTF-8 string from data.
+ * @param start initial element of the string
+ * @param size size of the string in bytes.
+ * @return a {@code String}
+ */
+ String getString(int start, int size);
+
+ /**
+ * Expose ReadBuf as an array of bytes.
+ * This method is meant to be as efficient as possible, so for a array-backed ReadBuf, it should
+ * return its own internal data. In case access to internal data is not possible,
+ * a copy of the data into an array of bytes might occur.
+ * @return ReadBuf as an array of bytes
+ */
+ byte[] data();
+
+ /**
+ * Defines the size of the message in the buffer. It also determines last position that buffer
+ * can be read. Last byte to be accessed is in position {@code limit() -1}.
+ * @return indicate last position
+ */
+ int limit();
+
+}
diff --git a/java/com/google/flatbuffers/ReadWriteBuf.java b/java/com/google/flatbuffers/ReadWriteBuf.java
new file mode 100644
index 00000000..df672fbc
--- /dev/null
+++ b/java/com/google/flatbuffers/ReadWriteBuf.java
@@ -0,0 +1,135 @@
+package com.google.flatbuffers;
+
+/**
+ * Interface to represent a read-write buffer. This interface will be used to access and write
+ * FlexBuffers message.
+ */
+interface ReadWriteBuf extends ReadBuf {
+ /**
+ * Put a boolean into the buffer at {@code writePosition()} . Booleans as stored as single
+ * byte. Write position will be incremented.
+ * @return boolean element
+ */
+ void putBoolean(boolean value);
+
+ /**
+ * Put an array of bytes into the buffer at {@code writePosition()}. Write position will be
+ * incremented.
+ * @param value the data to be copied
+ * @param start initial position on value to be copied
+ * @param length amount of bytes to be copied
+ */
+ void put (byte[] value, int start, int length);
+
+ /**
+ * Write a byte into the buffer at {@code writePosition()}. Write position will be
+ * incremented.
+ */
+ void put(byte value);
+
+ /**
+ * Write a 16-bit into in the buffer at {@code writePosition()}. Write position will be
+ * incremented.
+ */
+ void putShort(short value);
+
+ /**
+ * Write a 32-bit into in the buffer at {@code writePosition()}. Write position will be
+ * incremented.
+ */
+ void putInt(int value);
+
+ /**
+ * Write a 64-bit into in the buffer at {@code writePosition()}. Write position will be
+ * incremented.
+ */
+ void putLong(long value);
+
+ /**
+ * Write a 32-bit float into the buffer at {@code writePosition()}. Write position will be
+ * incremented.
+ */
+ void putFloat(float value);
+
+ /**
+ * Write a 64-bit float into the buffer at {@code writePosition()}. Write position will be
+ * incremented.
+ */
+ void putDouble(double value);
+
+ /**
+ * Write boolean into a given position on the buffer. Booleans as stored as single byte.
+ * @param index position of the element in buffer
+ */
+ void setBoolean(int index, boolean value);
+
+ /**
+ * Read a byte from data.
+ * @param index position of the element in the buffer
+ * @return a byte
+ */
+ void set(int index, byte value);
+
+ /**
+ * Write an array of bytes into the buffer.
+ * @param index initial position of the buffer to be written
+ * @param value the data to be copied
+ * @param start initial position on value to be copied
+ * @param length amount of bytes to be copied
+ */
+ void set(int index, byte[] value, int start, int length);
+
+ /**
+ * Read a short from data.
+ * @param index position of the element in ReadBuf
+ * @return a short
+ */
+ void setShort(int index, short value);
+
+ /**
+ * Read a 32-bit int from data.
+ * @param index position of the element in ReadBuf
+ * @return an int
+ */
+ void setInt(int index, int value);
+
+ /**
+ * Read a 64-bit long from data.
+ * @param index position of the element in ReadBuf
+ * @return a long
+ */
+ void setLong(int index, long value);
+
+ /**
+ * Read a 32-bit float from data.
+ * @param index position of the element in ReadBuf
+ * @return a float
+ */
+ void setFloat(int index, float value);
+
+ /**
+ * Read a 64-bit float from data.
+ * @param index position of the element in ReadBuf
+ * @return a double
+ */
+ void setDouble(int index, double value);
+
+
+ int writePosition();
+ /**
+ * Defines the size of the message in the buffer. It also determines last position that buffer
+ * can be read or write. Last byte to be accessed is in position {@code limit() -1}.
+ * @return indicate last position
+ */
+ int limit();
+
+ /**
+ * Request capacity of the buffer. In case buffer is already larger
+ * than the requested, this method will just return true. Otherwise
+ * It might try to resize the buffer.
+ *
+ * @return true if buffer is able to offer
+ * the requested capacity
+ */
+ boolean requestCapacity(int capacity);
+}
diff --git a/java/com/google/flatbuffers/ShortVector.java b/java/com/google/flatbuffers/ShortVector.java
new file mode 100644
index 00000000..b02ac3e4
--- /dev/null
+++ b/java/com/google/flatbuffers/ShortVector.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of signed or unsigned 16-bit values.
+ */
+public final class ShortVector extends BaseVector {
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param _vector Start data of a vector.
+ * @param _bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public ShortVector __assign(int _vector, ByteBuffer _bb) {
+ __reset(_vector, Constants.SIZEOF_SHORT, _bb); return this;
+ }
+
+ /**
+ * Reads the short value at the given index.
+ *
+ * @param j The index from which the short value will be read.
+ * @return the 16-bit value at the given index.
+ */
+ public short get(int j) {
+ return bb.getShort(__element(j));
+ }
+
+ /**
+ * Reads the short at the given index, zero-extends it to type int, and returns the result,
+ * which is therefore in the range 0 through 65535.
+ *
+ * @param j The index from which the short value will be read.
+ * @return the unsigned 16-bit at the given index.
+ */
+ public int getAsUnsigned(int j) {
+ return (int) get(j) & 0xFFFF;
+ }
+}
diff --git a/java/com/google/flatbuffers/StringVector.java b/java/com/google/flatbuffers/StringVector.java
new file mode 100644
index 00000000..6c20775c
--- /dev/null
+++ b/java/com/google/flatbuffers/StringVector.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of String.
+ */
+public final class StringVector extends BaseVector {
+ private Utf8 utf8 = Utf8.getDefault();
+
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param _vector Start data of a vector.
+ * @param _element_size Size of a vector element.
+ * @param _bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public StringVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
+ __reset(_vector, _element_size, _bb); return this;
+ }
+
+ /**
+ * Reads the String at the given index.
+ *
+ * @param j The index from which the String value will be read.
+ * @return the String at the given index.
+ */
+ public String get(int j) {
+ return Table.__string(__element(j), bb, utf8);
+ }
+}
diff --git a/java/com/google/flatbuffers/Struct.java b/java/com/google/flatbuffers/Struct.java
index 39a8215a..c92164ff 100644
--- a/java/com/google/flatbuffers/Struct.java
+++ b/java/com/google/flatbuffers/Struct.java
@@ -30,6 +30,21 @@ public class Struct {
protected ByteBuffer bb;
/**
+ * Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
+ *
+ * This method exists primarily to allow recycling Table instances without risking memory leaks
+ * due to {@code ByteBuffer} references.
+ */
+ protected void __reset(int _i, ByteBuffer _bb) {
+ bb = _bb;
+ if (bb != null) {
+ bb_pos = _i;
+ } else {
+ bb_pos = 0;
+ }
+ }
+
+ /**
* Resets internal state with a null {@code ByteBuffer} and a zero position.
*
* This method exists primarily to allow recycling Struct instances without risking memory leaks
@@ -39,8 +54,7 @@ public class Struct {
* @param struct the instance to reset to initial state
*/
public void __reset() {
- bb = null;
- bb_pos = 0;
+ __reset(0, null);
}
}
diff --git a/java/com/google/flatbuffers/Table.java b/java/com/google/flatbuffers/Table.java
index cedbb8eb..7f416396 100644
--- a/java/com/google/flatbuffers/Table.java
+++ b/java/com/google/flatbuffers/Table.java
@@ -19,7 +19,6 @@ package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.nio.charset.Charset;
/// @cond FLATBUFFERS_INTERNAL
@@ -27,20 +26,14 @@ import java.nio.charset.Charset;
* All tables in the generated code derive from this class, and add their own accessors.
*/
public class Table {
- public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() {
- @Override
- protected Charset initialValue() {
- return Charset.forName("UTF-8");
- }
- };
/** Used to hold the position of the `bb` buffer. */
protected int bb_pos;
/** The underlying ByteBuffer to hold the data of the Table. */
protected ByteBuffer bb;
/** Used to hold the vtable position. */
- protected int vtable_start;
+ private int vtable_start;
/** Used to hold the vtable size. */
- protected int vtable_size;
+ private int vtable_size;
Utf8 utf8 = Utf8.getDefault();
/**
@@ -75,6 +68,13 @@ public class Table {
return offset + bb.getInt(offset);
}
+ /**
+ * Retrieve a relative offset.
+ *
+ * @param offset An `int` index into a ByteBuffer containing the relative offset.
+ * @param bb from which the relative offset will be retrieved.
+ * @return Returns the relative offset stored at `offset`.
+ */
protected static int __indirect(int offset, ByteBuffer bb) {
return offset + bb.getInt(offset);
}
@@ -91,6 +91,23 @@ public class Table {
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
*/
protected String __string(int offset) {
+ return __string(offset, bb, utf8);
+ }
+
+ /**
+ * Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
+ *
+ * This allocates a new string and converts to wide chars upon each access,
+ * which is not very efficient. Instead, each FlatBuffer string also comes with an
+ * accessor based on __vector_as_bytebuffer below, which is much more efficient,
+ * assuming your Java program can handle UTF-8 data directly.
+ *
+ * @param offset An `int` index into the Table's ByteBuffer.
+ * @param bb Table ByteBuffer used to read a string at given offset.
+ * @param utf8 decoder that creates a Java `String` from UTF-8 characters.
+ * @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
+ */
+ protected static String __string(int offset, ByteBuffer bb, Utf8 utf8) {
offset += bb.getInt(offset);
int length = bb.getInt(offset);
return utf8.decodeUtf8(bb, offset + SIZEOF_INT, length);
@@ -169,11 +186,19 @@ public class Table {
* @return Returns the Table that points to the union at `offset`.
*/
protected Table __union(Table t, int offset) {
- offset += bb_pos;
- t.bb_pos = offset + bb.getInt(offset);
- t.bb = bb;
- t.vtable_start = t.bb_pos - bb.getInt(t.bb_pos);
- t.vtable_size = bb.getShort(t.vtable_start);
+ return __union(t, offset, bb);
+ }
+
+ /**
+ * Initialize any Table-derived type to point to the union at the given `offset`.
+ *
+ * @param t A `Table`-derived type that should point to the union at `offset`.
+ * @param offset An `int` index into the Table's ByteBuffer.
+ * @param bb Table ByteBuffer used to initialize the object Table-derived type.
+ * @return Returns the Table that points to the union at `offset`.
+ */
+ protected static Table __union(Table t, int offset, ByteBuffer bb) {
+ t.__reset(__indirect(offset, bb), bb);
return t;
}
@@ -264,6 +289,25 @@ public class Table {
}
/**
+ * Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
+ *
+ * This method exists primarily to allow recycling Table instances without risking memory leaks
+ * due to {@code ByteBuffer} references.
+ */
+ protected void __reset(int _i, ByteBuffer _bb) {
+ bb = _bb;
+ if (bb != null) {
+ bb_pos = _i;
+ vtable_start = bb_pos - bb.getInt(bb_pos);
+ vtable_size = bb.getShort(vtable_start);
+ } else {
+ bb_pos = 0;
+ vtable_start = 0;
+ vtable_size = 0;
+ }
+ }
+
+ /**
* Resets the internal state with a null {@code ByteBuffer} and a zero position.
*
* This method exists primarily to allow recycling Table instances without risking memory leaks
@@ -271,10 +315,7 @@ public class Table {
* again to a {@code ByteBuffer}.
*/
public void __reset() {
- bb = null;
- bb_pos = 0;
- vtable_start = 0;
- vtable_size = 0;
+ __reset(0, null);
}
}
diff --git a/java/com/google/flatbuffers/UnionVector.java b/java/com/google/flatbuffers/UnionVector.java
new file mode 100644
index 00000000..986cfea4
--- /dev/null
+++ b/java/com/google/flatbuffers/UnionVector.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2019 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.flatbuffers;
+
+import static com.google.flatbuffers.Constants.*;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+
+/**
+ * Helper type for accessing vector of unions.
+ */
+public final class UnionVector extends BaseVector {
+ /**
+ * Assigns vector access object to vector data.
+ *
+ * @param _vector Start data of a vector.
+ * @param _element_size Size of a vector element.
+ * @param _bb Table's ByteBuffer.
+ * @return Returns current vector access object assigned to vector data whose offset is stored at
+ * `vector`.
+ */
+ public UnionVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
+ __reset(_vector, _element_size, _bb); return this;
+ }
+
+
+ /**
+ * Initialize any Table-derived type to point to the union at the given `index`.
+ *
+ * @param obj A `Table`-derived type that should point to the union at `index`.
+ * @param j An `int` index into the union vector.
+ * @return Returns the Table that points to the union at `index`.
+ */
+ public Table get(Table obj, int j) {
+ return Table.__union(obj, __element(j), bb);
+ }
+}
diff --git a/java/com/google/flatbuffers/Utf8.java b/java/com/google/flatbuffers/Utf8.java
index a2640637..efb6811f 100644
--- a/java/com/google/flatbuffers/Utf8.java
+++ b/java/com/google/flatbuffers/Utf8.java
@@ -110,9 +110,11 @@ public abstract class Utf8 {
throws IllegalArgumentException {
// Simultaneously checks for illegal trailing-byte in leading position (<= '11000000') and
// overlong 2-byte, '11000001'.
- if (byte1 < (byte) 0xC2
- || isNotTrailingByte(byte2)) {
- throw new IllegalArgumentException("Invalid UTF-8");
+ if (byte1 < (byte) 0xC2) {
+ throw new IllegalArgumentException("Invalid UTF-8: Illegal leading byte in 2 bytes utf");
+ }
+ if (isNotTrailingByte(byte2)) {
+ throw new IllegalArgumentException("Invalid UTF-8: Illegal trailing byte in 2 bytes utf");
}
resultArr[resultPos] = (char) (((byte1 & 0x1F) << 6) | trailingByteValue(byte2));
}
diff --git a/java/com/google/flatbuffers/Utf8Old.java b/java/com/google/flatbuffers/Utf8Old.java
index 97933332..3dac714b 100644
--- a/java/com/google/flatbuffers/Utf8Old.java
+++ b/java/com/google/flatbuffers/Utf8Old.java
@@ -67,6 +67,7 @@ public class Utf8Old extends Utf8 {
throw new IllegalArgumentException("bad character encoding", e);
}
}
+ cache.lastOutput.flip();
return cache.lastOutput.remaining();
}
@@ -90,7 +91,6 @@ public class Utf8Old extends Utf8 {
buffer.limit(offset + length);
try {
CharBuffer result = decoder.decode(buffer);
- result.flip();
return result.toString();
} catch (CharacterCodingException e) {
throw new IllegalArgumentException("Bad encoding", e);
diff --git a/java/com/google/flatbuffers/Utf8Safe.java b/java/com/google/flatbuffers/Utf8Safe.java
index 06ea420b..523e3f1b 100644
--- a/java/com/google/flatbuffers/Utf8Safe.java
+++ b/java/com/google/flatbuffers/Utf8Safe.java
@@ -123,7 +123,7 @@ final public class Utf8Safe extends Utf8 {
return utf8Length;
}
- private static String decodeUtf8Array(byte[] bytes, int index, int size) {
+ public static String decodeUtf8Array(byte[] bytes, int index, int size) {
// Bitwise OR combines the sign bits so any negative value fails the check.
if ((index | size | bytes.length - index - size) < 0) {
throw new ArrayIndexOutOfBoundsException(
@@ -197,7 +197,7 @@ final public class Utf8Safe extends Utf8 {
return new String(resultArr, 0, resultPos);
}
- private static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
+ public static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
int length) {
// Bitwise OR combines the sign bits so any negative value fails the check.
if ((offset | length | buffer.limit() - offset - length) < 0) {
diff --git a/js/flatbuffers.js b/js/flatbuffers.js
index 41608520..74cd35ab 100644
--- a/js/flatbuffers.js
+++ b/js/flatbuffers.js
@@ -49,6 +49,12 @@ flatbuffers.SIZEOF_INT = 4;
flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
/**
+ * @type {number}
+ * @const
+ */
+flatbuffers.SIZE_PREFIX_LENGTH = 4;
+
+/**
* @enum {number}
*/
flatbuffers.Encoding = {
@@ -104,7 +110,7 @@ flatbuffers.Long = function(low, high) {
/**
* @param {number} low
* @param {number} high
- * @returns {flatbuffers.Long}
+ * @returns {!flatbuffers.Long}
*/
flatbuffers.Long.create = function(low, high) {
// Special-case zero to avoid GC overhead for default values
@@ -127,7 +133,7 @@ flatbuffers.Long.prototype.equals = function(other) {
};
/**
- * @type {flatbuffers.Long}
+ * @type {!flatbuffers.Long}
* @const
*/
flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
@@ -265,7 +271,7 @@ flatbuffers.Builder.prototype.dataBuffer = function() {
* Get the bytes representing the FlatBuffer. Only call this after you've
* called finish().
*
- * @returns {Uint8Array}
+ * @returns {!Uint8Array}
*/
flatbuffers.Builder.prototype.asUint8Array = function() {
return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
@@ -550,7 +556,7 @@ flatbuffers.Builder.prototype.offset = function() {
* the end of the new buffer (since we build the buffer backwards).
*
* @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
- * @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
+ * @returns {!flatbuffers.ByteBuffer} A new byte buffer with the old data copied
* to it. The data is located at the end of the buffer.
*
* uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
@@ -676,12 +682,14 @@ outer_loop:
*
* @param {flatbuffers.Offset} root_table
* @param {string=} opt_file_identifier
+ * @param {boolean=} opt_size_prefix
*/
-flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier) {
+flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier, opt_size_prefix) {
+ var size_prefix = opt_size_prefix ? flatbuffers.SIZE_PREFIX_LENGTH : 0;
if (opt_file_identifier) {
var file_identifier = opt_file_identifier;
this.prep(this.minalign, flatbuffers.SIZEOF_INT +
- flatbuffers.FILE_IDENTIFIER_LENGTH);
+ flatbuffers.FILE_IDENTIFIER_LENGTH + size_prefix);
if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
throw new Error('FlatBuffers: file identifier must be length ' +
flatbuffers.FILE_IDENTIFIER_LENGTH);
@@ -690,11 +698,24 @@ flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier)
this.writeInt8(file_identifier.charCodeAt(i));
}
}
- this.prep(this.minalign, flatbuffers.SIZEOF_INT);
+ this.prep(this.minalign, flatbuffers.SIZEOF_INT + size_prefix);
this.addOffset(root_table);
+ if (size_prefix) {
+ this.addInt32(this.bb.capacity() - this.space);
+ }
this.bb.setPosition(this.space);
};
+/**
+ * Finalize a size prefixed buffer, pointing to the given `root_table`.
+ *
+ * @param {flatbuffers.Offset} root_table
+ * @param {string=} opt_file_identifier
+ */
+flatbuffers.Builder.prototype.finishSizePrefixed = function (root_table, opt_file_identifier) {
+ this.finish(root_table, opt_file_identifier, true);
+};
+
/// @cond FLATBUFFERS_INTERNAL
/**
* This checks a required field has been set in a given table that has
@@ -804,7 +825,7 @@ flatbuffers.Builder.prototype.createString = function(s) {
*
* @param {number} low
* @param {number} high
- * @returns {flatbuffers.Long}
+ * @returns {!flatbuffers.Long}
*/
flatbuffers.Builder.prototype.createLong = function(low, high) {
return flatbuffers.Long.create(low, high);
@@ -835,7 +856,7 @@ flatbuffers.ByteBuffer = function(bytes) {
* Create and allocate a new ByteBuffer with a given size.
*
* @param {number} byte_size
- * @returns {flatbuffers.ByteBuffer}
+ * @returns {!flatbuffers.ByteBuffer}
*/
flatbuffers.ByteBuffer.allocate = function(byte_size) {
return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
@@ -931,7 +952,7 @@ flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
/**
* @param {number} offset
- * @returns {flatbuffers.Long}
+ * @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
@@ -939,7 +960,7 @@ flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
/**
* @param {number} offset
- * @returns {flatbuffers.Long}
+ * @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
@@ -1114,7 +1135,7 @@ flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
*
* @param {number} offset
* @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
- * @returns {string|Uint8Array}
+ * @returns {string|!Uint8Array}
*/
flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
offset += this.readInt32(offset);
@@ -1225,7 +1246,7 @@ flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
*
* @param {number} low
* @param {number} high
- * @returns {flatbuffers.Long}
+ * @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
return flatbuffers.Long.create(low, high);
diff --git a/lobster/flatbuffers.lobster b/lobster/flatbuffers.lobster
index 09105e76..0f1c15dd 100644
--- a/lobster/flatbuffers.lobster
+++ b/lobster/flatbuffers.lobster
@@ -12,32 +12,37 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-include "std.lobster"
+import std
namespace flatbuffers
-struct handle:
+class handle:
buf_:string
pos_:int
-enum + sz_8 = 1,
- sz_16 = 2,
- sz_32 = 4,
- sz_64 = 8,
- sz_voffset = 2,
- sz_uoffset = 4,
- sz_soffset = 4,
- sz_metadata_fields = 2
-
-struct builder:
- buf:string = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+// More strongly typed than a naked int, at no cost.
+struct offset:
+ o:int
+
+enum sizeof:
+ sz_8 = 1
+ sz_16 = 2
+ sz_32 = 4
+ sz_64 = 8
+ sz_voffset = 2
+ sz_uoffset = 4
+ sz_soffset = 4
+ sz_metadata_fields = 2
+
+class builder:
+ buf = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
current_vtable:[int] = []
- head:int = 0
- minalign:int = 1
- object_end:int = 0
+ head = 0
+ minalign = 1
+ object_end = 0
vtables:[int] = []
- nested:int = false
- finished:int = false
+ nested = false
+ finished = false
// Optionally call this right after creating the builder for a larger initial buffer.
def Initial(initial_size:int):
@@ -49,7 +54,7 @@ struct builder:
def Offset():
// Offset relative to the end of the buffer.
- return head
+ return offset { head }
// Returns a copy of the part of the buffer containing only the finished FlatBuffer
def SizedCopy():
@@ -75,11 +80,11 @@ struct builder:
// Prepend a zero scalar to the object. Later in this function we'll
// write an offset here that points to the object's vtable:
PrependInt32(0)
- object_offset := head
+ let object_offset = head
// Write out new vtable speculatively.
- vtable_size := (current_vtable.length + sz_metadata_fields) * sz_voffset
+ let vtable_size = (current_vtable.length + sz_metadata_fields) * sz_voffset
while current_vtable.length:
- o := current_vtable.pop()
+ let o = current_vtable.pop()
PrependVOffsetT(if o: object_offset - o else: 0)
// The two metadata fields are written last.
// First, store the object bytesize:
@@ -91,17 +96,18 @@ struct builder:
// BenchmarkVtableDeduplication for a case in which this heuristic
// saves about 30% of the time used in writing objects with duplicate
// tables.
- existing_vtable := do():
+ def find_existing_table():
reverse(vtables) vt2_offset:
// Find the other vtable:
- vt2_start := buf.length - vt2_offset
- vt2_len := buf.read_int16_le(vt2_start)
+ let vt2_start = buf.length - vt2_offset
+ let vt2_len = buf.read_int16_le(vt2_start)
// Compare the other vtable to the one under consideration.
// If they are equal, return the offset:
if vtable_size == vt2_len and
not compare_substring(buf, Start(), buf, vt2_start, vtable_size):
- return vt2_offset from do
- 0
+ return vt2_offset
+ return 0
+ let existing_vtable = find_existing_table()
if existing_vtable:
// Found a duplicate vtable, remove the one we wrote.
head = object_offset
@@ -116,10 +122,11 @@ struct builder:
// Finally, store this vtable in memory for future
// deduplication:
vtables.push(head)
- return object_offset
+ return offset { object_offset }
def Pad(n):
- for(n): buf, head = buf.write_int8_le_back(head, 0)
+ for(n):
+ buf, head = buf.write_int8_le_back(head, 0)
def Prep(size, additional_bytes):
// Track the biggest thing we've ever aligned to.
@@ -127,27 +134,27 @@ struct builder:
minalign = size
// Find the amount of alignment needed such that `size` is properly
// aligned after `additionalBytes`:
- align_size := ((~(head + additional_bytes)) + 1) & (size - 1)
+ let align_size = ((~(head + additional_bytes)) + 1) & (size - 1)
Pad(align_size)
- def PrependUOffsetTRelative(off):
+ def PrependUOffsetTRelative(off:offset):
// Prepends an unsigned offset into vector data, relative to where it will be written.
Prep(sz_uoffset, 0)
- assert off <= head
- PlaceUOffsetT(head - off + sz_uoffset)
+ assert off.o <= head
+ PlaceUOffsetT(head - off.o + sz_uoffset)
def StartVector(elem_size, num_elems, alignment):
// Initializes bookkeeping for writing a new vector.
StartNesting()
Prep(sz_32, elem_size * num_elems)
Prep(alignment, elem_size * num_elems) // In case alignment > int.
- return head
+ return Offset()
def EndVector(vector_num_elems):
EndNesting()
// we already made space for this, so write without PrependUint32
PlaceUOffsetT(vector_num_elems)
- return head
+ return Offset()
def CreateString(s:string):
// writes a null-terminated byte string.
@@ -168,11 +175,11 @@ struct builder:
while current_vtable.length <= slotnum: current_vtable.push(0)
current_vtable[slotnum] = head
- def __Finish(root_table:int, size_prefix:int):
+ def __Finish(root_table:offset, size_prefix:int):
// Finish finalizes a buffer, pointing to the given root_table
assert not finished
assert not nested
- prep_size := sz_32
+ var prep_size = sz_32
if size_prefix:
prep_size += sz_32
Prep(minalign, prep_size)
@@ -182,10 +189,10 @@ struct builder:
finished = true
return Start()
- def Finish(root_table:int):
+ def Finish(root_table:offset):
return __Finish(root_table, false)
- def FinishSizePrefixed(root_table:int):
+ def FinishSizePrefixed(root_table:offset):
return __Finish(root_table, true)
def PrependBool(x):
@@ -263,16 +270,15 @@ struct builder:
def PrependFloat32Slot(o, x, d): PrependSlot(o, x, d): PrependFloat32(_)
def PrependFloat64Slot(o, x, d): PrependSlot(o, x, d): PrependFloat64(_)
- def PrependUOffsetTRelativeSlot(o, x, d):
- if x != d:
+ def PrependUOffsetTRelativeSlot(o:int, x:offset):
+ if x.o:
PrependUOffsetTRelative(x)
Slot(o)
- def PrependStructSlot(v, x, d):
- if x != d:
+ def PrependStructSlot(v:int, x:offset):
+ if x.o:
// Structs are always stored inline, so need to be created right
// where they are used. You'll get this error if you created it
- //elsewhere.
- assert x == head
+ // elsewhere.
+ assert x.o == head
Slot(v)
-
diff --git a/lua/flatbuffers/builder.lua b/lua/flatbuffers/builder.lua
index 2fb22204..4a0c4f6a 100644
--- a/lua/flatbuffers/builder.lua
+++ b/lua/flatbuffers/builder.lua
@@ -29,12 +29,12 @@ local getAlignSize = compat.GetAlignSize
local function vtableEqual(a, objectStart, b)
UOffsetT:EnforceNumber(objectStart)
- if (#a * VOffsetT.bytewidth) ~= #b then
+ if (#a * 2) ~= #b then
return false
end
for i, elem in ipairs(a) do
- local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * VOffsetT.bytewidth)
+ local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * 2)
if x ~= 0 or elem ~= 0 then
local y = objectStart - elem
if x ~= y then
@@ -60,6 +60,23 @@ function m.New(initialSize)
return o
end
+-- Clears the builder and resets the state. It does not actually clear the backing binary array, it just reuses it as
+-- needed. This is a performant way to use the builder for multiple constructions without the overhead of multiple
+-- builder allocations.
+function mt:Clear()
+ self.finished = false
+ self.nested = false
+ self.minalign = 1
+ self.currentVTable = nil
+ self.objectEnd = nil
+ self.head = #self.bytes -- place the head at the end of the binary array
+
+ -- clear vtables instead of making a new table
+ local vtable = self.vtables
+ local vtableCount = #vtable
+ for i=1,vtableCount do vtable[i] = nil end
+end
+
function mt:Output(full)
assert(self.finished, "Builder Not Finished")
if full then
@@ -104,7 +121,7 @@ function mt:WriteVtable()
local vt2lenstr = self.bytes:Slice(vt2Start, vt2Start+1)
local vt2Len = string.unpack(VOffsetT.packFmt, vt2lenstr, 1)
- local metadata = VtableMetadataFields * VOffsetT.bytewidth
+ local metadata = VtableMetadataFields * 2
local vt2End = vt2Start + vt2Len
local vt2 = self.bytes:Slice(vt2Start+metadata,vt2End)
@@ -133,7 +150,7 @@ function mt:WriteVtable()
self:PrependVOffsetT(objectSize)
local vBytes = #self.currentVTable + VtableMetadataFields
- vBytes = vBytes * VOffsetT.bytewidth
+ vBytes = vBytes * 2
self:PrependVOffsetT(vBytes)
local objectStart = #self.bytes - objectOffset
@@ -208,17 +225,17 @@ function mt:Prep(size, additionalBytes)
end
function mt:PrependSOffsetTRelative(off)
- self:Prep(SOffsetT.bytewidth, 0)
+ self:Prep(4, 0)
assert(off <= self:Offset(), "Offset arithmetic error")
- local off2 = self:Offset() - off + SOffsetT.bytewidth
+ local off2 = self:Offset() - off + 4
self:Place(off2, SOffsetT)
end
function mt:PrependUOffsetTRelative(off)
- self:Prep(UOffsetT.bytewidth, 0)
+ self:Prep(4, 0)
local soffset = self:Offset()
if off <= soffset then
- local off2 = soffset - off + UOffsetT.bytewidth
+ local off2 = soffset - off + 4
self:Place(off2, UOffsetT)
else
error("Offset arithmetic error")
@@ -228,8 +245,9 @@ end
function mt:StartVector(elemSize, numElements, alignment)
assert(not self.nested)
self.nested = true
- self:Prep(Uint32.bytewidth, elemSize * numElements)
- self:Prep(alignment, elemSize * numElements)
+ local elementSize = elemSize * numElements
+ self:Prep(4, elementSize) -- Uint32 length
+ self:Prep(alignment, elementSize)
return self:Offset()
end
@@ -246,7 +264,7 @@ function mt:CreateString(s)
assert(type(s) == "string")
- self:Prep(UOffsetT.bytewidth, (#s + 1)*Uint8.bytewidth)
+ self:Prep(4, #s + 1)
self:Place(0, Uint8)
local l = #s
@@ -254,20 +272,21 @@ function mt:CreateString(s)
self.bytes:Set(s, self.head, self.head + l)
- return self:EndVector(#s)
+ return self:EndVector(l)
end
function mt:CreateByteVector(x)
assert(not self.nested)
self.nested = true
- self:Prep(UOffsetT.bytewidth, #x*Uint8.bytewidth)
local l = #x
+ self:Prep(4, l)
+
self.head = self.head - l
self.bytes:Set(x, self.head, self.head + l)
- return self:EndVector(#x)
+ return self:EndVector(l)
end
function mt:Slot(slotnum)
@@ -278,12 +297,7 @@ end
local function finish(self, rootTable, sizePrefix)
UOffsetT:EnforceNumber(rootTable)
- local prepSize = UOffsetT.bytewidth
- if sizePrefix then
- prepSize = prepSize + Int32.bytewidth
- end
-
- self:Prep(self.minalign, prepSize)
+ self:Prep(self.minalign, sizePrefix and 8 or 4)
self:PrependUOffsetTRelative(rootTable)
if sizePrefix then
local size = #self.bytes - self.head
@@ -308,8 +322,9 @@ function mt:Prepend(flags, off)
end
function mt:PrependSlot(flags, o, x, d)
- flags:EnforceNumber(x)
- flags:EnforceNumber(d)
+ flags:EnforceNumbers(x,d)
+-- flags:EnforceNumber(x)
+-- flags:EnforceNumber(d)
if x ~= d then
self:Prepend(flags, x)
self:Slot(o)
diff --git a/lua/flatbuffers/numTypes.lua b/lua/flatbuffers/numTypes.lua
index 84d0261c..01f41993 100644
--- a/lua/flatbuffers/numTypes.lua
+++ b/lua/flatbuffers/numTypes.lua
@@ -34,6 +34,20 @@ function type_mt:EnforceNumber(n)
error("Number is not in the valid range")
end
+function type_mt:EnforceNumbers(a,b)
+ -- duplicate code since the overhead of function calls
+ -- for such a popular method is time consuming
+ if not self.min_value and not self.max_value then
+ return
+ end
+
+ if self.min_value <= a and a <= self.max_value and self.min_value <= b and b <= self.max_value then
+ return
+ end
+
+ error("Number is not in the valid range")
+end
+
function type_mt:EnforceNumberAndPack(n)
return bpack(self.packFmt, n)
end
@@ -53,7 +67,13 @@ local bool_mt =
max_value = true,
lua_type = type(true),
name = "bool",
- packFmt = "<b"
+ packFmt = "<I1",
+ Pack = function(self, value) return value and "1" or "0" end,
+ Unpack = function(self, buf, pos) return buf[pos] == "1" end,
+ ValidNumber = function(self, n) return true end, -- anything is a valid boolean in Lua
+ EnforceNumber = function(self, n) end, -- anything is a valid boolean in Lua
+ EnforceNumbers = function(self, a, b) end, -- anything is a valid boolean in Lua
+ EnforceNumberAndPack = function(self, n) return self:Pack(value) end,
}
local uint8_mt =
@@ -170,7 +190,6 @@ setmetatable(float32_mt, {__index = type_mt})
setmetatable(float64_mt, {__index = type_mt})
-m.Bool = bool_mt
m.Uint8 = uint8_mt
m.Uint16 = uint16_mt
m.Uint32 = uint32_mt
@@ -186,7 +205,7 @@ m.UOffsetT = uint32_mt
m.VOffsetT = uint16_mt
m.SOffsetT = int32_mt
-function GenerateTypes(listOfTypes)
+local GenerateTypes = function(listOfTypes)
for _,t in pairs(listOfTypes) do
t.Pack = function(self, value) return bpack(self.packFmt, value) end
t.Unpack = function(self, buf, pos) return bunpack(self.packFmt, buf, pos) end
@@ -195,4 +214,6 @@ end
GenerateTypes(m)
+-- explicitly execute after GenerateTypes call, as we don't want to define a Pack/Unpack function for it.
+m.Bool = bool_mt
return m
diff --git a/lua/flatbuffers/view.lua b/lua/flatbuffers/view.lua
index da0f8bf7..fde15c3d 100644
--- a/lua/flatbuffers/view.lua
+++ b/lua/flatbuffers/view.lua
@@ -6,69 +6,83 @@ local mt_name = "flatbuffers.view.mt"
local N = require("flatbuffers.numTypes")
local binaryarray = require("flatbuffers.binaryarray")
+local function enforceOffset(off)
+ if off < 0 or off > 42949672951 then
+ error("Offset is not valid")
+ end
+end
+
+local unpack = string.unpack
+local function unPackUoffset(bytes, off)
+ return unpack("<I4", bytes.str, off + 1)
+end
+
+local function unPackVoffset(bytes, off)
+ return unpack("<I2", bytes.str, off + 1)
+end
+
function m.New(buf, pos)
- N.UOffsetT:EnforceNumber(pos)
-
+ enforceOffset(pos)
-- need to convert from a string buffer into
-- a binary array
local o = {
bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
- pos = pos
+ pos = pos,
}
setmetatable(o, {__index = mt, __metatable = mt_name})
return o
end
function mt:Offset(vtableOffset)
- local vtable = self.pos - self:Get(N.SOffsetT, self.pos)
- local vtableEnd = self:Get(N.VOffsetT, vtable)
- if vtableOffset < vtableEnd then
- return self:Get(N.VOffsetT, vtable + vtableOffset)
+ local vtable = self.vtable
+ if not vtable then
+ vtable = self.pos - self:Get(N.SOffsetT, self.pos)
+ self.vtable = vtable
+ self.vtableEnd = self:Get(N.VOffsetT, vtable)
+ end
+ if vtableOffset < self.vtableEnd then
+ return unPackVoffset(self.bytes, vtable + vtableOffset)
end
return 0
end
function mt:Indirect(off)
- N.UOffsetT:EnforceNumber(off)
- return off + N.UOffsetT:Unpack(self.bytes, off)
+ enforceOffset(off)
+ return off + unPackUoffset(self.bytes, off)
end
function mt:String(off)
- N.UOffsetT:EnforceNumber(off)
- off = off + N.UOffsetT:Unpack(self.bytes, off)
- local start = off + N.UOffsetT.bytewidth
- local length = N.UOffsetT:Unpack(self.bytes, off)
+ enforceOffset(off)
+ off = off + unPackUoffset(self.bytes, off)
+ local start = off + 4
+ local length = unPackUoffset(self.bytes, off)
return self.bytes:Slice(start, start+length)
end
function mt:VectorLen(off)
- N.UOffsetT:EnforceNumber(off)
+ enforceOffset(off)
off = off + self.pos
- off = off + N.UOffsetT:Unpack(self.bytes, off)
- return N.UOffsetT:Unpack(self.bytes, off)
+ off = off + unPackUoffset(self.bytes, off)
+ return unPackUoffset(self.bytes, off)
end
function mt:Vector(off)
- N.UOffsetT:EnforceNumber(off)
-
+ enforceOffset(off)
off = off + self.pos
- local x = off + self:Get(N.UOffsetT, off)
- x = x + N.UOffsetT.bytewidth
- return x
+ return off + self:Get(N.UOffsetT, off) + 4
end
function mt:Union(t2, off)
assert(getmetatable(t2) == mt_name)
- N.UOffsetT:EnforceNumber(off)
-
+ enforceOffset(off)
off = off + self.pos
t2.pos = off + self:Get(N.UOffsetT, off)
t2.bytes = self.bytes
end
function mt:Get(flags, off)
- N.UOffsetT:EnforceNumber(off)
+ enforceOffset(off)
return flags:Unpack(self.bytes, off)
end
@@ -85,8 +99,7 @@ function mt:GetSlot(slot, d, validatorFlags)
end
function mt:GetVOffsetTSlot(slot, d)
- N.VOffsetT:EnforceNumber(slot)
- N.VOffsetT:EnforceNumber(d)
+ N.VOffsetT:EnforceNumbers(slot, d)
local off = self:Offset(slot)
if off == 0 then
return d
diff --git a/net/FlatBuffers/FlatBufferBuilder.cs b/net/FlatBuffers/FlatBufferBuilder.cs
index 93f72be3..27c16b36 100644
--- a/net/FlatBuffers/FlatBufferBuilder.cs
+++ b/net/FlatBuffers/FlatBufferBuilder.cs
@@ -16,6 +16,7 @@
using System;
+using System.Collections.Generic;
using System.Text;
/// @file
@@ -47,6 +48,9 @@ namespace FlatBuffers
// For the current vector being built.
private int _vectorNumElems = 0;
+ // For CreateSharedString
+ private Dictionary<string, StringOffset> _sharedStringMap = null;
+
/// <summary>
/// Create a FlatBufferBuilder with a given initial size.
/// </summary>
@@ -191,7 +195,7 @@ namespace FlatBuffers
}
/// <summary>
- /// Puts an array of type T into this builder at the
+ /// Puts an array of type T into this builder at the
/// current offset
/// </summary>
/// <typeparam name="T">The type of the input data </typeparam>
@@ -204,7 +208,7 @@ namespace FlatBuffers
#if ENABLE_SPAN_T
/// <summary>
- /// Puts a span of type T into this builder at the
+ /// Puts a span of type T into this builder at the
/// current offset
/// </summary>
/// <typeparam name="T">The type of the input data </typeparam>
@@ -407,7 +411,7 @@ namespace FlatBuffers
"FlatBuffers: object serialization must not be nested.");
}
- public void StartObject(int numfields)
+ public void StartTable(int numfields)
{
if (numfields < 0)
throw new ArgumentOutOfRangeException("Flatbuffers: invalid numfields");
@@ -536,9 +540,9 @@ namespace FlatBuffers
/// </summary>
/// <param name="o">The index into the vtable</param>
/// <param name="x">The value to put into the buffer. If the value is equal to the default
- /// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
+ /// the value will be skipped.</param>
/// <param name="d">The default value to compare the value against</param>
- public void AddOffset(int o, int x, int d) { if (ForceDefaults || x != d) { AddOffset(x); Slot(o); } }
+ public void AddOffset(int o, int x, int d) { if (x != d) { AddOffset(x); Slot(o); } }
/// @endcond
/// <summary>
@@ -579,6 +583,32 @@ namespace FlatBuffers
}
#endif
+ /// <summary>
+ /// Store a string in the buffer, which can contain any binary data.
+ /// If a string with this exact contents has already been serialized before,
+ /// instead simply returns the offset of the existing string.
+ /// </summary>
+ /// <param name="s">The string to encode.</param>
+ /// <returns>
+ /// The offset in the buffer where the encoded string starts.
+ /// </returns>
+ public StringOffset CreateSharedString(string s)
+ {
+ if (_sharedStringMap == null)
+ {
+ _sharedStringMap = new Dictionary<string, StringOffset>();
+ }
+
+ if (_sharedStringMap.ContainsKey(s))
+ {
+ return _sharedStringMap[s];
+ }
+
+ var stringOffset = CreateString(s);
+ _sharedStringMap.Add(s, stringOffset);
+ return stringOffset;
+ }
+
/// @cond FLATBUFFERS_INTERNAL
// Structs are stored inline, so nothing additional is being added.
// `d` is always 0.
@@ -591,11 +621,11 @@ namespace FlatBuffers
}
}
- public int EndObject()
+ public int EndTable()
{
if (_vtableSize < 0)
throw new InvalidOperationException(
- "Flatbuffers: calling endObject without a startObject");
+ "Flatbuffers: calling EndTable without a StartTable");
AddInt((int)0);
var vtableloc = Offset;
diff --git a/net/FlatBuffers/FlatBufferConstants.cs b/net/FlatBuffers/FlatBufferConstants.cs
index e30f3f39..1d4c5dce 100644
--- a/net/FlatBuffers/FlatBufferConstants.cs
+++ b/net/FlatBuffers/FlatBufferConstants.cs
@@ -25,5 +25,13 @@ namespace FlatBuffers
{
public const int FileIdentifierLength = 4;
public const int SizePrefixLength = 4;
+ /** A version identifier to force a compile error if someone
+ accidentally tries to build generated code with a runtime of
+ two mismatched version. Versions need to always match, as
+ the runtime and generated code are modified in sync.
+ Changes to the C# implementation need to be sure to change
+ the version here and in the code generator on every possible
+ incompatible change */
+ public static void FLATBUFFERS_1_12_0() {}
}
}
diff --git a/net/FlatBuffers/Struct.cs b/net/FlatBuffers/Struct.cs
index 61da32f7..4832cda3 100644
--- a/net/FlatBuffers/Struct.cs
+++ b/net/FlatBuffers/Struct.cs
@@ -21,7 +21,14 @@ namespace FlatBuffers
/// </summary>
public struct Struct
{
- public int bb_pos;
- public ByteBuffer bb;
+ public int bb_pos { get; private set; }
+ public ByteBuffer bb { get; private set; }
+
+ // Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
+ public Struct(int _i, ByteBuffer _bb) : this()
+ {
+ bb = _bb;
+ bb_pos = _i;
+ }
}
}
diff --git a/net/FlatBuffers/Table.cs b/net/FlatBuffers/Table.cs
index cc7f3c1c..2ed07884 100644
--- a/net/FlatBuffers/Table.cs
+++ b/net/FlatBuffers/Table.cs
@@ -16,6 +16,7 @@
using System;
using System.Text;
+using System.Runtime.InteropServices;
namespace FlatBuffers
{
@@ -24,11 +25,18 @@ namespace FlatBuffers
/// </summary>
public struct Table
{
- public int bb_pos;
- public ByteBuffer bb;
+ public int bb_pos { get; private set; }
+ public ByteBuffer bb { get; private set; }
public ByteBuffer ByteBuffer { get { return bb; } }
+ // Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
+ public Table(int _i, ByteBuffer _bb) : this()
+ {
+ bb = _bb;
+ bb_pos = _i;
+ }
+
// Look up a field in the vtable, return an offset into the object, or 0 if the field is not
// present.
public int __offset(int vtableOffset)
@@ -82,17 +90,23 @@ namespace FlatBuffers
// Get the data of a vector whoses offset is stored at "offset" in this object as an
// Spant&lt;byte&gt;. If the vector is not present in the ByteBuffer,
// then an empty span will be returned.
- public Span<byte> __vector_as_span(int offset)
+ public Span<T> __vector_as_span<T>(int offset, int elementSize) where T : struct
{
+ if (!BitConverter.IsLittleEndian)
+ {
+ throw new NotSupportedException("Getting typed span on a Big Endian " +
+ "system is not support");
+ }
+
var o = this.__offset(offset);
if (0 == o)
{
- return new Span<byte>();
+ return new Span<T>();
}
var pos = this.__vector(o);
var len = this.__vector_len(o);
- return bb.ToSpan(pos, len);
+ return MemoryMarshal.Cast<byte, T>(bb.ToSpan(pos, len * elementSize));
}
#else
// Get the data of a vector whoses offset is stored at "offset" in this object as an
@@ -138,9 +152,8 @@ namespace FlatBuffers
// Initialize any Table-derived type to point to the union at the given offset.
public T __union<T>(int offset) where T : struct, IFlatbufferObject
{
- offset += bb_pos;
T t = new T();
- t.__init(offset + bb.GetInt(offset), bb);
+ t.__init(__indirect(offset), bb);
return t;
}
diff --git a/package.json b/package.json
index f95e7540..d01680a0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "flatbuffers",
- "version": "1.11.0",
+ "version": "1.12.0",
"description": "Memory Efficient Serialization Library",
"files": [
"js/flatbuffers.js",
diff --git a/pom.xml b/pom.xml
index 60bd7f58..db3f778b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-java</artifactId>
- <version>1.11.0-SNAPSHOT</version>
+ <version>1.12.0</version>
<packaging>bundle</packaging>
<name>FlatBuffers Java API</name>
<description>
@@ -32,6 +30,7 @@
<connection>
scm:git:https://github.com/google/flatbuffers.git
</connection>
+ <tag>HEAD</tag>
</scm>
<dependencies>
</dependencies>
diff --git a/python/flatbuffers/__init__.py b/python/flatbuffers/__init__.py
index d14872ae..5e45eb79 100644
--- a/python/flatbuffers/__init__.py
+++ b/python/flatbuffers/__init__.py
@@ -15,3 +15,4 @@
from .builder import Builder
from .table import Table
from .compat import range_func as compat_range
+from . import util
diff --git a/python/flatbuffers/builder.py b/python/flatbuffers/builder.py
index 1e96d6fe..f9448b0b 100644
--- a/python/flatbuffers/builder.py
+++ b/python/flatbuffers/builder.py
@@ -94,7 +94,7 @@ class Builder(object):
It holds the following internal state:
- Bytes: an array of bytes.
- current_vtable: a list of integers.
- - vtables: a list of vtable entries (i.e. a list of list of integers).
+ - vtables: a hash of vtable entries.
Attributes:
Bytes: The internal `bytearray` for the Builder.
@@ -103,7 +103,7 @@ class Builder(object):
## @cond FLATBUFFERS_INTENRAL
__slots__ = ("Bytes", "current_vtable", "head", "minalign", "objectEnd",
- "vtables", "nested", "finished")
+ "vtables", "nested", "forceDefaults", "finished")
"""Maximum buffer size constant, in bytes.
@@ -129,12 +129,12 @@ class Builder(object):
self.head = UOffsetTFlags.py_type(initialSize)
self.minalign = 1
self.objectEnd = None
- self.vtables = []
+ self.vtables = {}
self.nested = False
+ self.forceDefaults = False
## @endcond
self.finished = False
-
def Output(self):
"""Return the portion of the buffer that has been used for writing data.
@@ -191,52 +191,45 @@ class Builder(object):
self.PrependSOffsetTRelative(0)
objectOffset = self.Offset()
- existingVtable = None
-
- # Trim trailing 0 offsets.
- while self.current_vtable and self.current_vtable[-1] == 0:
- self.current_vtable.pop()
-
- # Search backwards through existing vtables, because similar vtables
- # are likely to have been recently appended. See
- # BenchmarkVtableDeduplication for a case in which this heuristic
- # saves about 30% of the time used in writing objects with duplicate
- # tables.
-
- i = len(self.vtables) - 1
- while i >= 0:
- # Find the other vtable, which is associated with `i`:
- vt2Offset = self.vtables[i]
- vt2Start = len(self.Bytes) - vt2Offset
- vt2Len = encode.Get(packer.voffset, self.Bytes, vt2Start)
-
- metadata = VtableMetadataFields * N.VOffsetTFlags.bytewidth
- vt2End = vt2Start + vt2Len
- vt2 = self.Bytes[vt2Start+metadata:vt2End]
-
- # Compare the other vtable to the one under consideration.
- # If they are equal, store the offset and break:
- if vtableEqual(self.current_vtable, objectOffset, vt2):
- existingVtable = vt2Offset
- break
-
- i -= 1
-
- if existingVtable is None:
+
+ vtKey = []
+ trim = True
+ for elem in reversed(self.current_vtable):
+ if elem == 0:
+ if trim:
+ continue
+ else:
+ elem = objectOffset - elem
+ trim = False
+
+ vtKey.append(elem)
+
+ vtKey = tuple(vtKey)
+ vt2Offset = self.vtables.get(vtKey)
+ if vt2Offset is None:
# Did not find a vtable, so write this one to the buffer.
# Write out the current vtable in reverse , because
# serialization occurs in last-first order:
i = len(self.current_vtable) - 1
+ trailing = 0
+ trim = True
while i >= 0:
off = 0
- if self.current_vtable[i] != 0:
+ elem = self.current_vtable[i]
+ i -= 1
+
+ if elem == 0:
+ if trim:
+ trailing += 1
+ continue
+ else:
# Forward reference to field;
# use 32bit number to ensure no overflow:
- off = objectOffset - self.current_vtable[i]
+ off = objectOffset - elem
+ trim = False
self.PrependVOffsetT(off)
- i -= 1
# The two metadata fields are written last.
@@ -245,7 +238,7 @@ class Builder(object):
self.PrependVOffsetT(VOffsetTFlags.py_type(objectSize))
# Second, store the vtable bytesize:
- vBytes = len(self.current_vtable) + VtableMetadataFields
+ vBytes = len(self.current_vtable) - trailing + VtableMetadataFields
vBytes *= N.VOffsetTFlags.bytewidth
self.PrependVOffsetT(VOffsetTFlags.py_type(vBytes))
@@ -257,17 +250,16 @@ class Builder(object):
# Finally, store this vtable in memory for future
# deduplication:
- self.vtables.append(self.Offset())
+ self.vtables[vtKey] = self.Offset()
else:
# Found a duplicate vtable.
-
objectStart = SOffsetTFlags.py_type(len(self.Bytes) - objectOffset)
self.head = UOffsetTFlags.py_type(objectStart)
# Write the offset to the found vtable in the
# already-allocated SOffsetT at the beginning of this object:
encode.Write(packer.soffset, self.Bytes, self.Head(),
- SOffsetTFlags.py_type(existingVtable - objectOffset))
+ SOffsetTFlags.py_type(vt2Offset - objectOffset))
self.current_vtable = None
return objectOffset
@@ -474,7 +466,7 @@ class Builder(object):
# tobytes ensures c_contiguous ordering
self.Bytes[self.Head():self.Head()+l] = x_lend.tobytes(order='C')
-
+
return self.EndVector(x.size)
## @cond FLATBUFFERS_INTERNAL
@@ -518,13 +510,28 @@ class Builder(object):
self.current_vtable[slotnum] = self.Offset()
## @endcond
- def __Finish(self, rootTable, sizePrefix):
+ def __Finish(self, rootTable, sizePrefix, file_identifier=None):
"""Finish finalizes a buffer, pointing to the given `rootTable`."""
N.enforce_number(rootTable, N.UOffsetTFlags)
+
prepSize = N.UOffsetTFlags.bytewidth
+ if file_identifier is not None:
+ prepSize += N.Int32Flags.bytewidth
if sizePrefix:
prepSize += N.Int32Flags.bytewidth
self.Prep(self.minalign, prepSize)
+
+ if file_identifier is not None:
+ self.Prep(N.UOffsetTFlags.bytewidth, encode.FILE_IDENTIFIER_LENGTH)
+
+ # Convert bytes object file_identifier to an array of 4 8-bit integers,
+ # and use big-endian to enforce size compliance.
+ # https://docs.python.org/2/library/struct.html#format-characters
+ file_identifier = N.struct.unpack(">BBBB", file_identifier)
+ for i in range(encode.FILE_IDENTIFIER_LENGTH-1, -1, -1):
+ # Place the bytes of the file_identifer in reverse order:
+ self.Place(file_identifier[i], N.Uint8Flags)
+
self.PrependUOffsetTRelative(rootTable)
if sizePrefix:
size = len(self.Bytes) - self.Head()
@@ -533,16 +540,16 @@ class Builder(object):
self.finished = True
return self.Head()
- def Finish(self, rootTable):
+ def Finish(self, rootTable, file_identifier=None):
"""Finish finalizes a buffer, pointing to the given `rootTable`."""
- return self.__Finish(rootTable, False)
+ return self.__Finish(rootTable, False, file_identifier=file_identifier)
- def FinishSizePrefixed(self, rootTable):
+ def FinishSizePrefixed(self, rootTable, file_identifier=None):
"""
Finish finalizes a buffer, pointing to the given `rootTable`,
with the size prefixed.
"""
- return self.__Finish(rootTable, True)
+ return self.__Finish(rootTable, True, file_identifier=file_identifier)
## @cond FLATBUFFERS_INTERNAL
def Prepend(self, flags, off):
@@ -552,7 +559,7 @@ class Builder(object):
def PrependSlot(self, flags, o, x, d):
N.enforce_number(x, flags)
N.enforce_number(d, flags)
- if x != d:
+ if x != d or self.forceDefaults:
self.Prepend(flags, x)
self.Slot(o)
@@ -589,7 +596,7 @@ class Builder(object):
be set to zero and no other data will be written.
"""
- if x != d:
+ if x != d or self.forceDefaults:
self.PrependUOffsetTRelative(x)
self.Slot(o)
@@ -691,6 +698,15 @@ class Builder(object):
"""
self.Prepend(N.Float64Flags, x)
+ def ForceDefaults(self, forceDefaults):
+ """
+ In order to save space, fields that are set to their default value
+ don't get serialized into the buffer. Forcing defaults provides a
+ way to manually disable this optimization. When set to `True`, will
+ always serialize default values.
+ """
+ self.forceDefaults = forceDefaults
+
##############################################################
## @cond FLATBUFFERS_INTERNAL
diff --git a/python/flatbuffers/encode.py b/python/flatbuffers/encode.py
index 3a330dd8..c4f1a59e 100644
--- a/python/flatbuffers/encode.py
+++ b/python/flatbuffers/encode.py
@@ -19,6 +19,8 @@ from .compat import import_numpy, NumpyRequiredForThisFeature
np = import_numpy()
+FILE_IDENTIFIER_LENGTH=4
+
def Get(packer_type, buf, head):
""" Get decodes a value at buf[head] using `packer_type`. """
return packer_type.unpack_from(memoryview_type(buf), head)[0]
diff --git a/python/flatbuffers/util.py b/python/flatbuffers/util.py
index abcb9c75..a5a78387 100644
--- a/python/flatbuffers/util.py
+++ b/python/flatbuffers/util.py
@@ -20,6 +20,21 @@ def GetSizePrefix(buf, offset):
"""Extract the size prefix from a buffer."""
return encode.Get(packer.int32, buf, offset)
+def GetBufferIdentifier(buf, offset, size_prefixed=False):
+ """Extract the file_identifier from a buffer"""
+ if size_prefixed:
+ # increase offset by size of UOffsetTFlags
+ offset += number_types.UOffsetTFlags.bytewidth
+ # increase offset by size of root table pointer
+ offset += number_types.UOffsetTFlags.bytewidth
+ # end of FILE_IDENTIFIER
+ end = offset + encode.FILE_IDENTIFIER_LENGTH
+ return buf[offset:end]
+
+def BufferHasIdentifier(buf, offset, file_identifier, size_prefixed=False):
+ got = GetBufferIdentifier(buf, offset, size_prefixed=size_prefixed)
+ return got == file_identifier
+
def RemoveSizePrefix(buf, offset):
"""
Create a slice of a size-prefixed buffer that has
diff --git a/python/setup.py b/python/setup.py
index 5aadef44..b3fc5665 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -47,11 +47,25 @@ setup(
license='Apache 2.0',
author='FlatBuffers Contributors',
author_email='me@rwinslow.com',
- url='https://github.com/google/flatbuffers',
- long_description=('Python runtime library for use with the Flatbuffers'
+ url='https://google.github.io/flatbuffers/',
+ long_description=('Python runtime library for use with the '
+ '`Flatbuffers <https://google.github.io/flatbuffers/>`_ '
'serialization format.'),
packages=['flatbuffers'],
include_package_data=True,
requires=[],
description='The FlatBuffers serialization format for Python',
-)
+ classifiers=[
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: Apache Software License',
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 3',
+ 'Topic :: Software Development :: Libraries :: Python Modules',
+ ],
+ project_urls={
+ 'Documentation': 'https://google.github.io/flatbuffers/',
+ 'Source': 'https://github.com/google/flatbuffers',
+ },
+) \ No newline at end of file
diff --git a/readme.md b/readme.md
index 3d5467eb..7cccfa1d 100644
--- a/readme.md
+++ b/readme.md
@@ -1,8 +1,12 @@
![logo](http://google.github.io/flatbuffers/fpl_logo_small.png) FlatBuffers
===========
+[![Build Status](https://travis-ci.org/google/flatbuffers.svg?branch=master)](https://travis-ci.org/google/flatbuffers)
+[![Build status](https://ci.appveyor.com/api/projects/status/yg5idd2fnusv1n10?svg=true)](https://ci.appveyor.com/project/gwvo/flatbuffers)
[![Join the chat at https://gitter.im/google/flatbuffers](https://badges.gitter.im/google/flatbuffers.svg)](https://gitter.im/google/flatbuffers?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-[![Build Status](https://travis-ci.org/google/flatbuffers.svg?branch=master)](https://travis-ci.org/google/flatbuffers) [![Build status](https://ci.appveyor.com/api/projects/status/yg5idd2fnusv1n10?svg=true)](https://ci.appveyor.com/project/gwvo/flatbuffers)
+[![Discord Chat](https://img.shields.io/discord/656202785926152206.svg)](https:///discord.gg/6qgKs3R)
+[![Twitter Follow](https://img.shields.io/twitter/follow/wvo.svg?style=social)](https://twitter.com/wvo)
+
**FlatBuffers** is a cross platform serialization library architected for
maximum memory efficiency. It allows you to directly access serialized data without parsing/unpacking it first, while still having great forwards/backwards compatibility.
diff --git a/reflection/generate_code.bat b/reflection/generate_code.bat
index e2993253..7b0f4d8d 100644
--- a/reflection/generate_code.bat
+++ b/reflection/generate_code.bat
@@ -15,4 +15,4 @@
set buildtype=Release
if "%1"=="-b" set buildtype=%2
-..\%buildtype%\flatc.exe --cpp --no-prefix -o ../include/flatbuffers reflection.fbs || exit /b 1
+..\%buildtype%\flatc.exe --cpp --cpp-std c++0x --no-prefix -o ../include/flatbuffers reflection.fbs || exit /b 1
diff --git a/reflection/generate_code.sh b/reflection/generate_code.sh
index f186b732..694baa2d 100755
--- a/reflection/generate_code.sh
+++ b/reflection/generate_code.sh
@@ -15,4 +15,17 @@
# limitations under the License.
set -e
-../flatc -c --no-prefix -o ../include/flatbuffers reflection.fbs
+tempDir="../include/flatbuffers/.tmp"
+originalFile="../include/flatbuffers/reflection_generated.h"
+newFile="$tempDir/reflection_generated.h"
+
+../flatc -c --cpp-std c++0x --no-prefix -o $tempDir reflection.fbs
+
+if [ -f "$newFile" ]; then
+ if ! cmp -s "$originalFile" "$newFile"; then
+ mv $newFile $originalFile
+ else
+ rm $newFile
+ fi
+ rmdir $tempDir
+fi
diff --git a/reflection/reflection.fbs b/reflection/reflection.fbs
index a344d7b8..8fed025f 100644
--- a/reflection/reflection.fbs
+++ b/reflection/reflection.fbs
@@ -23,15 +23,18 @@ enum BaseType : byte {
String,
Vector,
Obj, // Used for tables & structs.
- Union
+ Union,
+ Array
}
table Type {
base_type:BaseType;
- element:BaseType = None; // Only if base_type == Vector.
+ element:BaseType = None; // Only if base_type == Vector
+ // or base_type == Array.
index:int = -1; // If base_type == Object, index into "objects" below.
// If base_type == Union, UnionType, or integral derived
// from an enum, index into "enums" below.
+ fixed_length:uint16 = 0; // Only if base_type == Array.
}
table KeyValue {
diff --git a/rust/flatbuffers/Cargo.toml b/rust/flatbuffers/Cargo.toml
index 32d9b1b8..5202bd97 100644
--- a/rust/flatbuffers/Cargo.toml
+++ b/rust/flatbuffers/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "flatbuffers"
-version = "0.6.0"
+version = "0.6.2"
authors = ["Robert Winslow <hello@rwinslow.com>", "FlatBuffers Maintainers"]
license = "Apache-2.0"
description = "Official FlatBuffers Rust runtime library."
@@ -10,4 +10,4 @@ keywords = ["flatbuffers", "serialization", "zero-copy"]
categories = ["encoding", "data-structures", "memory-management"]
[dependencies]
-smallvec = "0.6"
+smallvec = "1.0"
diff --git a/rust/flatbuffers/src/builder.rs b/rust/flatbuffers/src/builder.rs
index f755a498..0b20f9ee 100644
--- a/rust/flatbuffers/src/builder.rs
+++ b/rust/flatbuffers/src/builder.rs
@@ -21,17 +21,17 @@ use std::marker::PhantomData;
use std::ptr::write_bytes;
use std::slice::from_raw_parts;
-use endian_scalar::{read_scalar, emplace_scalar};
+use endian_scalar::{emplace_scalar, read_scalar_at};
use primitives::*;
use push::{Push, PushAlignment};
use table::Table;
-use vtable::{VTable, field_index_to_field_offset};
-use vtable_writer::VTableWriter;
use vector::{SafeSliceAccess, Vector};
+use vtable::{field_index_to_field_offset, VTable};
+use vtable_writer::VTableWriter;
pub const N_SMALLVEC_STRING_VECTOR_CAPACITY: usize = 16;
-#[derive(Clone, Copy, Debug)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct FieldLoc {
off: UOffsetT,
id: VOffsetT,
@@ -40,6 +40,7 @@ struct FieldLoc {
/// FlatBufferBuilder builds a FlatBuffer through manipulating its internal
/// state. It has an owned `Vec<u8>` that grows as needed (up to the hardcoded
/// limit of 2GiB, which is set by the FlatBuffers format).
+#[derive(Clone, Debug, Eq, PartialEq)]
pub struct FlatBufferBuilder<'fbb> {
owned_buf: Vec<u8>,
head: usize,
@@ -68,8 +69,10 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
pub fn new_with_capacity(size: usize) -> Self {
// we need to check the size here because we create the backing buffer
// directly, bypassing the typical way of using grow_owned_buf:
- assert!(size <= FLATBUFFERS_MAX_BUFFER_SIZE,
- "cannot initialize buffer bigger than 2 gigabytes");
+ assert!(
+ size <= FLATBUFFERS_MAX_BUFFER_SIZE,
+ "cannot initialize buffer bigger than 2 gigabytes"
+ );
FlatBufferBuilder {
owned_buf: vec![0u8; size],
@@ -103,7 +106,9 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
{
let to_clear = self.owned_buf.len() - self.head;
let ptr = (&mut self.owned_buf[self.head..]).as_mut_ptr();
- unsafe { write_bytes(ptr, 0, to_clear); }
+ unsafe {
+ write_bytes(ptr, 0, to_clear);
+ }
}
self.head = self.owned_buf.len();
@@ -172,7 +177,9 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
/// Users probably want to use `push_slot` to add values after calling this.
#[inline]
pub fn start_table(&mut self) -> WIPOffset<TableUnfinishedWIPOffset> {
- self.assert_not_nested("start_table can not be called when a table or vector is under construction");
+ self.assert_not_nested(
+ "start_table can not be called when a table or vector is under construction",
+ );
self.nested = true;
WIPOffset::new(self.used_space() as UOffsetT)
@@ -182,7 +189,10 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
///
/// Asserts that the builder is in a nested state.
#[inline]
- pub fn end_table(&mut self, off: WIPOffset<TableUnfinishedWIPOffset>) -> WIPOffset<TableFinishedWIPOffset> {
+ pub fn end_table(
+ &mut self,
+ off: WIPOffset<TableUnfinishedWIPOffset>,
+ ) -> WIPOffset<TableFinishedWIPOffset> {
self.assert_nested("end_table");
let o = self.write_vtable(off);
@@ -202,7 +212,9 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
/// function will want to use `push` to add values.
#[inline]
pub fn start_vector<T: Push>(&mut self, num_items: usize) {
- self.assert_not_nested("start_vector can not be called when a table or vector is under construction");
+ self.assert_not_nested(
+ "start_vector can not be called when a table or vector is under construction",
+ );
self.nested = true;
self.align(num_items * T::size(), T::alignment().max_of(SIZE_UOFFSET));
}
@@ -226,14 +238,18 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
/// The wire format represents this as a zero-terminated byte vector.
#[inline]
pub fn create_string<'a: 'b, 'b>(&'a mut self, s: &'b str) -> WIPOffset<&'fbb str> {
- self.assert_not_nested("create_string can not be called when a table or vector is under construction");
+ self.assert_not_nested(
+ "create_string can not be called when a table or vector is under construction",
+ );
WIPOffset::new(self.create_byte_string(s.as_bytes()).value())
}
/// Create a zero-terminated byte vector.
#[inline]
pub fn create_byte_string(&mut self, data: &[u8]) -> WIPOffset<&'fbb [u8]> {
- self.assert_not_nested("create_byte_string can not be called when a table or vector is under construction");
+ self.assert_not_nested(
+ "create_byte_string can not be called when a table or vector is under construction",
+ );
self.align(data.len() + 1, PushAlignment::new(SIZE_UOFFSET));
self.push(0u8);
self.push_bytes_unprefixed(data);
@@ -248,8 +264,13 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
/// always safe, on any platform: bool, u8, i8, and any
/// FlatBuffers-generated struct.
#[inline]
- pub fn create_vector_direct<'a: 'b, 'b, T: SafeSliceAccess + Push + Sized + 'b>(&'a mut self, items: &'b [T]) -> WIPOffset<Vector<'fbb, T>> {
- self.assert_not_nested("create_vector_direct can not be called when a table or vector is under construction");
+ pub fn create_vector_direct<'a: 'b, 'b, T: SafeSliceAccess + Push + Sized + 'b>(
+ &'a mut self,
+ items: &'b [T],
+ ) -> WIPOffset<Vector<'fbb, T>> {
+ self.assert_not_nested(
+ "create_vector_direct can not be called when a table or vector is under construction",
+ );
let elem_size = T::size();
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
@@ -268,12 +289,18 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
/// Speed-sensitive users may wish to reduce memory usage by creating the
/// vector manually: use `start_vector`, `push`, and `end_vector`.
#[inline]
- pub fn create_vector_of_strings<'a, 'b>(&'a mut self, xs: &'b [&'b str]) -> WIPOffset<Vector<'fbb, ForwardsUOffset<&'fbb str>>> {
+ pub fn create_vector_of_strings<'a, 'b>(
+ &'a mut self,
+ xs: &'b [&'b str],
+ ) -> WIPOffset<Vector<'fbb, ForwardsUOffset<&'fbb str>>> {
self.assert_not_nested("create_vector_of_strings can not be called when a table or vector is under construction");
// internally, smallvec can be a stack-allocated or heap-allocated vector:
// if xs.len() > N_SMALLVEC_STRING_VECTOR_CAPACITY then it will overflow to the heap.
- let mut offsets: smallvec::SmallVec<[WIPOffset<&str>; N_SMALLVEC_STRING_VECTOR_CAPACITY]> = smallvec::SmallVec::with_capacity(xs.len());
- unsafe { offsets.set_len(xs.len()); }
+ let mut offsets: smallvec::SmallVec<[WIPOffset<&str>; N_SMALLVEC_STRING_VECTOR_CAPACITY]> =
+ smallvec::SmallVec::with_capacity(xs.len());
+ unsafe {
+ offsets.set_len(xs.len());
+ }
// note that this happens in reverse, because the buffer is built back-to-front:
for (i, &s) in xs.iter().enumerate().rev() {
@@ -288,7 +315,10 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
/// Speed-sensitive users may wish to reduce memory usage by creating the
/// vector manually: use `start_vector`, `push`, and `end_vector`.
#[inline]
- pub fn create_vector<'a: 'b, 'b, T: Push + Copy + 'b>(&'a mut self, items: &'b [T]) -> WIPOffset<Vector<'fbb, T::Output>> {
+ pub fn create_vector<'a: 'b, 'b, T: Push + Copy + 'b>(
+ &'a mut self,
+ items: &'b [T],
+ ) -> WIPOffset<Vector<'fbb, T::Output>> {
let elem_size = T::size();
self.align(items.len() * elem_size, T::alignment().max_of(SIZE_UOFFSET));
for i in (0..items.len()).rev() {
@@ -314,10 +344,12 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
///
/// This is somewhat low-level and is mostly used by the generated code.
#[inline]
- pub fn required(&self,
- tab_revloc: WIPOffset<TableFinishedWIPOffset>,
- slot_byte_loc: VOffsetT,
- assert_msg_name: &'static str) {
+ pub fn required(
+ &self,
+ tab_revloc: WIPOffset<TableFinishedWIPOffset>,
+ slot_byte_loc: VOffsetT,
+ assert_msg_name: &'static str,
+ ) {
let idx = self.used_space() - tab_revloc.value() as usize;
let tab = Table::new(&self.owned_buf[self.head..], idx);
let o = tab.vtable().get(slot_byte_loc) as usize;
@@ -357,21 +389,21 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
#[inline]
fn track_field(&mut self, slot_off: VOffsetT, off: UOffsetT) {
- let fl = FieldLoc {
- id: slot_off,
- off: off,
- };
+ let fl = FieldLoc { id: slot_off, off };
self.field_locs.push(fl);
}
/// Write the VTable, if it is new.
- fn write_vtable(&mut self, table_tail_revloc: WIPOffset<TableUnfinishedWIPOffset>) -> WIPOffset<VTableWIPOffset> {
+ fn write_vtable(
+ &mut self,
+ table_tail_revloc: WIPOffset<TableUnfinishedWIPOffset>,
+ ) -> WIPOffset<VTableWIPOffset> {
self.assert_nested("write_vtable");
// Write the vtable offset, which is the start of any Table.
// We fill its value later.
let object_revloc_to_vtable: WIPOffset<VTableWIPOffset> =
- WIPOffset::new(self.push::<UOffsetT>(0xF0F0F0F0 as UOffsetT).value());
+ WIPOffset::new(self.push::<UOffsetT>(0xF0F0_F0F0 as UOffsetT).value());
// Layout of the data this function will create when a new vtable is
// needed.
@@ -432,9 +464,11 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
// serialize every FieldLoc to the vtable:
for &fl in self.field_locs.iter() {
let pos: VOffsetT = (object_revloc_to_vtable.value() - fl.off) as VOffsetT;
- debug_assert_eq!(vtfw.get_field_offset(fl.id),
- 0,
- "tried to write a vtable field multiple times");
+ debug_assert_eq!(
+ vtfw.get_field_offset(fl.id),
+ 0,
+ "tried to write a vtable field multiple times"
+ );
vtfw.write_field_offset(fl.id, pos);
}
}
@@ -458,10 +492,12 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
{
let n = self.head + self.used_space() - object_revloc_to_vtable.value() as usize;
- let saw = read_scalar::<UOffsetT>(&self.owned_buf[n..n + SIZE_SOFFSET]);
- debug_assert_eq!(saw, 0xF0F0F0F0);
- emplace_scalar::<SOffsetT>(&mut self.owned_buf[n..n + SIZE_SOFFSET],
- vt_use as SOffsetT - object_revloc_to_vtable.value() as SOffsetT);
+ let saw = read_scalar_at::<UOffsetT>(&self.owned_buf, n);
+ debug_assert_eq!(saw, 0xF0F0_F0F0);
+ emplace_scalar::<SOffsetT>(
+ &mut self.owned_buf[n..n + SIZE_SOFFSET],
+ vt_use as SOffsetT - object_revloc_to_vtable.value() as SOffsetT,
+ );
}
self.field_locs.clear();
@@ -472,7 +508,10 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
#[inline]
fn find_duplicate_stored_vtable_revloc(&self, needle: VTable) -> Option<UOffsetT> {
for &revloc in self.written_vtable_revpos.iter().rev() {
- let o = VTable::init(&self.owned_buf[..], self.head + self.used_space() - revloc as usize);
+ let o = VTable::init(
+ &self.owned_buf[..],
+ self.head + self.used_space() - revloc as usize,
+ );
if needle == o {
return Some(revloc);
}
@@ -509,18 +548,24 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
// finally, zero out the old end data.
{
let ptr = (&mut self.owned_buf[..middle]).as_mut_ptr();
- unsafe { write_bytes(ptr, 0, middle); }
+ unsafe {
+ write_bytes(ptr, 0, middle);
+ }
}
}
// with or without a size prefix changes how we load the data, so finish*
// functions are split along those lines.
- fn finish_with_opts<T>(&mut self,
- root: WIPOffset<T>,
- file_identifier: Option<&str>,
- size_prefixed: bool) {
+ fn finish_with_opts<T>(
+ &mut self,
+ root: WIPOffset<T>,
+ file_identifier: Option<&str>,
+ size_prefixed: bool,
+ ) {
self.assert_not_finished("buffer cannot be finished when it is already finished");
- self.assert_not_nested("buffer cannot be finished when a table or vector is under construction");
+ self.assert_not_nested(
+ "buffer cannot be finished when a table or vector is under construction",
+ );
self.written_vtable_revpos.clear();
let to_align = {
@@ -571,7 +616,7 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
#[inline]
fn push_bytes_unprefixed(&mut self, x: &[u8]) -> UOffsetT {
let n = self.make_space(x.len());
- &mut self.owned_buf[n..n + x.len()].copy_from_slice(x);
+ self.owned_buf[n..n + x.len()].copy_from_slice(x);
n as UOffsetT
}
@@ -588,8 +633,10 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
if self.unused_ready_space() >= want {
return want;
}
- assert!(want <= FLATBUFFERS_MAX_BUFFER_SIZE,
- "cannot grow buffer beyond 2 gigabytes");
+ assert!(
+ want <= FLATBUFFERS_MAX_BUFFER_SIZE,
+ "cannot grow buffer beyond 2 gigabytes"
+ );
while self.unused_ready_space() < want {
self.grow_owned_buf();
@@ -604,7 +651,13 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
fn assert_nested(&self, fn_name: &'static str) {
// we don't assert that self.field_locs.len() >0 because the vtable
// could be empty (e.g. for empty tables, or for all-default values).
- debug_assert!(self.nested, format!("incorrect FlatBufferBuilder usage: {} must be called while in a nested state", fn_name));
+ debug_assert!(
+ self.nested,
+ format!(
+ "incorrect FlatBufferBuilder usage: {} must be called while in a nested state",
+ fn_name
+ )
+ );
}
#[inline]
fn assert_not_nested(&self, msg: &'static str) {
@@ -618,7 +671,6 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
fn assert_not_finished(&self, msg: &'static str) {
debug_assert!(!self.finished, msg);
}
-
}
/// Compute the length of the vtable needed to represent the provided FieldLocs.
@@ -628,8 +680,8 @@ impl<'fbb> FlatBufferBuilder<'fbb> {
fn get_vtable_byte_len(field_locs: &[FieldLoc]) -> usize {
let max_voffset = field_locs.iter().map(|fl| fl.id).max();
match max_voffset {
- None => { field_index_to_field_offset(0) as usize }
- Some(mv) => { mv as usize + SIZE_VOFFSET }
+ None => field_index_to_field_offset(0) as usize,
+ Some(mv) => mv as usize + SIZE_VOFFSET,
}
}
@@ -638,3 +690,9 @@ fn padding_bytes(buf_size: usize, scalar_size: usize) -> usize {
// ((!buf_size) + 1) & (scalar_size - 1)
(!buf_size).wrapping_add(1) & (scalar_size.wrapping_sub(1))
}
+
+impl<'fbb> Default for FlatBufferBuilder<'fbb> {
+ fn default() -> Self {
+ Self::new_with_capacity(0)
+ }
+}
diff --git a/rust/flatbuffers/src/endian_scalar.rs b/rust/flatbuffers/src/endian_scalar.rs
index 3e7244e0..df0b384a 100644
--- a/rust/flatbuffers/src/endian_scalar.rs
+++ b/rust/flatbuffers/src/endian_scalar.rs
@@ -34,7 +34,7 @@ pub trait EndianScalar: Sized + PartialEq + Copy + Clone {
/// Macro for implementing a no-op endian conversion. This is used for types
/// that are one byte wide.
macro_rules! impl_endian_scalar_noop {
- ($ty:ident) => (
+ ($ty:ident) => {
impl EndianScalar for $ty {
#[inline]
fn to_little_endian(self) -> Self {
@@ -45,7 +45,7 @@ macro_rules! impl_endian_scalar_noop {
self
}
}
- )
+ };
}
/// Macro for implementing an endian conversion using the stdlib `to_le` and
@@ -53,7 +53,7 @@ macro_rules! impl_endian_scalar_noop {
/// floats, because the `to_le` and `from_le` are not implemented for them in
/// the stdlib.
macro_rules! impl_endian_scalar_stdlib_le_conversion {
- ($ty:ident) => (
+ ($ty:ident) => {
impl EndianScalar for $ty {
#[inline]
fn to_little_endian(self) -> Self {
@@ -64,7 +64,7 @@ macro_rules! impl_endian_scalar_stdlib_le_conversion {
Self::from_le(self)
}
}
- )
+ };
}
impl_endian_scalar_noop!(bool);
@@ -177,4 +177,3 @@ pub fn read_scalar<T: EndianScalar>(s: &[u8]) -> T {
x.from_little_endian()
}
-
diff --git a/rust/flatbuffers/src/lib.rs b/rust/flatbuffers/src/lib.rs
index 5e304344..a1d2745e 100644
--- a/rust/flatbuffers/src/lib.rs
+++ b/rust/flatbuffers/src/lib.rs
@@ -39,12 +39,14 @@ mod vtable;
mod vtable_writer;
pub use builder::FlatBufferBuilder;
-pub use endian_scalar::{EndianScalar, emplace_scalar, read_scalar, read_scalar_at, byte_swap_f32, byte_swap_f64};
+pub use endian_scalar::{
+ byte_swap_f32, byte_swap_f64, emplace_scalar, read_scalar, read_scalar_at, EndianScalar,
+};
pub use follow::{Follow, FollowStart};
pub use primitives::*;
pub use push::Push;
-pub use table::{Table, buffer_has_identifier, get_root, get_size_prefixed_root};
-pub use vector::{SafeSliceAccess, Vector, follow_cast_ref};
+pub use table::{buffer_has_identifier, get_root, get_size_prefixed_root, Table};
+pub use vector::{follow_cast_ref, SafeSliceAccess, Vector, VectorIter};
pub use vtable::field_index_to_field_offset;
// TODO(rw): Unify `create_vector` and `create_vector_direct` by using
diff --git a/rust/flatbuffers/src/primitives.rs b/rust/flatbuffers/src/primitives.rs
index 59176b8f..06a22eae 100644
--- a/rust/flatbuffers/src/primitives.rs
+++ b/rust/flatbuffers/src/primitives.rs
@@ -60,15 +60,19 @@ pub type UOffsetT = u32;
pub type VOffsetT = i16;
/// TableFinishedWIPOffset marks a WIPOffset as being for a finished table.
+#[derive(Clone, Copy)]
pub struct TableFinishedWIPOffset {}
/// TableUnfinishedWIPOffset marks a WIPOffset as being for an unfinished table.
+#[derive(Clone, Copy)]
pub struct TableUnfinishedWIPOffset {}
/// UnionWIPOffset marks a WIPOffset as being for a union value.
+#[derive(Clone, Copy)]
pub struct UnionWIPOffset {}
/// VTableWIPOffset marks a WIPOffset as being for a vtable.
+#[derive(Clone, Copy)]
pub struct VTableWIPOffset {}
/// WIPOffset contains an UOffsetT with a special meaning: it is the location of
@@ -78,15 +82,18 @@ pub struct VTableWIPOffset {}
#[derive(Debug)]
pub struct WIPOffset<T>(UOffsetT, PhantomData<T>);
-// TODO(rw): why do we need to reimplement (with a default impl) Copy to
-// avoid ownership errors?
+// We cannot use derive for these two impls, as the derived impls would only
+// implement `Copy` and `Clone` for `T: Copy` and `T: Clone` respectively.
+// However `WIPOffset<T>` can always be copied, no matter that `T` you
+// have.
impl<T> Copy for WIPOffset<T> {}
impl<T> Clone for WIPOffset<T> {
- #[inline]
- fn clone(&self) -> WIPOffset<T> {
- WIPOffset::new(self.0.clone())
+ #[inline(always)]
+ fn clone(&self) -> Self {
+ *self
}
}
+
impl<T> PartialEq for WIPOffset<T> {
fn eq(&self, o: &WIPOffset<T>) -> bool {
self.value() == o.value()
@@ -113,12 +120,12 @@ impl<'a, T: 'a> WIPOffset<T> {
/// Return a wrapped value that brings its meaning as a union WIPOffset
/// into the type system.
#[inline(always)]
- pub fn as_union_value(&self) -> WIPOffset<UnionWIPOffset> {
+ pub fn as_union_value(self) -> WIPOffset<UnionWIPOffset> {
WIPOffset::new(self.0)
}
/// Get the underlying value.
#[inline(always)]
- pub fn value(&self) -> UOffsetT {
+ pub fn value(self) -> UOffsetT {
self.0
}
}
@@ -146,9 +153,22 @@ impl<T> Push for ForwardsUOffset<T> {
/// is incremented by the value contained in this type.
#[derive(Debug)]
pub struct ForwardsUOffset<T>(UOffsetT, PhantomData<T>);
+
+// We cannot use derive for these two impls, as the derived impls would only
+// implement `Copy` and `Clone` for `T: Copy` and `T: Clone` respectively.
+// However `ForwardsUOffset<T>` can always be copied, no matter that `T` you
+// have.
+impl<T> Copy for ForwardsUOffset<T> {}
+impl<T> Clone for ForwardsUOffset<T> {
+ #[inline(always)]
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
impl<T> ForwardsUOffset<T> {
#[inline(always)]
- pub fn value(&self) -> UOffsetT {
+ pub fn value(self) -> UOffsetT {
self.0
}
}
@@ -268,13 +288,21 @@ impl<'a, T: Follow<'a> + 'a> Follow<'a> for SkipFileIdentifier<T> {
}
}
+impl<'a> Follow<'a> for bool {
+ type Inner = bool;
+ #[inline(always)]
+ fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+ read_scalar_at::<u8>(buf, loc) != 0
+ }
+}
+
/// Follow trait impls for primitive types.
///
/// Ideally, these would be implemented as a single impl using trait bounds on
/// EndianScalar, but implementing Follow that way causes a conflict with
/// other impls.
macro_rules! impl_follow_for_endian_scalar {
- ($ty:ident) => (
+ ($ty:ident) => {
impl<'a> Follow<'a> for $ty {
type Inner = $ty;
#[inline(always)]
@@ -282,10 +310,9 @@ macro_rules! impl_follow_for_endian_scalar {
read_scalar_at::<$ty>(buf, loc)
}
}
- )
+ };
}
-impl_follow_for_endian_scalar!(bool);
impl_follow_for_endian_scalar!(u8);
impl_follow_for_endian_scalar!(u16);
impl_follow_for_endian_scalar!(u32);
diff --git a/rust/flatbuffers/src/push.rs b/rust/flatbuffers/src/push.rs
index 2b307a3a..18630589 100644
--- a/rust/flatbuffers/src/push.rs
+++ b/rust/flatbuffers/src/push.rs
@@ -55,7 +55,7 @@ impl PushAlignment {
/// Macro to implement Push for EndianScalar types.
macro_rules! impl_push_for_endian_scalar {
- ($ty:ident) => (
+ ($ty:ident) => {
impl Push for $ty {
type Output = $ty;
@@ -63,9 +63,8 @@ macro_rules! impl_push_for_endian_scalar {
fn push(&self, dst: &mut [u8], _rest: &[u8]) {
emplace_scalar::<$ty>(dst, *self);
}
-
}
- )
+ };
}
impl_push_for_endian_scalar!(bool);
diff --git a/rust/flatbuffers/src/table.rs b/rust/flatbuffers/src/table.rs
index 7b1c4a54..397d24c6 100644
--- a/rust/flatbuffers/src/table.rs
+++ b/rust/flatbuffers/src/table.rs
@@ -27,7 +27,7 @@ pub struct Table<'a> {
impl<'a> Table<'a> {
#[inline]
pub fn new(buf: &'a [u8], loc: usize) -> Self {
- Table { buf: buf, loc: loc }
+ Table { buf, loc }
}
#[inline]
pub fn vtable(&self) -> VTable<'a> {
@@ -51,7 +51,7 @@ impl<'a> Follow<'a> for Table<'a> {
type Inner = Table<'a>;
#[inline]
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
- Table { buf: buf, loc: loc }
+ Table { buf, loc }
}
}
diff --git a/rust/flatbuffers/src/vector.rs b/rust/flatbuffers/src/vector.rs
index 397089a6..d1921438 100644
--- a/rust/flatbuffers/src/vector.rs
+++ b/rust/flatbuffers/src/vector.rs
@@ -14,20 +14,31 @@
* limitations under the License.
*/
+use std::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
use std::marker::PhantomData;
use std::mem::size_of;
use std::slice::from_raw_parts;
use std::str::from_utf8_unchecked;
+use endian_scalar::read_scalar_at;
#[cfg(target_endian = "little")]
use endian_scalar::EndianScalar;
-use endian_scalar::read_scalar;
use follow::Follow;
use primitives::*;
#[derive(Debug)]
pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
+// We cannot use derive for these two impls, as it would only implement Copy
+// and Clone for `T: Copy` and `T: Clone` respectively. However `Vector<'a, T>`
+// can always be copied, no matter that `T` you have.
+impl<'a, T> Copy for Vector<'a, T> {}
+impl<'a, T> Clone for Vector<'a, T> {
+ fn clone(&self) -> Self {
+ *self
+ }
+}
+
impl<'a, T: 'a> Vector<'a, T> {
#[inline(always)]
pub fn new(buf: &'a [u8], loc: usize) -> Self {
@@ -40,18 +51,27 @@ impl<'a, T: 'a> Vector<'a, T> {
#[inline(always)]
pub fn len(&self) -> usize {
- read_scalar::<UOffsetT>(&self.0[self.1 as usize..]) as usize
+ read_scalar_at::<UOffsetT>(&self.0, self.1) as usize
+ }
+ #[inline(always)]
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
}
}
impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
#[inline(always)]
pub fn get(&self, idx: usize) -> T::Inner {
- debug_assert!(idx < read_scalar::<u32>(&self.0[self.1 as usize..]) as usize);
+ debug_assert!(idx < read_scalar_at::<u32>(&self.0, self.1) as usize);
let sz = size_of::<T>();
debug_assert!(sz > 0);
T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx)
}
+
+ #[inline(always)]
+ pub fn iter(&self) -> VectorIter<'a, T> {
+ VectorIter::new(*self)
+ }
}
pub trait SafeSliceAccess {}
@@ -61,7 +81,7 @@ impl<'a, T: SafeSliceAccess + 'a> Vector<'a, T> {
let loc = self.1;
let sz = size_of::<T>();
debug_assert!(sz > 0);
- let len = read_scalar::<UOffsetT>(&buf[loc..loc + SIZE_UOFFSET]) as usize;
+ let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
let ptr = data_buf.as_ptr() as *const T;
let s: &'a [T] = unsafe { from_raw_parts(ptr, len) };
@@ -100,10 +120,9 @@ pub fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
impl<'a> Follow<'a> for &'a str {
type Inner = &'a str;
fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
- let len = read_scalar::<UOffsetT>(&buf[loc..loc + SIZE_UOFFSET]) as usize;
+ let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
- let s = unsafe { from_utf8_unchecked(slice) };
- s
+ unsafe { from_utf8_unchecked(slice) }
}
}
@@ -111,7 +130,7 @@ impl<'a> Follow<'a> for &'a str {
fn follow_slice_helper<T>(buf: &[u8], loc: usize) -> &[T] {
let sz = size_of::<T>();
debug_assert!(sz > 0);
- let len = read_scalar::<UOffsetT>(&buf[loc..loc + SIZE_UOFFSET]) as usize;
+ let len = read_scalar_at::<UOffsetT>(&buf, loc) as usize;
let data_buf = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len * sz];
let ptr = data_buf.as_ptr() as *const T;
let s: &[T] = unsafe { from_raw_parts(ptr, len) };
@@ -135,3 +154,123 @@ impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
}
}
+/// An iterator over a `Vector`.
+#[derive(Debug)]
+pub struct VectorIter<'a, T: 'a> {
+ buf: &'a [u8],
+ loc: usize,
+ remaining: usize,
+ phantom: PhantomData<T>,
+}
+
+impl<'a, T: 'a> VectorIter<'a, T> {
+ #[inline]
+ pub fn new(inner: Vector<'a, T>) -> Self {
+ VectorIter {
+ buf: inner.0,
+ // inner.1 is the location of the data for the vector.
+ // The first SIZE_UOFFSET bytes is the length. We skip
+ // that to get to the actual vector content.
+ loc: inner.1 + SIZE_UOFFSET,
+ remaining: inner.len(),
+ phantom: PhantomData,
+ }
+ }
+}
+
+impl<'a, T: Follow<'a> + 'a> Clone for VectorIter<'a, T> {
+ #[inline]
+ fn clone(&self) -> Self {
+ VectorIter {
+ buf: self.buf,
+ loc: self.loc,
+ remaining: self.remaining,
+ phantom: self.phantom,
+ }
+ }
+}
+
+impl<'a, T: Follow<'a> + 'a> Iterator for VectorIter<'a, T> {
+ type Item = T::Inner;
+
+ #[inline]
+ fn next(&mut self) -> Option<T::Inner> {
+ let sz = size_of::<T>();
+ debug_assert!(sz > 0);
+
+ if self.remaining == 0 {
+ None
+ } else {
+ let result = T::follow(self.buf, self.loc);
+ self.loc += sz;
+ self.remaining -= 1;
+ Some(result)
+ }
+ }
+
+ #[inline]
+ fn nth(&mut self, n: usize) -> Option<T::Inner> {
+ let sz = size_of::<T>();
+ debug_assert!(sz > 0);
+
+ self.remaining = self.remaining.saturating_sub(n);
+
+ // Note that this might overflow, but that is okay because
+ // in that case self.remaining will have been set to zero.
+ self.loc = self.loc.wrapping_add(sz * n);
+
+ self.next()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.remaining, Some(self.remaining))
+ }
+}
+
+impl<'a, T: Follow<'a> + 'a> DoubleEndedIterator for VectorIter<'a, T> {
+ #[inline]
+ fn next_back(&mut self) -> Option<T::Inner> {
+ let sz = size_of::<T>();
+ debug_assert!(sz > 0);
+
+ if self.remaining == 0 {
+ None
+ } else {
+ self.remaining -= 1;
+ Some(T::follow(self.buf, self.loc + sz * self.remaining))
+ }
+ }
+
+ #[inline]
+ fn nth_back(&mut self, n: usize) -> Option<T::Inner> {
+ self.remaining = self.remaining.saturating_sub(n);
+ self.next_back()
+ }
+}
+
+impl<'a, T: 'a + Follow<'a>> ExactSizeIterator for VectorIter<'a, T> {
+ #[inline]
+ fn len(&self) -> usize {
+ self.remaining
+ }
+}
+
+impl<'a, T: 'a + Follow<'a>> FusedIterator for VectorIter<'a, T> {}
+
+impl<'a, T: Follow<'a> + 'a> IntoIterator for Vector<'a, T> {
+ type Item = T::Inner;
+ type IntoIter = VectorIter<'a, T>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
+
+impl<'a, 'b, T: Follow<'a> + 'a> IntoIterator for &'b Vector<'a, T> {
+ type Item = T::Inner;
+ type IntoIter = VectorIter<'a, T>;
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
diff --git a/rust/flatbuffers/src/vtable.rs b/rust/flatbuffers/src/vtable.rs
index cd7ede6e..f8f266a0 100644
--- a/rust/flatbuffers/src/vtable.rs
+++ b/rust/flatbuffers/src/vtable.rs
@@ -34,10 +34,7 @@ impl<'a> PartialEq for VTable<'a> {
impl<'a> VTable<'a> {
pub fn init(buf: &'a [u8], loc: usize) -> Self {
- VTable {
- buf: buf,
- loc: loc,
- }
+ VTable { buf, loc }
}
pub fn num_fields(&self) -> usize {
(self.num_bytes() / SIZE_VOFFSET) - 2
@@ -72,7 +69,6 @@ impl<'a> VTable<'a> {
}
}
-
#[allow(dead_code)]
pub fn field_index_to_field_offset(field_id: VOffsetT) -> VOffsetT {
// Should correspond to what end_table() below builds up.
diff --git a/rust/flatbuffers/src/vtable_writer.rs b/rust/flatbuffers/src/vtable_writer.rs
index 119f794c..f065fdd0 100644
--- a/rust/flatbuffers/src/vtable_writer.rs
+++ b/rust/flatbuffers/src/vtable_writer.rs
@@ -16,7 +16,7 @@
use std::ptr::write_bytes;
-use endian_scalar::{emplace_scalar, read_scalar};
+use endian_scalar::{emplace_scalar, read_scalar_at};
use primitives::*;
/// VTableWriter compartmentalizes actions needed to create a vtable.
@@ -28,7 +28,7 @@ pub struct VTableWriter<'a> {
impl<'a> VTableWriter<'a> {
#[inline(always)]
pub fn init(buf: &'a mut [u8]) -> Self {
- VTableWriter { buf: buf }
+ VTableWriter { buf }
}
/// Writes the vtable length (in bytes) into the vtable.
@@ -57,7 +57,7 @@ impl<'a> VTableWriter<'a> {
#[inline(always)]
pub fn get_field_offset(&self, vtable_offset: VOffsetT) -> VOffsetT {
let idx = vtable_offset as usize;
- read_scalar::<VOffsetT>(&self.buf[idx..idx + SIZE_VOFFSET])
+ read_scalar_at::<VOffsetT>(&self.buf, idx)
}
/// Writes an object field offset into the vtable.
@@ -82,4 +82,3 @@ impl<'a> VTableWriter<'a> {
}
}
}
-
diff --git a/samples/SampleBinary.java b/samples/SampleBinary.java
index 555194f3..f7052ae9 100644
--- a/samples/SampleBinary.java
+++ b/samples/SampleBinary.java
@@ -95,6 +95,12 @@ class SampleBinary {
assert monster.weapons(i).damage() == expectedWeaponDamages[i];
}
+ Weapon.Vector weaponsVector = monster.weaponsVector();
+ for (int i = 0; i < weaponsVector.length(); i++) {
+ assert weaponsVector.get(i).name().equals(expectedWeaponNames[i]);
+ assert weaponsVector.get(i).damage() == expectedWeaponDamages[i];
+ }
+
// Get and test the `equipped` FlatBuffer `union`.
assert monster.equippedType() == Equipment.Weapon;
Weapon equipped = (Weapon)monster.equipped(new Weapon());
diff --git a/samples/SampleBinary.kt b/samples/SampleBinary.kt
new file mode 100644
index 00000000..2974f36a
--- /dev/null
+++ b/samples/SampleBinary.kt
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2015 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Run this file with the `java_sample.sh` script.
+
+import MyGame.Sample.Color
+import MyGame.Sample.Equipment
+import MyGame.Sample.Monster
+import MyGame.Sample.Vec3
+import MyGame.Sample.Weapon
+
+import com.google.flatbuffers.FlatBufferBuilder
+
+class SampleBinary {
+
+ companion object {
+ // Example how to use FlatBuffers to create and read binary buffers.
+ @JvmStatic
+ fun main(args: Array<String>) {
+ val builder = FlatBufferBuilder(0)
+
+ // Create some weapons for our Monster ('Sword' and 'Axe').
+ val weaponOneName = builder.createString("Sword")
+ val weaponOneDamage: Short = 3
+ val weaponTwoName = builder.createString("Axe")
+ val weaponTwoDamage: Short = 5
+
+ // Use the `createWeapon()` helper function to create the weapons, since we set every field.
+ val weaps = IntArray(2)
+ weaps[0] = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage)
+ weaps[1] = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage)
+
+ // Serialize the FlatBuffer data.
+ val name = builder.createString("Orc")
+ val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
+ val inv = Monster.createInventoryVector(builder, treasure)
+ val weapons = Monster.createWeaponsVector(builder, weaps)
+ val pos = Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)
+
+ Monster.startMonster(builder)
+ Monster.addPos(builder, pos)
+ Monster.addName(builder, name)
+ Monster.addColor(builder, Color.Red)
+ Monster.addHp(builder, 300.toShort())
+ Monster.addInventory(builder, inv)
+ Monster.addWeapons(builder, weapons)
+ Monster.addEquippedType(builder, Equipment.Weapon)
+ Monster.addEquipped(builder, weaps[1])
+ val orc = Monster.endMonster(builder)
+
+ builder.finish(orc) // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
+
+ // We now have a FlatBuffer that can be stored on disk or sent over a network.
+
+ // ...Code to store to disk or send over a network goes here...
+
+ // Instead, we are going to access it right away, as if we just received it.
+
+ val buf = builder.dataBuffer()
+
+ // Get access to the root:
+ val monster = Monster.getRootAsMonster(buf)
+
+ // Note: We did not set the `mana` field explicitly, so we get back the default value.
+ assert(monster.mana == 150.toShort())
+ assert(monster.hp == 300.toShort())
+ assert(monster.name.equals("Orc"))
+ assert(monster.color == Color.Red)
+ assert(monster.pos!!.x == 1.0f)
+ assert(monster.pos!!.y == 2.0f)
+ assert(monster.pos!!.z == 3.0f)
+
+ // Get and test the `inventory` FlatBuffer `vector`.
+ for (i in 0 until monster.inventoryLength) {
+ assert(monster.inventory(i) == i.toByte().toInt())
+ }
+
+ // Get and test the `weapons` FlatBuffer `vector` of `table`s.
+ val expectedWeaponNames = arrayOf("Sword", "Axe")
+ val expectedWeaponDamages = intArrayOf(3, 5)
+ for (i in 0 until monster.weaponsLength) {
+ assert(monster.weapons(i)!!.name.equals(expectedWeaponNames[i]))
+ assert(monster.weapons(i)!!.damage.toInt() == expectedWeaponDamages[i])
+ }
+
+ // Get and test the `equipped` FlatBuffer `union`.
+ assert(monster.equippedType == Equipment.Weapon)
+ val equipped = monster.equipped(Weapon()) as Weapon?
+ assert(equipped!!.name.equals("Axe"))
+ assert(equipped.damage == 5.toShort())
+
+ println("The FlatBuffer was successfully created and verified!")
+ }
+ }
+}
diff --git a/samples/android/jni/main.cpp b/samples/android/jni/main.cpp
index 87580272..0785a2bc 100644
--- a/samples/android/jni/main.cpp
+++ b/samples/android/jni/main.cpp
@@ -17,9 +17,7 @@
#include "android_native_app_glue.h"
#include "animal_generated.h" // Includes "flatbuffers/flatbuffers.h".
-void android_main(android_app *app) {
- app_dummy();
-
+void android_main(android_app *) {
flatbuffers::FlatBufferBuilder builder;
auto name = builder.CreateString("Dog");
auto sound = builder.CreateString("Bark");
diff --git a/samples/kotlin_sample.sh b/samples/kotlin_sample.sh
new file mode 100755
index 00000000..ca4ea86d
--- /dev/null
+++ b/samples/kotlin_sample.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+#
+# Copyright 2015 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Note: This script runs on Mac and Linux. It requires `kotlin` to be installed
+# and `flatc` to be built (using `cmake` in the root directory).
+
+sampledir=$(cd $(dirname $BASH_SOURCE) && pwd)
+rootdir=$(cd $sampledir/.. && pwd)
+currentdir=$(pwd)
+
+if [[ "$sampledir" != "$currentdir" ]]; then
+ echo Error: This script must be run from inside the $sampledir directory.
+ echo You executed it from the $currentdir directory.
+ exit 1
+fi
+
+# Run `flatc`. Note: This requires you to compile using `cmake` from the
+# root `/flatbuffers` directory.
+if [ -e ../flatc ]; then
+ echo "compiling now"
+ ../flatc --kotlin --gen-mutable monster.fbs
+elif [ -e ../Debug/flatc ]; then
+ ../Debug/flatc --kotlin --gen-mutable monster.fbs
+else
+ echo 'flatc' could not be found. Make sure to build FlatBuffers from the \
+ $rootdir directory.
+ exit 1
+fi
+
+echo Compiling and running the Kotlin sample
+
+all_kt_files=`find $sampledir -name "*.kt" -print`
+# Run test
+mkdir -v "${sampledir}/kotlin"
+echo Compiling Java Runtime
+javac ${rootdir}/java/com/google/flatbuffers/*.java -d ${sampledir}/kotlin
+echo Compiling Kotlin source
+kotlinc -classpath ${sampledir}/../java:${sampledir}/kotlin $all_kt_files SampleBinary.kt -include-runtime -d ${sampledir}/kotlin
+# Make jar
+echo Making jar
+jar cvf ${sampledir}/kotlin/kotlin_sample.jar -C ${sampledir}/kotlin . > /dev/null
+echo Running test
+kotlin -cp ${sampledir}/kotlin/kotlin_sample.jar SampleBinary
+
+# Cleanup temporary files.
+rm -rf MyGame/
+# rm -rf ${sampledir}/kotlin
diff --git a/samples/monster_generated.h b/samples/monster_generated.h
index 7026116d..4e49d5f9 100644
--- a/samples/monster_generated.h
+++ b/samples/monster_generated.h
@@ -12,9 +12,11 @@ namespace Sample {
struct Vec3;
struct Monster;
+struct MonsterBuilder;
struct MonsterT;
struct Weapon;
+struct WeaponBuilder;
struct WeaponT;
bool operator==(const Vec3 &lhs, const Vec3 &rhs);
@@ -48,7 +50,7 @@ inline const Color (&EnumValuesColor())[3] {
}
inline const char * const *EnumNamesColor() {
- static const char * const names[] = {
+ static const char * const names[4] = {
"Red",
"Green",
"Blue",
@@ -58,7 +60,7 @@ inline const char * const *EnumNamesColor() {
}
inline const char *EnumNameColor(Color e) {
- if (e < Color_Red || e > Color_Blue) return "";
+ if (flatbuffers::IsOutRange(e, Color_Red, Color_Blue)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesColor()[index];
}
@@ -79,7 +81,7 @@ inline const Equipment (&EnumValuesEquipment())[2] {
}
inline const char * const *EnumNamesEquipment() {
- static const char * const names[] = {
+ static const char * const names[3] = {
"NONE",
"Weapon",
nullptr
@@ -88,7 +90,7 @@ inline const char * const *EnumNamesEquipment() {
}
inline const char *EnumNameEquipment(Equipment e) {
- if (e < Equipment_NONE || e > Equipment_Weapon) return "";
+ if (flatbuffers::IsOutRange(e, Equipment_NONE, Equipment_Weapon)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesEquipment()[index];
}
@@ -97,7 +99,7 @@ template<typename T> struct EquipmentTraits {
static const Equipment enum_value = Equipment_NONE;
};
-template<> struct EquipmentTraits<Weapon> {
+template<> struct EquipmentTraits<MyGame::Sample::Weapon> {
static const Equipment enum_value = Equipment_Weapon;
};
@@ -109,8 +111,8 @@ struct EquipmentUnion {
EquipmentUnion(EquipmentUnion&& u) FLATBUFFERS_NOEXCEPT :
type(Equipment_NONE), value(nullptr)
{ std::swap(type, u.type); std::swap(value, u.value); }
- EquipmentUnion(const EquipmentUnion &) FLATBUFFERS_NOEXCEPT;
- EquipmentUnion &operator=(const EquipmentUnion &u) FLATBUFFERS_NOEXCEPT
+ EquipmentUnion(const EquipmentUnion &);
+ EquipmentUnion &operator=(const EquipmentUnion &u)
{ EquipmentUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
EquipmentUnion &operator=(EquipmentUnion &&u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
@@ -133,13 +135,13 @@ struct EquipmentUnion {
static void *UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver);
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
- WeaponT *AsWeapon() {
+ MyGame::Sample::WeaponT *AsWeapon() {
return type == Equipment_Weapon ?
- reinterpret_cast<WeaponT *>(value) : nullptr;
+ reinterpret_cast<MyGame::Sample::WeaponT *>(value) : nullptr;
}
- const WeaponT *AsWeapon() const {
+ const MyGame::Sample::WeaponT *AsWeapon() const {
return type == Equipment_Weapon ?
- reinterpret_cast<const WeaponT *>(value) : nullptr;
+ reinterpret_cast<const MyGame::Sample::WeaponT *>(value) : nullptr;
}
};
@@ -151,8 +153,8 @@ inline bool operator==(const EquipmentUnion &lhs, const EquipmentUnion &rhs) {
return true;
}
case Equipment_Weapon: {
- return *(reinterpret_cast<const WeaponT *>(lhs.value)) ==
- *(reinterpret_cast<const WeaponT *>(rhs.value));
+ return *(reinterpret_cast<const MyGame::Sample::WeaponT *>(lhs.value)) ==
+ *(reinterpret_cast<const MyGame::Sample::WeaponT *>(rhs.value));
}
default: {
return false;
@@ -220,19 +222,19 @@ inline bool operator!=(const Vec3 &lhs, const Vec3 &rhs) {
struct MonsterT : public flatbuffers::NativeTable {
typedef Monster TableType;
- flatbuffers::unique_ptr<Vec3> pos;
+ flatbuffers::unique_ptr<MyGame::Sample::Vec3> pos;
int16_t mana;
int16_t hp;
std::string name;
std::vector<uint8_t> inventory;
- Color color;
- std::vector<flatbuffers::unique_ptr<WeaponT>> weapons;
- EquipmentUnion equipped;
- std::vector<Vec3> path;
+ MyGame::Sample::Color color;
+ std::vector<flatbuffers::unique_ptr<MyGame::Sample::WeaponT>> weapons;
+ MyGame::Sample::EquipmentUnion equipped;
+ std::vector<MyGame::Sample::Vec3> path;
MonsterT()
: mana(150),
hp(100),
- color(Color_Blue) {
+ color(MyGame::Sample::Color_Blue) {
}
};
@@ -256,6 +258,7 @@ inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef MonsterT NativeTableType;
+ typedef MonsterBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MonsterTypeTable();
}
@@ -271,11 +274,11 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_EQUIPPED = 22,
VT_PATH = 24
};
- const Vec3 *pos() const {
- return GetStruct<const Vec3 *>(VT_POS);
+ const MyGame::Sample::Vec3 *pos() const {
+ return GetStruct<const MyGame::Sample::Vec3 *>(VT_POS);
}
- Vec3 *mutable_pos() {
- return GetStruct<Vec3 *>(VT_POS);
+ MyGame::Sample::Vec3 *mutable_pos() {
+ return GetStruct<MyGame::Sample::Vec3 *>(VT_POS);
}
int16_t mana() const {
return GetField<int16_t>(VT_MANA, 150);
@@ -301,43 +304,40 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
flatbuffers::Vector<uint8_t> *mutable_inventory() {
return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
}
- Color color() const {
- return static_cast<Color>(GetField<int8_t>(VT_COLOR, 2));
+ MyGame::Sample::Color color() const {
+ return static_cast<MyGame::Sample::Color>(GetField<int8_t>(VT_COLOR, 2));
}
- bool mutate_color(Color _color) {
+ bool mutate_color(MyGame::Sample::Color _color) {
return SetField<int8_t>(VT_COLOR, static_cast<int8_t>(_color), 2);
}
- const flatbuffers::Vector<flatbuffers::Offset<Weapon>> *weapons() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Weapon>> *>(VT_WEAPONS);
+ const flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *weapons() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *>(VT_WEAPONS);
}
- flatbuffers::Vector<flatbuffers::Offset<Weapon>> *mutable_weapons() {
- return GetPointer<flatbuffers::Vector<flatbuffers::Offset<Weapon>> *>(VT_WEAPONS);
+ flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *mutable_weapons() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *>(VT_WEAPONS);
}
- Equipment equipped_type() const {
- return static_cast<Equipment>(GetField<uint8_t>(VT_EQUIPPED_TYPE, 0));
- }
- bool mutate_equipped_type(Equipment _equipped_type) {
- return SetField<uint8_t>(VT_EQUIPPED_TYPE, static_cast<uint8_t>(_equipped_type), 0);
+ MyGame::Sample::Equipment equipped_type() const {
+ return static_cast<MyGame::Sample::Equipment>(GetField<uint8_t>(VT_EQUIPPED_TYPE, 0));
}
const void *equipped() const {
return GetPointer<const void *>(VT_EQUIPPED);
}
template<typename T> const T *equipped_as() const;
- const Weapon *equipped_as_Weapon() const {
- return equipped_type() == Equipment_Weapon ? static_cast<const Weapon *>(equipped()) : nullptr;
+ const MyGame::Sample::Weapon *equipped_as_Weapon() const {
+ return equipped_type() == MyGame::Sample::Equipment_Weapon ? static_cast<const MyGame::Sample::Weapon *>(equipped()) : nullptr;
}
void *mutable_equipped() {
return GetPointer<void *>(VT_EQUIPPED);
}
- const flatbuffers::Vector<const Vec3 *> *path() const {
- return GetPointer<const flatbuffers::Vector<const Vec3 *> *>(VT_PATH);
+ const flatbuffers::Vector<const MyGame::Sample::Vec3 *> *path() const {
+ return GetPointer<const flatbuffers::Vector<const MyGame::Sample::Vec3 *> *>(VT_PATH);
}
- flatbuffers::Vector<const Vec3 *> *mutable_path() {
- return GetPointer<flatbuffers::Vector<const Vec3 *> *>(VT_PATH);
+ flatbuffers::Vector<const MyGame::Sample::Vec3 *> *mutable_path() {
+ return GetPointer<flatbuffers::Vector<const MyGame::Sample::Vec3 *> *>(VT_PATH);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
- VerifyField<Vec3>(verifier, VT_POS) &&
+ VerifyField<MyGame::Sample::Vec3>(verifier, VT_POS) &&
VerifyField<int16_t>(verifier, VT_MANA) &&
VerifyField<int16_t>(verifier, VT_HP) &&
VerifyOffset(verifier, VT_NAME) &&
@@ -360,14 +360,15 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
-template<> inline const Weapon *Monster::equipped_as<Weapon>() const {
+template<> inline const MyGame::Sample::Weapon *Monster::equipped_as<MyGame::Sample::Weapon>() const {
return equipped_as_Weapon();
}
struct MonsterBuilder {
+ typedef Monster Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
- void add_pos(const Vec3 *pos) {
+ void add_pos(const MyGame::Sample::Vec3 *pos) {
fbb_.AddStruct(Monster::VT_POS, pos);
}
void add_mana(int16_t mana) {
@@ -382,19 +383,19 @@ struct MonsterBuilder {
void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) {
fbb_.AddOffset(Monster::VT_INVENTORY, inventory);
}
- void add_color(Color color) {
+ void add_color(MyGame::Sample::Color color) {
fbb_.AddElement<int8_t>(Monster::VT_COLOR, static_cast<int8_t>(color), 2);
}
- void add_weapons(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Weapon>>> weapons) {
+ void add_weapons(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>>> weapons) {
fbb_.AddOffset(Monster::VT_WEAPONS, weapons);
}
- void add_equipped_type(Equipment equipped_type) {
+ void add_equipped_type(MyGame::Sample::Equipment equipped_type) {
fbb_.AddElement<uint8_t>(Monster::VT_EQUIPPED_TYPE, static_cast<uint8_t>(equipped_type), 0);
}
void add_equipped(flatbuffers::Offset<void> equipped) {
fbb_.AddOffset(Monster::VT_EQUIPPED, equipped);
}
- void add_path(flatbuffers::Offset<flatbuffers::Vector<const Vec3 *>> path) {
+ void add_path(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Sample::Vec3 *>> path) {
fbb_.AddOffset(Monster::VT_PATH, path);
}
explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
@@ -411,16 +412,16 @@ struct MonsterBuilder {
inline flatbuffers::Offset<Monster> CreateMonster(
flatbuffers::FlatBufferBuilder &_fbb,
- const Vec3 *pos = 0,
+ const MyGame::Sample::Vec3 *pos = 0,
int16_t mana = 150,
int16_t hp = 100,
flatbuffers::Offset<flatbuffers::String> name = 0,
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
- Color color = Color_Blue,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Weapon>>> weapons = 0,
- Equipment equipped_type = Equipment_NONE,
+ MyGame::Sample::Color color = MyGame::Sample::Color_Blue,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Sample::Weapon>>> weapons = 0,
+ MyGame::Sample::Equipment equipped_type = MyGame::Sample::Equipment_NONE,
flatbuffers::Offset<void> equipped = 0,
- flatbuffers::Offset<flatbuffers::Vector<const Vec3 *>> path = 0) {
+ flatbuffers::Offset<flatbuffers::Vector<const MyGame::Sample::Vec3 *>> path = 0) {
MonsterBuilder builder_(_fbb);
builder_.add_path(path);
builder_.add_equipped(equipped);
@@ -437,20 +438,20 @@ inline flatbuffers::Offset<Monster> CreateMonster(
inline flatbuffers::Offset<Monster> CreateMonsterDirect(
flatbuffers::FlatBufferBuilder &_fbb,
- const Vec3 *pos = 0,
+ const MyGame::Sample::Vec3 *pos = 0,
int16_t mana = 150,
int16_t hp = 100,
const char *name = nullptr,
const std::vector<uint8_t> *inventory = nullptr,
- Color color = Color_Blue,
- const std::vector<flatbuffers::Offset<Weapon>> *weapons = nullptr,
- Equipment equipped_type = Equipment_NONE,
+ MyGame::Sample::Color color = MyGame::Sample::Color_Blue,
+ const std::vector<flatbuffers::Offset<MyGame::Sample::Weapon>> *weapons = nullptr,
+ MyGame::Sample::Equipment equipped_type = MyGame::Sample::Equipment_NONE,
flatbuffers::Offset<void> equipped = 0,
- const std::vector<Vec3> *path = nullptr) {
+ const std::vector<MyGame::Sample::Vec3> *path = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
- auto weapons__ = weapons ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(*weapons) : 0;
- auto path__ = path ? _fbb.CreateVectorOfStructs<Vec3>(*path) : 0;
+ auto weapons__ = weapons ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Sample::Weapon>>(*weapons) : 0;
+ auto path__ = path ? _fbb.CreateVectorOfStructs<MyGame::Sample::Vec3>(*path) : 0;
return MyGame::Sample::CreateMonster(
_fbb,
pos,
@@ -489,6 +490,7 @@ inline bool operator!=(const WeaponT &lhs, const WeaponT &rhs) {
struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef WeaponT NativeTableType;
+ typedef WeaponBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return WeaponTypeTable();
}
@@ -521,6 +523,7 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct WeaponBuilder {
+ typedef Weapon Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
@@ -565,24 +568,24 @@ inline flatbuffers::Offset<Weapon> CreateWeaponDirect(
flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new MonsterT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::Sample::MonsterT> _o = flatbuffers::unique_ptr<MyGame::Sample::MonsterT>(new MonsterT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = pos(); if (_e) _o->pos = flatbuffers::unique_ptr<Vec3>(new Vec3(*_e)); };
- { auto _e = mana(); _o->mana = _e; };
- { auto _e = hp(); _o->hp = _e; };
- { auto _e = name(); if (_e) _o->name = _e->str(); };
- { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } };
- { auto _e = color(); _o->color = _e; };
- { auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = flatbuffers::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(_resolver)); } } };
- { auto _e = equipped_type(); _o->equipped.type = _e; };
- { auto _e = equipped(); if (_e) _o->equipped.value = EquipmentUnion::UnPack(_e, equipped_type(), _resolver); };
- { auto _e = path(); if (_e) { _o->path.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->path[_i] = *_e->Get(_i); } } };
+ { auto _e = pos(); if (_e) _o->pos = flatbuffers::unique_ptr<MyGame::Sample::Vec3>(new MyGame::Sample::Vec3(*_e)); }
+ { auto _e = mana(); _o->mana = _e; }
+ { auto _e = hp(); _o->hp = _e; }
+ { auto _e = name(); if (_e) _o->name = _e->str(); }
+ { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } }
+ { auto _e = color(); _o->color = _e; }
+ { auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = flatbuffers::unique_ptr<MyGame::Sample::WeaponT>(_e->Get(_i)->UnPack(_resolver)); } } }
+ { auto _e = equipped_type(); _o->equipped.type = _e; }
+ { auto _e = equipped(); if (_e) _o->equipped.value = MyGame::Sample::EquipmentUnion::UnPack(_e, equipped_type(), _resolver); }
+ { auto _e = path(); if (_e) { _o->path.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->path[_i] = *_e->Get(_i); } } }
}
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -599,7 +602,7 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
auto _color = _o->color;
- auto _weapons = _o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return CreateWeapon(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ) : 0;
+ auto _weapons = _o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Sample::Weapon>> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return CreateWeapon(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ) : 0;
auto _equipped_type = _o->equipped.type;
auto _equipped = _o->equipped.Pack(_fbb);
auto _path = _o->path.size() ? _fbb.CreateVectorOfStructs(_o->path) : 0;
@@ -618,16 +621,16 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
}
inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new WeaponT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::Sample::WeaponT> _o = flatbuffers::unique_ptr<MyGame::Sample::WeaponT>(new WeaponT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void Weapon::UnPackTo(WeaponT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = name(); if (_e) _o->name = _e->str(); };
- { auto _e = damage(); _o->damage = _e; };
+ { auto _e = name(); if (_e) _o->name = _e->str(); }
+ { auto _e = damage(); _o->damage = _e; }
}
inline flatbuffers::Offset<Weapon> Weapon::Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -652,10 +655,10 @@ inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Eq
return true;
}
case Equipment_Weapon: {
- auto ptr = reinterpret_cast<const Weapon *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Sample::Weapon *>(obj);
return verifier.VerifyTable(ptr);
}
- default: return false;
+ default: return true;
}
}
@@ -674,7 +677,7 @@ inline bool VerifyEquipmentVector(flatbuffers::Verifier &verifier, const flatbuf
inline void *EquipmentUnion::UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver) {
switch (type) {
case Equipment_Weapon: {
- auto ptr = reinterpret_cast<const Weapon *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Sample::Weapon *>(obj);
return ptr->UnPack(resolver);
}
default: return nullptr;
@@ -684,17 +687,17 @@ inline void *EquipmentUnion::UnPack(const void *obj, Equipment type, const flatb
inline flatbuffers::Offset<void> EquipmentUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
switch (type) {
case Equipment_Weapon: {
- auto ptr = reinterpret_cast<const WeaponT *>(value);
+ auto ptr = reinterpret_cast<const MyGame::Sample::WeaponT *>(value);
return CreateWeapon(_fbb, ptr, _rehasher).Union();
}
default: return 0;
}
}
-inline EquipmentUnion::EquipmentUnion(const EquipmentUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+inline EquipmentUnion::EquipmentUnion(const EquipmentUnion &u) : type(u.type), value(nullptr) {
switch (type) {
case Equipment_Weapon: {
- value = new WeaponT(*reinterpret_cast<WeaponT *>(u.value));
+ value = new MyGame::Sample::WeaponT(*reinterpret_cast<MyGame::Sample::WeaponT *>(u.value));
break;
}
default:
@@ -705,7 +708,7 @@ inline EquipmentUnion::EquipmentUnion(const EquipmentUnion &u) FLATBUFFERS_NOEXC
inline void EquipmentUnion::Reset() {
switch (type) {
case Equipment_Weapon: {
- auto ptr = reinterpret_cast<WeaponT *>(value);
+ auto ptr = reinterpret_cast<MyGame::Sample::WeaponT *>(value);
delete ptr;
break;
}
@@ -722,7 +725,7 @@ inline const flatbuffers::TypeTable *ColorTypeTable() {
{ flatbuffers::ET_CHAR, 0, 0 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- ColorTypeTable
+ MyGame::Sample::ColorTypeTable
};
static const char * const names[] = {
"Red",
@@ -741,7 +744,7 @@ inline const flatbuffers::TypeTable *EquipmentTypeTable() {
{ flatbuffers::ET_SEQUENCE, 0, 0 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- WeaponTypeTable
+ MyGame::Sample::WeaponTypeTable
};
static const char * const names[] = {
"NONE",
@@ -786,10 +789,10 @@ inline const flatbuffers::TypeTable *MonsterTypeTable() {
{ flatbuffers::ET_SEQUENCE, 1, 0 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- Vec3TypeTable,
- ColorTypeTable,
- WeaponTypeTable,
- EquipmentTypeTable
+ MyGame::Sample::Vec3TypeTable,
+ MyGame::Sample::ColorTypeTable,
+ MyGame::Sample::WeaponTypeTable,
+ MyGame::Sample::EquipmentTypeTable
};
static const char * const names[] = {
"pos",
@@ -859,10 +862,16 @@ inline void FinishSizePrefixedMonsterBuffer(
fbb.FinishSizePrefixed(root);
}
-inline flatbuffers::unique_ptr<MonsterT> UnPackMonster(
+inline flatbuffers::unique_ptr<MyGame::Sample::MonsterT> UnPackMonster(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<MyGame::Sample::MonsterT>(GetMonster(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Sample::MonsterT> UnPackSizePrefixedMonster(
const void *buf,
const flatbuffers::resolver_function_t *res = nullptr) {
- return flatbuffers::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(res));
+ return flatbuffers::unique_ptr<MyGame::Sample::MonsterT>(GetSizePrefixedMonster(buf)->UnPack(res));
}
} // namespace Sample
diff --git a/samples/monster_generated.lobster b/samples/monster_generated.lobster
index 409e77d7..702cdd42 100644
--- a/samples/monster_generated.lobster
+++ b/samples/monster_generated.lobster
@@ -1,31 +1,30 @@
// automatically generated by the FlatBuffers compiler, do not modify
-
-include "flatbuffers.lobster"
+import flatbuffers
namespace MyGame_Sample
-enum +
- Color_Red = 0,
- Color_Green = 1,
+enum Color:
+ Color_Red = 0
+ Color_Green = 1
Color_Blue = 2
-enum +
- Equipment_NONE = 0,
+enum Equipment:
+ Equipment_NONE = 0
Equipment_Weapon = 1
-struct Vec3
+class Vec3
-struct Monster
+class Monster
-struct Weapon
+class Weapon
-struct Vec3 : flatbuffers_handle
+class Vec3 : flatbuffers_handle
def x():
- buf_.read_float32_le(pos_ + 0)
+ return buf_.read_float32_le(pos_ + 0)
def y():
- buf_.read_float32_le(pos_ + 4)
+ return buf_.read_float32_le(pos_ + 4)
def z():
- buf_.read_float32_le(pos_ + 8)
+ return buf_.read_float32_le(pos_ + 8)
def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float):
b_.Prep(4, 12)
@@ -34,90 +33,111 @@ def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float):
b_.PrependFloat32(x)
return b_.Offset()
-struct Monster : flatbuffers_handle
+class Monster : flatbuffers_handle
def pos():
- o := buf_.flatbuffers_field_struct(pos_, 4)
- if o: MyGame_Sample_Vec3 { buf_, o } else: nil
+ let o = buf_.flatbuffers_field_struct(pos_, 4)
+ return if o: MyGame_Sample_Vec3 { buf_, o } else: nil
def mana():
- buf_.flatbuffers_field_int16(pos_, 6, 150)
+ return buf_.flatbuffers_field_int16(pos_, 6, 150)
def hp():
- buf_.flatbuffers_field_int16(pos_, 8, 100)
+ return buf_.flatbuffers_field_int16(pos_, 8, 100)
def name():
- buf_.flatbuffers_field_string(pos_, 10)
+ return buf_.flatbuffers_field_string(pos_, 10)
def inventory(i:int):
- buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
+ return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
def inventory_length():
- buf_.flatbuffers_field_vector_len(pos_, 14)
+ return buf_.flatbuffers_field_vector_len(pos_, 14)
def color():
- buf_.flatbuffers_field_int8(pos_, 16, 2)
+ return Color(buf_.flatbuffers_field_int8(pos_, 16, 2))
def weapons(i:int):
- MyGame_Sample_Weapon { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 18) + i * 4) }
+ return MyGame_Sample_Weapon { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 18) + i * 4) }
def weapons_length():
- buf_.flatbuffers_field_vector_len(pos_, 18)
+ return buf_.flatbuffers_field_vector_len(pos_, 18)
def equipped_type():
- buf_.flatbuffers_field_int8(pos_, 20, 0)
+ return Equipment(buf_.flatbuffers_field_int8(pos_, 20, 0))
def equipped_as_Weapon():
- MyGame_Sample_Weapon { buf_, buf_.flatbuffers_field_table(pos_, 22) }
+ return MyGame_Sample_Weapon { buf_, buf_.flatbuffers_field_table(pos_, 22) }
def path(i:int):
- MyGame_Sample_Vec3 { buf_, buf_.flatbuffers_field_vector(pos_, 24) + i * 12 }
+ return MyGame_Sample_Vec3 { buf_, buf_.flatbuffers_field_vector(pos_, 24) + i * 12 }
def path_length():
- buf_.flatbuffers_field_vector_len(pos_, 24)
-
-def GetRootAsMonster(buf:string): Monster { buf, buf.flatbuffers_indirect(0) }
-
-def MonsterStart(b_:flatbuffers_builder):
- b_.StartObject(11)
-def MonsterAddPos(b_:flatbuffers_builder, pos:int):
- b_.PrependStructSlot(0, pos, 0)
-def MonsterAddMana(b_:flatbuffers_builder, mana:int):
- b_.PrependInt16Slot(1, mana, 150)
-def MonsterAddHp(b_:flatbuffers_builder, hp:int):
- b_.PrependInt16Slot(2, hp, 100)
-def MonsterAddName(b_:flatbuffers_builder, name:int):
- b_.PrependUOffsetTRelativeSlot(3, name, 0)
-def MonsterAddInventory(b_:flatbuffers_builder, inventory:int):
- b_.PrependUOffsetTRelativeSlot(5, inventory, 0)
+ return buf_.flatbuffers_field_vector_len(pos_, 24)
+
+def GetRootAsMonster(buf:string): return Monster { buf, buf.flatbuffers_indirect(0) }
+
+struct MonsterBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(11)
+ return this
+ def add_pos(pos:flatbuffers_offset):
+ b_.PrependStructSlot(0, pos)
+ return this
+ def add_mana(mana:int):
+ b_.PrependInt16Slot(1, mana, 150)
+ return this
+ def add_hp(hp:int):
+ b_.PrependInt16Slot(2, hp, 100)
+ return this
+ def add_name(name:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(3, name)
+ return this
+ def add_inventory(inventory:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(5, inventory)
+ return this
+ def add_color(color:Color):
+ b_.PrependInt8Slot(6, color, 2)
+ return this
+ def add_weapons(weapons:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(7, weapons)
+ return this
+ def add_equipped_type(equipped_type:Equipment):
+ b_.PrependUint8Slot(8, equipped_type, 0)
+ return this
+ def add_equipped(equipped:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(9, equipped)
+ return this
+ def add_path(path:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(10, path)
+ return this
+ def end():
+ return b_.EndObject()
+
def MonsterStartInventoryVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(1, n_, 1)
def MonsterCreateInventoryVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(1, v_.length, 1)
reverse(v_) e_: b_.PrependUint8(e_)
- b_.EndVector(v_.length)
-def MonsterAddColor(b_:flatbuffers_builder, color:int):
- b_.PrependInt8Slot(6, color, 2)
-def MonsterAddWeapons(b_:flatbuffers_builder, weapons:int):
- b_.PrependUOffsetTRelativeSlot(7, weapons, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartWeaponsVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(4, n_, 4)
-def MonsterCreateWeaponsVector(b_:flatbuffers_builder, v_:[int]):
+def MonsterCreateWeaponsVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
b_.StartVector(4, v_.length, 4)
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
- b_.EndVector(v_.length)
-def MonsterAddEquippedType(b_:flatbuffers_builder, equipped_type:int):
- b_.PrependUint8Slot(8, equipped_type, 0)
-def MonsterAddEquipped(b_:flatbuffers_builder, equipped:int):
- b_.PrependUOffsetTRelativeSlot(9, equipped, 0)
-def MonsterAddPath(b_:flatbuffers_builder, path:int):
- b_.PrependUOffsetTRelativeSlot(10, path, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartPathVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(12, n_, 4)
-def MonsterEnd(b_:flatbuffers_builder):
- b_.EndObject()
-struct Weapon : flatbuffers_handle
+class Weapon : flatbuffers_handle
def name():
- buf_.flatbuffers_field_string(pos_, 4)
+ return buf_.flatbuffers_field_string(pos_, 4)
def damage():
- buf_.flatbuffers_field_int16(pos_, 6, 0)
-
-def GetRootAsWeapon(buf:string): Weapon { buf, buf.flatbuffers_indirect(0) }
-
-def WeaponStart(b_:flatbuffers_builder):
- b_.StartObject(2)
-def WeaponAddName(b_:flatbuffers_builder, name:int):
- b_.PrependUOffsetTRelativeSlot(0, name, 0)
-def WeaponAddDamage(b_:flatbuffers_builder, damage:int):
- b_.PrependInt16Slot(1, damage, 0)
-def WeaponEnd(b_:flatbuffers_builder):
- b_.EndObject()
+ return buf_.flatbuffers_field_int16(pos_, 6, 0)
+
+def GetRootAsWeapon(buf:string): return Weapon { buf, buf.flatbuffers_indirect(0) }
+
+struct WeaponBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(2)
+ return this
+ def add_name(name:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(0, name)
+ return this
+ def add_damage(damage:int):
+ b_.PrependInt16Slot(1, damage, 0)
+ return this
+ def end():
+ return b_.EndObject()
diff --git a/samples/sample_bfbs.cpp b/samples/sample_bfbs.cpp
index 9512e242..0e176907 100644
--- a/samples/sample_bfbs.cpp
+++ b/samples/sample_bfbs.cpp
@@ -16,9 +16,7 @@
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-
-#include "monster_test_generated.h"
-#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
+#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
using namespace MyGame::Sample;
@@ -31,7 +29,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
std::string bfbs_file;
bool ok =
flatbuffers::LoadFile("tests/monster_test.fbs", false, &schema_file) &&
- flatbuffers::LoadFile("tests/monsterdata_test.golden", false, &json_file) &&
+ flatbuffers::LoadFile("tests/monsterdata_test.golden", false,
+ &json_file) &&
flatbuffers::LoadFile("tests/monster_test.bfbs", true, &bfbs_file);
if (!ok) {
printf("couldn't load files!\n");
diff --git a/samples/sample_binary.cpp b/samples/sample_binary.cpp
index 46f08bb1..b8f4f1f6 100644
--- a/samples/sample_binary.cpp
+++ b/samples/sample_binary.cpp
@@ -20,7 +20,7 @@ using namespace MyGame::Sample;
// Example how to use FlatBuffers to create and read binary buffers.
-int main(int /*argc*/, const char * /*argv*/ []) {
+int main(int /*argc*/, const char * /*argv*/[]) {
// Build up a serialized buffer algorithmically:
flatbuffers::FlatBufferBuilder builder;
diff --git a/samples/sample_binary.lobster b/samples/sample_binary.lobster
index 0434af06..cd7adab2 100644
--- a/samples/sample_binary.lobster
+++ b/samples/sample_binary.lobster
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-include from "../lobster/"
-include "monster_generated.lobster"
+import from "../lobster/"
+import monster_generated
// Example of how to use FlatBuffers to create and read binary buffers.
@@ -24,12 +24,13 @@ let b = flatbuffers_builder {}
let weapon_names = [ "Sword", "Axe" ]
let weapon_damages = [ 3, 5 ]
-weapon_offsets := map(weapon_names) name, i:
+let weapon_offsets = map(weapon_names) name, i:
let ns = b.CreateString(name)
- b.MyGame_Sample_WeaponStart()
- b.MyGame_Sample_WeaponAddName(ns)
- b.MyGame_Sample_WeaponAddDamage(weapon_damages[i])
- b.MyGame_Sample_WeaponEnd()
+ MyGame_Sample_WeaponBuilder { b }
+ .start()
+ .add_name(ns)
+ .add_damage(weapon_damages[i])
+ .end()
let weapons = b.MyGame_Sample_MonsterCreateWeaponsVector(weapon_offsets)
@@ -40,16 +41,17 @@ let name = b.CreateString("Orc")
let inv = b.MyGame_Sample_MonsterCreateInventoryVector(map(10): _)
// Now pack it all together in our root monster object.
-b.MyGame_Sample_MonsterStart()
-b.MyGame_Sample_MonsterAddPos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
-b.MyGame_Sample_MonsterAddHp(300)
-b.MyGame_Sample_MonsterAddName(name)
-b.MyGame_Sample_MonsterAddInventory(inv)
-b.MyGame_Sample_MonsterAddColor(MyGame_Sample_Color_Red)
-b.MyGame_Sample_MonsterAddWeapons(weapons)
-b.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
-b.MyGame_Sample_MonsterAddEquipped(weapon_offsets[1])
-let orc = b.MyGame_Sample_MonsterEnd()
+let orc = MyGame_Sample_MonsterBuilder { b }
+ .start()
+ .add_pos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
+ .add_hp(300)
+ .add_name(name)
+ .add_inventory(inv)
+ .add_color(MyGame_Sample_Color_Red)
+ .add_weapons(weapons)
+ .add_equipped_type(MyGame_Sample_Equipment_Weapon)
+ .add_equipped(weapon_offsets[1])
+ .end()
// Finish the buffer!
b.Finish(orc)
diff --git a/samples/sample_binary.swift b/samples/sample_binary.swift
new file mode 100644
index 00000000..3a6dc747
--- /dev/null
+++ b/samples/sample_binary.swift
@@ -0,0 +1,68 @@
+ // THIS IS JUST TO SHOW THE CODE, PLEASE DO IMPORT FLATBUFFERS WITH SPM..
+import Flatbuffers
+
+typealias Monster = MyGame.Sample.Monster
+typealias Weapon = MyGame.Sample.Weapon
+typealias Color = MyGame.Sample.Color
+typealias Vec3 = MyGame.Sample.Vec3
+
+func main() {
+ let expectedDMG: [Int16] = [3, 5]
+ let expectedNames = ["Sword", "Axe"]
+
+ let builder = FlatBufferBuilder(initialSize: 1024)
+ let weapon1Name = builder.create(string: expectedNames[0])
+ let weapon2Name = builder.create(string: expectedNames[1])
+
+ let weapon1Start = Weapon.startWeapon(builder)
+ Weapon.add(name: weapon1Name, builder)
+ Weapon.add(damage: expectedDMG[0], builder)
+ let sword = Weapon.endWeapon(builder, start: weapon1Start)
+ let weapon2Start = Weapon.startWeapon(builder)
+ Weapon.add(name: weapon2Name, builder)
+ Weapon.add(damage: expectedDMG[1], builder)
+ let axe = Weapon.endWeapon(builder, start: weapon2Start)
+
+ let name = builder.create(string: "Orc")
+ let inventory: [Byte] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ let inventoryOffset = builder.createVector(inventory)
+
+ let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
+ let pos = builder.create(struct: MyGame.Sample.createVec3(x: 1, y: 2, z: 3), type: Vec3.self)
+
+
+ let orc = Monster.createMonster(builder,
+ offsetOfPos: pos,
+ hp: 300,
+ offsetOfName: name,
+ vectorOfInventory: inventoryOffset,
+ color: .red,
+ vectorOfWeapons: weaponsOffset,
+ equippedType: .weapon,
+ offsetOfEquipped: axe)
+ builder.finish(offset: orc)
+
+ var buf = builder.sizedByteArray
+ var monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
+
+ assert(monster.mana == 150)
+ assert(monster.hp == 300)
+ assert(monster.name == "Orc")
+ assert(monster.color == MyGame.Sample.Color.red)
+ assert(monster.pos != nil)
+ for i in 0..<monster.inventoryCount {
+ assert(i == monster.inventory(at: i))
+ }
+
+ for i in 0..<monster.weaponsCount {
+ let weap = monster.weapons(at: i)
+ let index = Int(i)
+ assert(weap?.damage == expectedDMG[index])
+ assert(weap?.name == expectedNames[index])
+ }
+ assert(monster.equippedType == .weapon)
+ let equipped = monster.equipped(type: Weapon.self)
+ assert(equipped?.name == "Axe")
+ assert(equipped?.damage == 5)
+ print("Monster Object is Verified")
+} \ No newline at end of file
diff --git a/samples/sample_text.cpp b/samples/sample_text.cpp
index aca0189c..d46185b3 100644
--- a/samples/sample_text.cpp
+++ b/samples/sample_text.cpp
@@ -16,14 +16,13 @@
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-
#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
using namespace MyGame::Sample;
// This is an example of parsing text straight into a buffer and then
// generating flatbuffer (JSON) text from the buffer.
-int main(int /*argc*/, const char * /*argv*/ []) {
+int main(int /*argc*/, const char * /*argv*/[]) {
// load FlatBuffer schema (.fbs) and JSON from disk
std::string schemafile;
std::string jsonfile;
diff --git a/samples/sample_text.lobster b/samples/sample_text.lobster
index 9da4fa25..26b3eaff 100644
--- a/samples/sample_text.lobster
+++ b/samples/sample_text.lobster
@@ -12,20 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-include from "../lobster/"
-include "monster_generated.lobster"
+import from "../lobster/"
+import monster_generated
// Example how to interop with JSON.
// Test loading some JSON, converting it to a binary FlatBuffer and back again.
// First read the schema and JSON data.
-schema := read_file("monster.fbs", true)
-json := read_file("monsterdata.json", true)
+let schema = read_file("monster.fbs", true)
+let json = read_file("monsterdata.json", true)
assert schema and json
// Parse JSON to binary:
-fb, err1 := flatbuffers_json_to_binary(schema, json, [])
+let fb, err1 = flatbuffers_json_to_binary(schema, json, [])
assert not err1
// Access one field in it, just to check:
@@ -33,7 +33,7 @@ let monster = MyGame_Sample_GetRootAsMonster(fb)
assert monster.name == "Orc"
// Convert binary back to JSON:
-json2, err2 := flatbuffers_binary_to_json(schema, fb, [])
+let json2, err2 = flatbuffers_binary_to_json(schema, fb, [])
assert not err2
// The generated JSON should be exactly equal to the original!
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 17138961..35ec1736 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -1,7 +1,6 @@
name: flatbuffers
base: core18
-version: latest
-version-script: git describe --always | sed -e 's/-/+git/;y/-/./' | tail -c +2
+version: git
summary: FlatBuffers compiler
description: |
FlatBuffers compiler
@@ -27,8 +26,6 @@ parts:
- -DCMAKE_BUILD_TYPE=Release
build-packages:
- g++
- # used to set version number
- - git
apps:
flatc:
diff --git a/src/BUILD b/src/BUILD
new file mode 100644
index 00000000..cf1bd2f6
--- /dev/null
+++ b/src/BUILD
@@ -0,0 +1,75 @@
+package(
+ default_visibility = ["//visibility:private"],
+)
+
+load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
+
+# Public flatc library to compile flatbuffer files at runtime.
+cc_library(
+ name = "flatbuffers",
+ srcs = [
+ "code_generators.cpp",
+ "idl_gen_fbs.cpp",
+ "idl_gen_text.cpp",
+ "idl_parser.cpp",
+ "reflection.cpp",
+ "util.cpp",
+ ],
+ hdrs = ["//:public_headers"],
+ strip_include_prefix = "/include",
+ visibility = ["//:__pkg__"],
+)
+
+# Public flatc compiler library.
+cc_library(
+ name = "flatc_library",
+ srcs = [
+ "flatc.cpp",
+ ],
+ hdrs = [
+ "//:flatc_headers",
+ ],
+ strip_include_prefix = "/include",
+ visibility = ["//:__pkg__"],
+ deps = [
+ ":flatbuffers",
+ ],
+)
+
+# Public flatc compiler.
+cc_library(
+ name = "flatc",
+ srcs = [
+ "flatc_main.cpp",
+ "idl_gen_cpp.cpp",
+ "idl_gen_csharp.cpp",
+ "idl_gen_dart.cpp",
+ "idl_gen_go.cpp",
+ "idl_gen_grpc.cpp",
+ "idl_gen_java.cpp",
+ "idl_gen_js_ts.cpp",
+ "idl_gen_json_schema.cpp",
+ "idl_gen_kotlin.cpp",
+ "idl_gen_lobster.cpp",
+ "idl_gen_lua.cpp",
+ "idl_gen_php.cpp",
+ "idl_gen_python.cpp",
+ "idl_gen_rust.cpp",
+ "idl_gen_text.cpp",
+ "idl_gen_swift.cpp",
+ "util.cpp",
+ ],
+ hdrs = [
+ "//:flatc_headers",
+ ],
+ strip_include_prefix = "/include",
+ visibility = ["//:__pkg__"],
+ deps = [
+ ":flatc_library",
+ "//grpc/src/compiler:cpp_generator",
+ "//grpc/src/compiler:go_generator",
+ "//grpc/src/compiler:java_generator",
+ "//grpc/src/compiler:python_generator",
+ "//grpc/src/compiler:swift_generator",
+ ],
+)
diff --git a/src/clang-format-all.sh b/src/clang-format-all.sh
new file mode 100644
index 00000000..3fd9e337
--- /dev/null
+++ b/src/clang-format-all.sh
@@ -0,0 +1,6 @@
+# Running it twice corrects some bugs in clang-format.
+for run in {1..2}
+do
+ clang-format -i -style=file include/flatbuffers/* src/*.cpp tests/*.cpp samples/*.cpp grpc/src/compiler/schema_interface.h grpc/tests/*.cpp
+done
+git checkout include/flatbuffers/reflection_generated.h
diff --git a/src/clang-format-git.sh b/src/clang-format-git.sh
new file mode 100644
index 00000000..0611cbba
--- /dev/null
+++ b/src/clang-format-git.sh
@@ -0,0 +1,6 @@
+# Running it twice corrects some bugs in clang-format.
+for run in {1..2}
+do
+ git clang-format HEAD^ -- include/flatbuffers/* src/*.cpp tests/*.cpp samples/*.cpp grpc/src/compiler/schema_interface.h grpc/tests/*.cpp
+done
+git checkout include/flatbuffers/reflection_generated.h
diff --git a/src/clang-format.sh b/src/clang-format.sh
deleted file mode 100644
index fbce6b9e..00000000
--- a/src/clang-format.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-clang-format -i -style=file include/flatbuffers/* src/*.cpp tests/test.cpp samples/*.cpp grpc/src/compiler/schema_interface.h grpc/tests/*.cpp
-git checkout include/flatbuffers/reflection_generated.h
diff --git a/src/code_generators.cpp b/src/code_generators.cpp
index 3b10db7f..46d65f7c 100644
--- a/src/code_generators.cpp
+++ b/src/code_generators.cpp
@@ -15,12 +15,14 @@
*/
#include "flatbuffers/code_generators.h"
+
#include <assert.h>
-#include "flatbuffers/base.h"
-#include "flatbuffers/util.h"
#include <cmath>
+#include "flatbuffers/base.h"
+#include "flatbuffers/util.h"
+
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4127) // C4127: conditional expression is constant
@@ -29,6 +31,8 @@
namespace flatbuffers {
void CodeWriter::operator+=(std::string text) {
+ if (!ignore_ident_ && !text.empty()) AppendIdent(stream_);
+
while (true) {
auto begin = text.find("{{");
if (begin == std::string::npos) { break; }
@@ -58,12 +62,21 @@ void CodeWriter::operator+=(std::string text) {
}
if (!text.empty() && string_back(text) == '\\') {
text.pop_back();
+ ignore_ident_ = true;
stream_ << text;
} else {
+ ignore_ident_ = false;
stream_ << text << std::endl;
}
}
+void CodeWriter::AppendIdent(std::stringstream &stream) {
+ int lvl = cur_ident_lvl_;
+ while (lvl--) {
+ stream.write(pad_.c_str(), static_cast<std::streamsize>(pad_.size()));
+ }
+}
+
const char *BaseGenerator::FlatBuffersGeneratedWarning() {
return "automatically generated by the FlatBuffers compiler,"
" do not modify";
@@ -72,13 +85,13 @@ const char *BaseGenerator::FlatBuffersGeneratedWarning() {
std::string BaseGenerator::NamespaceDir(const Parser &parser,
const std::string &path,
const Namespace &ns) {
- EnsureDirExists(path.c_str());
+ EnsureDirExists(path);
if (parser.opts.one_file) return path;
std::string namespace_dir = path; // Either empty or ends in separator.
auto &namespaces = ns.components;
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
namespace_dir += *it + kPathSeparator;
- EnsureDirExists(namespace_dir.c_str());
+ EnsureDirExists(namespace_dir);
}
return namespace_dir;
}
@@ -105,11 +118,9 @@ std::string BaseGenerator::LastNamespacePart(const Namespace &ns) {
return std::string("");
}
-// Ensure that a type is prefixed with its namespace whenever it is used
-// outside of its namespace.
+// Ensure that a type is prefixed with its namespace.
std::string BaseGenerator::WrapInNameSpace(const Namespace *ns,
const std::string &name) const {
- if (CurrentNameSpace() == ns) return name;
std::string qualified_name = qualifying_start_;
for (auto it = ns->components.begin(); it != ns->components.end(); ++it)
qualified_name += *it + qualifying_separator_;
@@ -134,6 +145,14 @@ std::string BaseGenerator::GetNameSpace(const Definition &def) const {
return qualified_name;
}
+std::string BaseGenerator::GeneratedFileName(const std::string &path,
+ const std::string &file_name,
+ const IDLOptions &options) const {
+ return path + file_name + options.filename_suffix + "." +
+ (options.filename_extension.empty() ? default_extension_
+ : options.filename_extension);
+}
+
// Generate a documentation comment, if available.
void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
const CommentConfig *config, const char *prefix) {
@@ -276,6 +295,80 @@ std::string SimpleFloatConstantGenerator::NaN(float v) const {
return this->NaN(static_cast<double>(v));
}
+std::string JavaCSharpMakeRule(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ FLATBUFFERS_ASSERT(parser.opts.lang == IDLOptions::kJava ||
+ parser.opts.lang == IDLOptions::kCSharp);
+
+ std::string file_extension =
+ (parser.opts.lang == IDLOptions::kJava) ? ".java" : ".cs";
+
+ std::string make_rule;
+
+ for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end();
+ ++it) {
+ auto &enum_def = **it;
+ if (!make_rule.empty()) make_rule += " ";
+ std::string directory =
+ BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace);
+ make_rule += directory + enum_def.name + file_extension;
+ }
+
+ for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
+ ++it) {
+ auto &struct_def = **it;
+ if (!make_rule.empty()) make_rule += " ";
+ std::string directory = BaseGenerator::NamespaceDir(
+ parser, path, *struct_def.defined_namespace);
+ make_rule += directory + struct_def.name + file_extension;
+ }
+
+ make_rule += ": ";
+ auto included_files = parser.GetIncludedFilesRecursive(file_name);
+ for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+ make_rule += " " + *it;
+ }
+ return make_rule;
+}
+
+std::string BinaryFileName(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin";
+ return path + file_name + "." + ext;
+}
+
+bool GenerateBinary(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ if (parser.opts.use_flexbuffers) {
+ auto data_vec = parser.flex_builder_.GetBuffer();
+ auto data_ptr = reinterpret_cast<char *>(data(data_vec));
+ return !parser.flex_builder_.GetSize() ||
+ flatbuffers::SaveFile(
+ BinaryFileName(parser, path, file_name).c_str(), data_ptr,
+ parser.flex_builder_.GetSize(), true);
+ }
+ return !parser.builder_.GetSize() ||
+ flatbuffers::SaveFile(
+ BinaryFileName(parser, path, file_name).c_str(),
+ reinterpret_cast<char *>(parser.builder_.GetBufferPointer()),
+ parser.builder_.GetSize(), true);
+}
+
+std::string BinaryMakeRule(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ if (!parser.builder_.GetSize()) return "";
+ std::string filebase =
+ flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
+ std::string make_rule =
+ BinaryFileName(parser, path, filebase) + ": " + file_name;
+ auto included_files =
+ parser.GetIncludedFilesRecursive(parser.root_struct_def_->file);
+ for (auto it = included_files.begin(); it != included_files.end(); ++it) {
+ make_rule += " " + *it;
+ }
+ return make_rule;
+}
+
} // namespace flatbuffers
#if defined(_MSC_VER)
diff --git a/src/flatc.cpp b/src/flatc.cpp
index 78e4c5bf..5cb2a80c 100644
--- a/src/flatc.cpp
+++ b/src/flatc.cpp
@@ -18,10 +18,10 @@
#include <list>
-#define FLATC_VERSION "1.11.0"
-
namespace flatbuffers {
+const char *FLATC_VERSION() { return FLATBUFFERS_VERSION(); }
+
void FlatCompiler::ParseFile(
flatbuffers::Parser &parser, const std::string &filename,
const std::string &contents,
@@ -42,7 +42,7 @@ void FlatCompiler::LoadBinarySchema(flatbuffers::Parser &parser,
const std::string &filename,
const std::string &contents) {
if (!parser.Deserialize(reinterpret_cast<const uint8_t *>(contents.c_str()),
- contents.size())) {
+ contents.size())) {
Error("failed to load binary schema: " + filename, false, false);
}
}
@@ -63,96 +63,118 @@ std::string FlatCompiler::GetUsageString(const char *program_name) const {
const Generator &g = params_.generators[i];
std::stringstream full_name;
- full_name << std::setw(12) << std::left << g.generator_opt_long;
+ full_name << std::setw(16) << std::left << g.generator_opt_long;
const char *name = g.generator_opt_short ? g.generator_opt_short : " ";
const char *help = g.generator_help;
ss << " " << full_name.str() << " " << name << " " << help << ".\n";
}
// clang-format off
+
+ // Output width
+ // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
ss <<
- " -o PATH Prefix PATH to all generated files.\n"
- " -I PATH Search for includes in the specified path.\n"
- " -M Print make rules for generated files.\n"
- " --version Print the version number of flatc and exit.\n"
- " --strict-json Strict JSON: field names must be / will be quoted,\n"
- " no trailing commas in tables/vectors.\n"
- " --allow-non-utf8 Pass non-UTF-8 input through parser and emit nonstandard\n"
- " \\x escapes in JSON. (Default is to raise parse error on\n"
- " non-UTF-8 input.)\n"
- " --natural-utf8 Output strings with UTF-8 as human-readable strings.\n"
- " By default, UTF-8 characters are printed as \\uXXXX escapes.\n"
- " --defaults-json Output fields whose value is the default when\n"
- " writing JSON\n"
- " --unknown-json Allow fields in JSON that are not defined in the\n"
- " schema. These fields will be discared when generating\n"
- " binaries.\n"
- " --no-prefix Don\'t prefix enum values with the enum type in C++.\n"
- " --scoped-enums Use C++11 style scoped and strongly typed enums.\n"
- " also implies --no-prefix.\n"
- " --gen-includes (deprecated), this is the default behavior.\n"
- " If the original behavior is required (no include\n"
- " statements) use --no-includes.\n"
- " --no-includes Don\'t generate include statements for included\n"
- " schemas the generated file depends on (C++).\n"
- " --gen-mutable Generate accessors that can mutate buffers in-place.\n"
- " --gen-onefile Generate single output file for C# and Go.\n"
- " --gen-name-strings Generate type name functions for C++.\n"
- " --gen-object-api Generate an additional object-based API.\n"
- " --gen-compare Generate operator== for object-based API types.\n"
- " --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
- " --gen-generated Add @Generated annotation for Java\n"
- " --gen-all Generate not just code for the current schema files,\n"
- " but for all files it includes as well.\n"
- " If the language uses a single file for output (by default\n"
- " the case for C++ and JS), all code will end up in this one\n"
- " file.\n"
- " --cpp-ptr-type T Set object API pointer type (default std::unique_ptr).\n"
- " --cpp-str-type T Set object API string type (default std::string).\n"
- " T::c_str(), T::length() and T::empty() must be supported.\n"
- " The custom type also needs to be constructible from std::string\n"
- " (see the --cpp-str-flex-ctor option to change this behavior).\n"
- " --cpp-str-flex-ctor Don't construct custom string types by passing std::string\n"
- " from Flatbuffers, but (char* + length).\n"
- " --object-prefix Customise class prefix for C++ object-based API.\n"
- " --object-suffix Customise class suffix for C++ object-based API.\n"
- " Default value is \"T\".\n"
- " --no-js-exports Removes Node.js style export lines in JS.\n"
- " --goog-js-export Uses goog.exports* for closure compiler exporting in JS.\n"
- " --es6-js-export Uses ECMAScript 6 export style lines in JS.\n"
- " --go-namespace Generate the overrided namespace in Golang.\n"
- " --go-import Generate the overrided import for flatbuffers in Golang\n"
- " (default is \"github.com/google/flatbuffers/go\").\n"
- " --raw-binary Allow binaries without file_indentifier to be read.\n"
- " This may crash flatc given a mismatched schema.\n"
- " --size-prefixed Input binaries are size prefixed buffers.\n"
- " --proto Input is a .proto, translate to .fbs.\n"
- " --oneof-union Translate .proto oneofs to flatbuffer unions.\n"
- " --grpc Generate GRPC interfaces for the specified languages.\n"
- " --schema Serialize schemas instead of JSON (use with -b).\n"
- " --bfbs-comments Add doc comments to the binary schema files.\n"
- " --bfbs-builtins Add builtin attributes to the binary schema files.\n"
- " --conform FILE Specify a schema the following schemas should be\n"
- " an evolution of. Gives errors if not.\n"
- " --conform-includes Include path for the schema given with --conform PATH\n"
- " --include-prefix Prefix this path to any generated include statements.\n"
+ " -o PATH Prefix PATH to all generated files.\n"
+ " -I PATH Search for includes in the specified path.\n"
+ " -M Print make rules for generated files.\n"
+ " --version Print the version number of flatc and exit.\n"
+ " --strict-json Strict JSON: field names must be / will be quoted,\n"
+ " no trailing commas in tables/vectors.\n"
+ " --allow-non-utf8 Pass non-UTF-8 input through parser and emit nonstandard\n"
+ " \\x escapes in JSON. (Default is to raise parse error on\n"
+ " non-UTF-8 input.)\n"
+ " --natural-utf8 Output strings with UTF-8 as human-readable strings.\n"
+ " By default, UTF-8 characters are printed as \\uXXXX escapes.\n"
+ " --defaults-json Output fields whose value is the default when\n"
+ " writing JSON\n"
+ " --unknown-json Allow fields in JSON that are not defined in the\n"
+ " schema. These fields will be discared when generating\n"
+ " binaries.\n"
+ " --no-prefix Don\'t prefix enum values with the enum type in C++.\n"
+ " --scoped-enums Use C++11 style scoped and strongly typed enums.\n"
+ " also implies --no-prefix.\n"
+ " --gen-includes (deprecated), this is the default behavior.\n"
+ " If the original behavior is required (no include\n"
+ " statements) use --no-includes.\n"
+ " --no-includes Don\'t generate include statements for included\n"
+ " schemas the generated file depends on (C++ / Python).\n"
+ " --gen-mutable Generate accessors that can mutate buffers in-place.\n"
+ " --gen-onefile Generate single output file for C# and Go.\n"
+ " --gen-name-strings Generate type name functions for C++ and Rust.\n"
+ " --gen-object-api Generate an additional object-based API.\n"
+ " --gen-compare Generate operator== for object-based API types.\n"
+ " --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
+ " --java-checkerframe work Add @Pure for Java.\n"
+ " --gen-generated Add @Generated annotation for Java\n"
+ " --gen-all Generate not just code for the current schema files,\n"
+ " but for all files it includes as well.\n"
+ " If the language uses a single file for output (by default\n"
+ " the case for C++ and JS), all code will end up in this one\n"
+ " file.\n"
+ " --cpp-include Adds an #include in generated file.\n"
+ " --cpp-ptr-type T Set object API pointer type (default std::unique_ptr).\n"
+ " --cpp-str-type T Set object API string type (default std::string).\n"
+ " T::c_str(), T::length() and T::empty() must be supported.\n"
+ " The custom type also needs to be constructible from std::string\n"
+ " (see the --cpp-str-flex-ctor option to change this behavior).\n"
+ " --cpp-str-flex-ctor Don't construct custom string types by passing std::string\n"
+ " from Flatbuffers, but (char* + length).\n"
+ " --cpp-std CPP_STD Generate a C++ code using features of selected C++ standard.\n"
+ " Supported CPP_STD values:\n"
+ " * 'c++0x' - generate code compatible with old compilers;\n"
+ " * 'c++11' - use C++11 code generator (default);\n"
+ " * 'c++17' - use C++17 features in generated code (experimental).\n"
+ " --object-prefix Customise class prefix for C++ object-based API.\n"
+ " --object-suffix Customise class suffix for C++ object-based API.\n"
+ " Default value is \"T\".\n"
+ " --no-js-exports Removes Node.js style export lines in JS.\n"
+ " --goog-js-export Uses goog.exports* for closure compiler exporting in JS.\n"
+ " --es6-js-export Uses ECMAScript 6 export style lines in JS.\n"
+ " --go-namespace Generate the overrided namespace in Golang.\n"
+ " --go-import Generate the overrided import for flatbuffers in Golang\n"
+ " (default is \"github.com/google/flatbuffers/go\").\n"
+ " --raw-binary Allow binaries without file_indentifier to be read.\n"
+ " This may crash flatc given a mismatched schema.\n"
+ " --size-prefixed Input binaries are size prefixed buffers.\n"
+ " --proto Input is a .proto, translate to .fbs.\n"
+ " --proto-namespace-suffix Add this namespace to any flatbuffers generated\n"
+ " SUFFIX from protobufs.\n"
+ " --oneof-union Translate .proto oneofs to flatbuffer unions.\n"
+ " --grpc Generate GRPC interfaces for the specified languages.\n"
+ " --schema Serialize schemas instead of JSON (use with -b).\n"
+ " --bfbs-comments Add doc comments to the binary schema files.\n"
+ " --bfbs-builtins Add builtin attributes to the binary schema files.\n"
+ " --bfbs-gen-embed Generate code to embed the bfbs schema to the source.\n"
+ " --conform FILE Specify a schema the following schemas should be\n"
+ " an evolution of. Gives errors if not.\n"
+ " --conform-includes Include path for the schema given with --conform PATH\n"
+ " --filename-suffix The suffix appended to the generated file names.\n"
+ " Default is '_generated'.\n"
+ " --filename-ext The extension appended to the generated file names.\n"
+ " Default is language-specific (e.g., '.h' for C++)\n"
+ " --include-prefix Prefix this path to any generated include statements.\n"
" PATH\n"
- " --keep-prefix Keep original prefix of schema include statement.\n"
- " --no-fb-import Don't include flatbuffers import statement for TypeScript.\n"
- " --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n"
- " --short-names Use short function names for JS and TypeScript.\n"
- " --reflect-types Add minimal type reflection to code generation.\n"
- " --reflect-names Add minimal type/name reflection.\n"
- " --root-type T Select or override the default root_type\n"
- " --force-defaults Emit default values in binary output from JSON\n"
- " --force-empty When serializing from object API representation,\n"
- " force strings and vectors to empty rather than null.\n"
+ " --keep-prefix Keep original prefix of schema include statement.\n"
+ " --no-fb-import Don't include flatbuffers import statement for TypeScript.\n"
+ " --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n"
+ " --short-names Use short function names for JS and TypeScript.\n"
+ " --reflect-types Add minimal type reflection to code generation.\n"
+ " --reflect-names Add minimal type/name reflection.\n"
+ " --root-type T Select or override the default root_type\n"
+ " --force-defaults Emit default values in binary output from JSON\n"
+ " --force-empty When serializing from object API representation,\n"
+ " force strings and vectors to empty rather than null.\n"
+ " --force-empty-vectors When serializing from object API representation,\n"
+ " force vectors to empty rather than null.\n"
+ " --flexbuffers Used with \"binary\" and \"json\" options, it generates\n"
+ " data using schema-less FlexBuffers.\n"
"FILEs may be schemas (must end in .fbs), binary schemas (must end in .bfbs),\n"
"or JSON files (conforming to preceding schema). FILEs after the -- must be\n"
"binary flatbuffer format files.\n"
"Output files are named using the base file name of the input,\n"
"and written to the current directory or the path given by -o.\n"
"example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n";
+ // 12345678901234567890123456789012345678901234567890123456789012345678901234567890
// clang-format on
return ss.str();
}
@@ -188,22 +210,22 @@ int FlatCompiler::Compile(int argc, const char **argv) {
output_path = flatbuffers::ConCatPathFileName(
flatbuffers::PosixPath(argv[argi]), "");
} else if (arg == "-I") {
- if (++argi >= argc) Error("missing path following" + arg, true);
+ if (++argi >= argc) Error("missing path following: " + arg, true);
include_directories_storage.push_back(
flatbuffers::PosixPath(argv[argi]));
include_directories.push_back(
include_directories_storage.back().c_str());
} else if (arg == "--conform") {
- if (++argi >= argc) Error("missing path following" + arg, true);
+ if (++argi >= argc) Error("missing path following: " + arg, true);
conform_to_schema = flatbuffers::PosixPath(argv[argi]);
} else if (arg == "--conform-includes") {
- if (++argi >= argc) Error("missing path following" + arg, true);
+ if (++argi >= argc) Error("missing path following: " + arg, true);
include_directories_storage.push_back(
flatbuffers::PosixPath(argv[argi]));
conform_include_directories.push_back(
include_directories_storage.back().c_str());
} else if (arg == "--include-prefix") {
- if (++argi >= argc) Error("missing path following" + arg, true);
+ if (++argi >= argc) Error("missing path following: " + arg, true);
opts.include_prefix = flatbuffers::ConCatPathFileName(
flatbuffers::PosixPath(argv[argi]), "");
} else if (arg == "--keep-prefix") {
@@ -247,30 +269,35 @@ int FlatCompiler::Compile(int argc, const char **argv) {
opts.generate_object_based_api = true;
} else if (arg == "--gen-compare") {
opts.gen_compare = true;
+ } else if (arg == "--cpp-include") {
+ if (++argi >= argc) Error("missing include following: " + arg, true);
+ opts.cpp_includes.push_back(argv[argi]);
} else if (arg == "--cpp-ptr-type") {
- if (++argi >= argc) Error("missing type following" + arg, true);
+ if (++argi >= argc) Error("missing type following: " + arg, true);
opts.cpp_object_api_pointer_type = argv[argi];
} else if (arg == "--cpp-str-type") {
- if (++argi >= argc) Error("missing type following" + arg, true);
+ if (++argi >= argc) Error("missing type following: " + arg, true);
opts.cpp_object_api_string_type = argv[argi];
} else if (arg == "--cpp-str-flex-ctor") {
opts.cpp_object_api_string_flexible_constructor = true;
} else if (arg == "--gen-nullable") {
opts.gen_nullable = true;
+ } else if (arg == "--java-checkerframework") {
+ opts.java_checkerframework = true;
} else if (arg == "--gen-generated") {
opts.gen_generated = true;
} else if (arg == "--object-prefix") {
- if (++argi >= argc) Error("missing prefix following" + arg, true);
+ if (++argi >= argc) Error("missing prefix following: " + arg, true);
opts.object_prefix = argv[argi];
} else if (arg == "--object-suffix") {
- if (++argi >= argc) Error("missing suffix following" + arg, true);
+ if (++argi >= argc) Error("missing suffix following: " + arg, true);
opts.object_suffix = argv[argi];
} else if (arg == "--gen-all") {
opts.generate_all = true;
opts.include_dependence_headers = false;
} else if (arg == "--gen-includes") {
// Deprecated, remove this option some time in the future.
- printf("warning: --gen-includes is deprecated (it is now default)\n");
+ Warn("warning: --gen-includes is deprecated (it is now default)\n");
} else if (arg == "--no-includes") {
opts.include_dependence_headers = false;
} else if (arg == "--gen-onefile") {
@@ -283,6 +310,9 @@ int FlatCompiler::Compile(int argc, const char **argv) {
binary_files_from = filenames.size();
} else if (arg == "--proto") {
opts.proto_mode = true;
+ } else if (arg == "--proto-namespace-suffix") {
+ if (++argi >= argc) Error("missing namespace suffix" + arg, true);
+ opts.proto_namespace_suffix = argv[argi];
} else if (arg == "--oneof-union") {
opts.proto_oneof_union = true;
} else if (arg == "--schema") {
@@ -290,7 +320,7 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} else if (arg == "-M") {
print_make_rules = true;
} else if (arg == "--version") {
- printf("flatc version %s\n", FLATC_VERSION);
+ printf("flatc version %s\n", FLATC_VERSION());
exit(0);
} else if (arg == "--grpc") {
grpc_enabled = true;
@@ -298,6 +328,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
opts.binary_schema_comments = true;
} else if (arg == "--bfbs-builtins") {
opts.binary_schema_builtins = true;
+ } else if (arg == "--bfbs-gen-embed") {
+ opts.binary_schema_gen_embed = true;
} else if (arg == "--no-fb-import") {
opts.skip_flatbuffers_import = true;
} else if (arg == "--no-ts-reexport") {
@@ -309,12 +341,31 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} else if (arg == "--reflect-names") {
opts.mini_reflect = IDLOptions::kTypesAndNames;
} else if (arg == "--root-type") {
- if (++argi >= argc) Error("missing type following" + arg, true);
+ if (++argi >= argc) Error("missing type following: " + arg, true);
opts.root_type = argv[argi];
+ } else if (arg == "--filename-suffix") {
+ if (++argi >= argc) Error("missing filename suffix: " + arg, true);
+ opts.filename_suffix = argv[argi];
+ } else if (arg == "--filename-ext") {
+ if (++argi >= argc) Error("missing filename extension: " + arg, true);
+ opts.filename_extension = argv[argi];
} else if (arg == "--force-defaults") {
opts.force_defaults = true;
} else if (arg == "--force-empty") {
- opts.set_empty_to_null = false;
+ opts.set_empty_strings_to_null = false;
+ opts.set_empty_vectors_to_null = false;
+ } else if (arg == "--force-empty-vectors") {
+ opts.set_empty_vectors_to_null = false;
+ } else if (arg == "--java-primitive-has-method") {
+ opts.java_primitive_has_method = true;
+ } else if (arg == "--cs-gen-json-serializer") {
+ opts.cs_gen_json_serializer = true;
+ } else if (arg == "--flexbuffers") {
+ opts.use_flexbuffers = true;
+ } else if (arg == "--cpp-std") {
+ if (++argi >= argc)
+ Error("missing C++ standard specification" + arg, true);
+ opts.cpp_std = argv[argi];
} else {
for (size_t i = 0; i < params_.num_generators; ++i) {
if (arg == params_.generators[i].generator_opt_long ||
@@ -389,7 +440,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
"\" matches the schema, use --raw-binary to read this file"
" anyway.");
} else if (!flatbuffers::BufferHasIdentifier(
- contents.c_str(), parser->file_identifier_.c_str(), opts.size_prefixed)) {
+ contents.c_str(), parser->file_identifier_.c_str(),
+ opts.size_prefixed)) {
Error("binary \"" + filename +
"\" does not have expected file_identifier \"" +
parser->file_identifier_ +
@@ -398,7 +450,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
}
} else {
// Check if file contains 0 bytes.
- if (!is_binary_schema && contents.length() != strlen(contents.c_str())) {
+ if (!opts.use_flexbuffers && !is_binary_schema &&
+ contents.length() != strlen(contents.c_str())) {
Error("input file appears to be binary: " + filename, true);
}
if (is_schema) {
@@ -409,6 +462,16 @@ int FlatCompiler::Compile(int argc, const char **argv) {
}
if (is_binary_schema) {
LoadBinarySchema(*parser.get(), filename, contents);
+ }
+ if (opts.use_flexbuffers) {
+ if (opts.lang_to_generate == IDLOptions::kJson) {
+ parser->flex_root_ = flexbuffers::GetRoot(
+ reinterpret_cast<const uint8_t *>(contents.c_str()),
+ contents.size());
+ } else {
+ parser->flex_builder_.Clear();
+ ParseFile(*parser.get(), filename, contents, include_directories);
+ }
} else {
ParseFile(*parser.get(), filename, contents, include_directories);
if (!is_schema && !parser->builder_.GetSize()) {
@@ -423,8 +486,10 @@ int FlatCompiler::Compile(int argc, const char **argv) {
auto err = parser->ConformTo(conform_parser);
if (!err.empty()) Error("schemas don\'t conform: " + err);
}
- if (schema_binary) {
+ if (schema_binary || opts.binary_schema_gen_embed) {
parser->Serialize();
+ }
+ if (schema_binary) {
parser->file_extension_ = reflection::SchemaExtension();
}
}
@@ -445,11 +510,16 @@ int FlatCompiler::Compile(int argc, const char **argv) {
params_.generators[i].lang_name + " for " + filebase);
}
} else {
- std::string make_rule = params_.generators[i].make_rule(
- *parser.get(), output_path, filename);
- if (!make_rule.empty())
- printf("%s\n",
- flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str());
+ if (params_.generators[i].make_rule == nullptr) {
+ Error(std::string("Cannot generate make rule for ") +
+ params_.generators[i].lang_name);
+ } else {
+ std::string make_rule = params_.generators[i].make_rule(
+ *parser.get(), output_path, filename);
+ if (!make_rule.empty())
+ printf("%s\n",
+ flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str());
+ }
}
if (grpc_enabled) {
if (params_.generators[i].generateGRPC != nullptr) {
diff --git a/src/flatc_main.cpp b/src/flatc_main.cpp
index 78e66a6f..0ad26448 100644
--- a/src/flatc_main.cpp
+++ b/src/flatc_main.cpp
@@ -15,6 +15,7 @@
*/
#include "flatbuffers/flatc.h"
+#include "flatbuffers/util.h"
static const char *g_program_name = nullptr;
@@ -29,11 +30,26 @@ static void Error(const flatbuffers::FlatCompiler *flatc,
const std::string &err, bool usage, bool show_exe_name) {
if (show_exe_name) { printf("%s: ", g_program_name); }
printf("error: %s\n", err.c_str());
- if (usage) { printf("%s", flatc->GetUsageString(g_program_name).c_str()); }
+ if (usage && flatc) {
+ printf("%s", flatc->GetUsageString(g_program_name).c_str());
+ }
exit(1);
}
+namespace flatbuffers {
+void LogCompilerWarn(const std::string &warn) {
+ Warn(static_cast<const flatbuffers::FlatCompiler *>(nullptr), warn, true);
+}
+void LogCompilerError(const std::string &err) {
+ Error(static_cast<const flatbuffers::FlatCompiler *>(nullptr), err, false,
+ true);
+}
+} // namespace flatbuffers
+
int main(int argc, const char *argv[]) {
+ // Prevent Appveyor-CI hangs.
+ flatbuffers::SetupDefaultCRTReportMode();
+
g_program_name = argv[0];
const flatbuffers::FlatCompiler::Generator generators[] = {
@@ -50,45 +66,50 @@ int main(int argc, const char *argv[]) {
"Generate C++ headers for tables/structs", flatbuffers::CPPMakeRule },
{ flatbuffers::GenerateGo, "-g", "--go", "Go", true,
flatbuffers::GenerateGoGRPC, flatbuffers::IDLOptions::kGo,
- "Generate Go files for tables/structs", flatbuffers::GeneralMakeRule },
- { flatbuffers::GenerateGeneral, "-j", "--java", "Java", true,
+ "Generate Go files for tables/structs", nullptr },
+ { flatbuffers::GenerateJava, "-j", "--java", "Java", true,
flatbuffers::GenerateJavaGRPC, flatbuffers::IDLOptions::kJava,
"Generate Java classes for tables/structs",
- flatbuffers::GeneralMakeRule },
+ flatbuffers::JavaCSharpMakeRule },
{ flatbuffers::GenerateJSTS, "-s", "--js", "JavaScript", true, nullptr,
flatbuffers::IDLOptions::kJs,
- "Generate JavaScript code for tables/structs", flatbuffers::JSTSMakeRule },
+ "Generate JavaScript code for tables/structs",
+ flatbuffers::JSTSMakeRule },
{ flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr,
flatbuffers::IDLOptions::kDart,
"Generate Dart classes for tables/structs", flatbuffers::DartMakeRule },
{ flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr,
flatbuffers::IDLOptions::kTs,
- "Generate TypeScript code for tables/structs", flatbuffers::JSTSMakeRule },
- { flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", true, nullptr,
+ "Generate TypeScript code for tables/structs",
+ flatbuffers::JSTSMakeRule },
+ { flatbuffers::GenerateCSharp, "-n", "--csharp", "C#", true, nullptr,
flatbuffers::IDLOptions::kCSharp,
- "Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule },
- { flatbuffers::GeneratePython, "-p", "--python", "Python", true, nullptr,
- flatbuffers::IDLOptions::kPython,
- "Generate Python files for tables/structs",
- flatbuffers::GeneralMakeRule },
- { flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true, nullptr,
- flatbuffers::IDLOptions::kLobster,
- "Generate Lobster files for tables/structs",
- flatbuffers::GeneralMakeRule },
+ "Generate C# classes for tables/structs",
+ flatbuffers::JavaCSharpMakeRule },
+ { flatbuffers::GeneratePython, "-p", "--python", "Python", true,
+ flatbuffers::GeneratePythonGRPC, flatbuffers::IDLOptions::kPython,
+ "Generate Python files for tables/structs", nullptr },
+ { flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true,
+ nullptr, flatbuffers::IDLOptions::kLobster,
+ "Generate Lobster files for tables/structs", nullptr },
{ flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr,
- flatbuffers::IDLOptions::kLua,
- "Generate Lua files for tables/structs",
- flatbuffers::GeneralMakeRule },
+ flatbuffers::IDLOptions::kLua, "Generate Lua files for tables/structs",
+ nullptr },
{ flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr,
- flatbuffers::IDLOptions::kRust,
- "Generate Rust files for tables/structs",
+ flatbuffers::IDLOptions::kRust, "Generate Rust files for tables/structs",
flatbuffers::RustMakeRule },
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr,
flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs",
- flatbuffers::GeneralMakeRule },
+ nullptr },
+ { flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr,
+ flatbuffers::IDLOptions::kKotlin,
+ "Generate Kotlin classes for tables/structs", nullptr },
{ flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema",
true, nullptr, flatbuffers::IDLOptions::kJsonSchema,
- "Generate Json schema", flatbuffers::GeneralMakeRule },
+ "Generate Json schema", nullptr },
+ { flatbuffers::GenerateSwift, nullptr, "--swift", "swift", true,
+ flatbuffers::GenerateSwiftGRPC, flatbuffers::IDLOptions::kSwift,
+ "Generate Swift files for tables/structs", nullptr },
};
flatbuffers::FlatCompiler::InitParams params;
diff --git a/src/flathash.cpp b/src/flathash.cpp
index bc3d2df2..1264f821 100644
--- a/src/flathash.cpp
+++ b/src/flathash.cpp
@@ -15,9 +15,11 @@
*/
#include <stdio.h>
+
#include <iostream>
#include <sstream>
#include <string>
+
#include "flatbuffers/hash.h"
enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x };
@@ -35,7 +37,7 @@ int main(int argc, char *argv[]) {
}
printf(" 32 bit:\n");
size = sizeof(flatbuffers::kHashFunctions32) /
- sizeof(flatbuffers::kHashFunctions32[0]);
+ sizeof(flatbuffers::kHashFunctions32[0]);
for (size_t i = 0; i < size; ++i) {
printf(" * %s\n", flatbuffers::kHashFunctions32[i].name);
}
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp
index 268c436e..f78ee268 100644
--- a/src/idl_gen_cpp.cpp
+++ b/src/idl_gen_cpp.cpp
@@ -16,30 +16,84 @@
// independent from idl_parser, since this code is not needed for most clients
+#include <unordered_set>
+
#include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flatc.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-#include <unordered_set>
-
namespace flatbuffers {
// Pedantic warning free version of toupper().
-inline char ToUpper(char c) { return static_cast<char>(::toupper(c)); }
+inline char ToUpper(char c) {
+ return static_cast<char>(::toupper(static_cast<unsigned char>(c)));
+}
+
+// Make numerical literal with type-suffix.
+// This function is only needed for C++! Other languages do not need it.
+static inline std::string NumToStringCpp(std::string val, BaseType type) {
+ // Avoid issues with -2147483648, -9223372036854775808.
+ switch (type) {
+ case BASE_TYPE_INT:
+ return (val != "-2147483648") ? val : ("(-2147483647 - 1)");
+ case BASE_TYPE_ULONG: return (val == "0") ? val : (val + "ULL");
+ case BASE_TYPE_LONG:
+ if (val == "-9223372036854775808")
+ return "(-9223372036854775807LL - 1LL)";
+ else
+ return (val == "0") ? val : (val + "LL");
+ default: return val;
+ }
+}
-static std::string GeneratedFileName(const std::string &path,
- const std::string &file_name) {
- return path + file_name + "_generated.h";
+static std::string GenIncludeGuard(const std::string &file_name,
+ const Namespace &name_space,
+ const std::string &postfix = "") {
+ // Generate include guard.
+ std::string guard = file_name;
+ // Remove any non-alpha-numeric characters that may appear in a filename.
+ struct IsAlnum {
+ bool operator()(char c) const { return !is_alnum(c); }
+ };
+ guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()),
+ guard.end());
+ guard = "FLATBUFFERS_GENERATED_" + guard;
+ guard += "_";
+ // For further uniqueness, also add the namespace.
+ for (auto it = name_space.components.begin();
+ it != name_space.components.end(); ++it) {
+ guard += *it + "_";
+ }
+ // Anything extra to add to the guard?
+ if (!postfix.empty()) { guard += postfix + "_"; }
+ guard += "H_";
+ std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
+ return guard;
}
namespace cpp {
+
+enum CppStandard { CPP_STD_X0 = 0, CPP_STD_11, CPP_STD_17 };
+
+// Extension of IDLOptions for cpp-generator.
+struct IDLOptionsCpp : public IDLOptions {
+ // All fields start with 'g_' prefix to distinguish from the base IDLOptions.
+ CppStandard g_cpp_std; // Base version of C++ standard.
+ bool g_only_fixed_enums; // Generate underlaying type for all enums.
+
+ IDLOptionsCpp(const IDLOptions &opts)
+ : IDLOptions(opts), g_cpp_std(CPP_STD_11), g_only_fixed_enums(true) {}
+};
+
class CppGenerator : public BaseGenerator {
public:
CppGenerator(const Parser &parser, const std::string &path,
- const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "", "::"),
+ const std::string &file_name, IDLOptionsCpp opts)
+ : BaseGenerator(parser, path, file_name, "", "::", "h"),
cur_name_space_(nullptr),
+ opts_(opts),
float_const_gen_("std::numeric_limits<double>::",
"std::numeric_limits<float>::", "quiet_NaN()",
"infinity()") {
@@ -144,28 +198,6 @@ class CppGenerator : public BaseGenerator {
for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
}
- std::string GenIncludeGuard() const {
- // Generate include guard.
- std::string guard = file_name_;
- // Remove any non-alpha-numeric characters that may appear in a filename.
- struct IsAlnum {
- bool operator()(char c) const { return !is_alnum(c); }
- };
- guard.erase(std::remove_if(guard.begin(), guard.end(), IsAlnum()),
- guard.end());
- guard = "FLATBUFFERS_GENERATED_" + guard;
- guard += "_";
- // For further uniqueness, also add the namespace.
- auto name_space = parser_.current_namespace_;
- for (auto it = name_space->components.begin();
- it != name_space->components.end(); ++it) {
- guard += *it + "_";
- }
- guard += "H_";
- std::transform(guard.begin(), guard.end(), guard.begin(), ToUpper);
- return guard;
- }
-
void GenIncludeDependencies() {
int num_includes = 0;
for (auto it = parser_.native_included_files_.begin();
@@ -178,15 +210,22 @@ class CppGenerator : public BaseGenerator {
if (it->second.empty()) continue;
auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext);
-
- code_ += "#include \"" + parser_.opts.include_prefix +
- (parser_.opts.keep_include_path ? noext : basename) +
- "_generated.h\"";
+ auto includeName =
+ GeneratedFileName(opts_.include_prefix,
+ opts_.keep_include_path ? noext : basename, opts_);
+ code_ += "#include \"" + includeName + "\"";
num_includes++;
}
if (num_includes) code_ += "";
}
+ void GenExtraIncludes() {
+ for (std::size_t i = 0; i < opts_.cpp_includes.size(); ++i) {
+ code_ += "#include \"" + opts_.cpp_includes[i] + "\"";
+ }
+ if (!opts_.cpp_includes.empty()) { code_ += ""; }
+ }
+
std::string EscapeKeyword(const std::string &name) const {
return keywords_.find(name) == keywords_.end() ? name : name + "_";
}
@@ -197,20 +236,83 @@ class CppGenerator : public BaseGenerator {
std::string Name(const EnumVal &ev) const { return EscapeKeyword(ev.name); }
+ bool generate_bfbs_embed() {
+ code_.Clear();
+ code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+
+ // If we don't have a root struct definition,
+ if (!parser_.root_struct_def_) {
+ // put a comment in the output why there is no code generated.
+ code_ += "// Binary schema not generated, no root struct found";
+ } else {
+ auto &struct_def = *parser_.root_struct_def_;
+ const auto include_guard =
+ GenIncludeGuard(file_name_, *struct_def.defined_namespace, "bfbs");
+
+ code_ += "#ifndef " + include_guard;
+ code_ += "#define " + include_guard;
+ code_ += "";
+ if (parser_.opts.gen_nullable) {
+ code_ += "#pragma clang system_header\n\n";
+ }
+
+ SetNameSpace(struct_def.defined_namespace);
+ auto name = Name(struct_def);
+ code_.SetValue("STRUCT_NAME", name);
+
+ // Create code to return the binary schema data.
+ auto binary_schema_hex_text =
+ BufferToHexText(parser_.builder_.GetBufferPointer(),
+ parser_.builder_.GetSize(), 105, " ", "");
+
+ code_ += "struct {{STRUCT_NAME}}BinarySchema {";
+ code_ += " static const uint8_t *data() {";
+ code_ += " // Buffer containing the binary schema.";
+ code_ += " static const uint8_t bfbsData[" +
+ NumToString(parser_.builder_.GetSize()) + "] = {";
+ code_ += binary_schema_hex_text;
+ code_ += " };";
+ code_ += " return bfbsData;";
+ code_ += " }";
+ code_ += " static size_t size() {";
+ code_ += " return " + NumToString(parser_.builder_.GetSize()) + ";";
+ code_ += " }";
+ code_ += " const uint8_t *begin() {";
+ code_ += " return data();";
+ code_ += " }";
+ code_ += " const uint8_t *end() {";
+ code_ += " return data() + size();";
+ code_ += " }";
+ code_ += "};";
+ code_ += "";
+
+ if (cur_name_space_) SetNameSpace(nullptr);
+
+ // Close the include guard.
+ code_ += "#endif // " + include_guard;
+ }
+
+ // We are just adding "_bfbs" to the generated filename.
+ const auto file_path =
+ GeneratedFileName(path_, file_name_ + "_bfbs", opts_);
+ const auto final_code = code_.ToString();
+
+ return SaveFile(file_path.c_str(), final_code, false);
+ }
+
// Iterate through all definitions we haven't generate code for (enums,
// structs, and tables) and output them to a single file.
bool generate() {
code_.Clear();
code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
- const auto include_guard = GenIncludeGuard();
+ const auto include_guard =
+ GenIncludeGuard(file_name_, *parser_.current_namespace_);
code_ += "#ifndef " + include_guard;
code_ += "#define " + include_guard;
code_ += "";
- if (parser_.opts.gen_nullable) {
- code_ += "#pragma clang system_header\n\n";
- }
+ if (opts_.gen_nullable) { code_ += "#pragma clang system_header\n\n"; }
code_ += "#include \"flatbuffers/flatbuffers.h\"";
if (parser_.uses_flexbuffers_) {
@@ -218,7 +320,8 @@ class CppGenerator : public BaseGenerator {
}
code_ += "";
- if (parser_.opts.include_dependence_headers) { GenIncludeDependencies(); }
+ if (opts_.include_dependence_headers) { GenIncludeDependencies(); }
+ GenExtraIncludes();
FLATBUFFERS_ASSERT(!cur_name_space_);
@@ -230,9 +333,11 @@ class CppGenerator : public BaseGenerator {
if (!struct_def.generated) {
SetNameSpace(struct_def.defined_namespace);
code_ += "struct " + Name(struct_def) + ";";
- if (parser_.opts.generate_object_based_api) {
- auto nativeName =
- NativeName(Name(struct_def), &struct_def, parser_.opts);
+ if (!struct_def.fixed) {
+ code_ += "struct " + Name(struct_def) + "Builder;";
+ }
+ if (opts_.generate_object_based_api) {
+ auto nativeName = NativeName(Name(struct_def), &struct_def, opts_);
if (!struct_def.fixed) { code_ += "struct " + nativeName + ";"; }
}
code_ += "";
@@ -240,25 +345,24 @@ class CppGenerator : public BaseGenerator {
}
// Generate forward declarations for all equal operators
- if (parser_.opts.generate_object_based_api && parser_.opts.gen_compare) {
+ if (opts_.generate_object_based_api && opts_.gen_compare) {
for (auto it = parser_.structs_.vec.begin();
it != parser_.structs_.vec.end(); ++it) {
const auto &struct_def = **it;
if (!struct_def.generated) {
SetNameSpace(struct_def.defined_namespace);
- auto nativeName =
- NativeName(Name(struct_def), &struct_def, parser_.opts);
+ auto nativeName = NativeName(Name(struct_def), &struct_def, opts_);
code_ += "bool operator==(const " + nativeName + " &lhs, const " +
nativeName + " &rhs);";
code_ += "bool operator!=(const " + nativeName + " &lhs, const " +
- nativeName + " &rhs);";
+ nativeName + " &rhs);";
}
}
code_ += "";
}
// Generate preablmle code for mini reflection.
- if (parser_.opts.mini_reflect != IDLOptions::kNone) {
+ if (opts_.mini_reflect != IDLOptions::kNone) {
// To break cyclic dependencies, first pre-declare all tables/structs.
for (auto it = parser_.structs_.vec.begin();
it != parser_.structs_.vec.end(); ++it) {
@@ -317,7 +421,7 @@ class CppGenerator : public BaseGenerator {
}
// Generate code for mini reflection.
- if (parser_.opts.mini_reflect != IDLOptions::kNone) {
+ if (opts_.mini_reflect != IDLOptions::kNone) {
// Then the unions/enums that may refer to them.
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) {
@@ -368,7 +472,7 @@ class CppGenerator : public BaseGenerator {
code_ += "}";
code_ += "";
- if (parser_.opts.mutable_buffer) {
+ if (opts_.mutable_buffer) {
code_ += "inline \\";
code_ += "{{STRUCT_NAME}} *GetMutable{{STRUCT_NAME}}(void *buf) {";
code_ += " return flatbuffers::GetMutableRoot<{{STRUCT_NAME}}>(buf);";
@@ -441,10 +545,10 @@ class CppGenerator : public BaseGenerator {
code_ += "}";
code_ += "";
- if (parser_.opts.generate_object_based_api) {
+ if (opts_.generate_object_based_api) {
// A convenient root unpack function.
auto native_name =
- NativeName(WrapInNameSpace(struct_def), &struct_def, parser_.opts);
+ NativeName(WrapInNameSpace(struct_def), &struct_def, opts_);
code_.SetValue("UNPACK_RETURN",
GenTypeNativePtr(native_name, nullptr, false));
code_.SetValue("UNPACK_TYPE",
@@ -457,6 +561,14 @@ class CppGenerator : public BaseGenerator {
code_ += "(Get{{STRUCT_NAME}}(buf)->UnPack(res));";
code_ += "}";
code_ += "";
+
+ code_ += "inline {{UNPACK_RETURN}} UnPackSizePrefixed{{STRUCT_NAME}}(";
+ code_ += " const void *buf,";
+ code_ += " const flatbuffers::resolver_function_t *res = nullptr) {";
+ code_ += " return {{UNPACK_TYPE}}\\";
+ code_ += "(GetSizePrefixed{{STRUCT_NAME}}(buf)->UnPack(res));";
+ code_ += "}";
+ code_ += "";
}
}
@@ -465,9 +577,12 @@ class CppGenerator : public BaseGenerator {
// Close the include guard.
code_ += "#endif // " + include_guard;
- const auto file_path = GeneratedFileName(path_, file_name_);
+ const auto file_path = GeneratedFileName(path_, file_name_, opts_);
const auto final_code = code_.ToString();
- return SaveFile(file_path.c_str(), final_code, false);
+
+ // Save the file and optionally generate the binary schema code.
+ return SaveFile(file_path.c_str(), final_code, false) &&
+ (!parser_.opts.binary_schema_gen_embed || generate_bfbs_embed());
}
private:
@@ -478,6 +593,9 @@ class CppGenerator : public BaseGenerator {
// This tracks the current namespace so we can insert namespace declarations.
const Namespace *cur_name_space_;
+ const IDLOptionsCpp opts_;
+ const TypedFloatConstantGenerator float_const_gen_;
+
const Namespace *CurrentNameSpace() const { return cur_name_space_; }
// Translates a qualified name in flatbuffer text format to the same name in
@@ -485,13 +603,28 @@ class CppGenerator : public BaseGenerator {
static std::string TranslateNameSpace(const std::string &qualified_name) {
std::string cpp_qualified_name = qualified_name;
size_t start_pos = 0;
- while ((start_pos = cpp_qualified_name.find(".", start_pos)) !=
+ while ((start_pos = cpp_qualified_name.find('.', start_pos)) !=
std::string::npos) {
cpp_qualified_name.replace(start_pos, 1, "::");
}
return cpp_qualified_name;
}
+ bool TypeHasKey(const Type &type) {
+ if (type.base_type != BASE_TYPE_STRUCT) { return false; }
+ for (auto it = type.struct_def->fields.vec.begin();
+ it != type.struct_def->fields.vec.end(); ++it) {
+ const auto &field = **it;
+ if (field.key) { return true; }
+ }
+ return false;
+ }
+
+ bool VectorElementUserFacing(const Type &type) const {
+ return opts_.g_cpp_std >= cpp::CPP_STD_17 && opts_.g_only_fixed_enums &&
+ IsEnum(type);
+ }
+
void GenComment(const std::vector<std::string> &dc, const char *prefix = "") {
std::string text;
::flatbuffers::GenComment(dc, &text, nullptr, prefix);
@@ -502,11 +635,10 @@ class CppGenerator : public BaseGenerator {
std::string GenTypeBasic(const Type &type, bool user_facing_type) const {
// clang-format off
static const char *const ctypename[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
- RTYPE) \
- #CTYPE,
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ #CTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
- #undef FLATBUFFERS_TD
+ #undef FLATBUFFERS_TD
};
// clang-format on
if (user_facing_type) {
@@ -524,15 +656,18 @@ class CppGenerator : public BaseGenerator {
return "flatbuffers::String";
}
case BASE_TYPE_VECTOR: {
- const auto type_name = GenTypeWire(type.VectorType(), "", false);
+ const auto type_name = GenTypeWire(
+ type.VectorType(), "", VectorElementUserFacing(type.VectorType()));
return "flatbuffers::Vector<" + type_name + ">";
}
case BASE_TYPE_STRUCT: {
return WrapInNameSpace(*type.struct_def);
}
case BASE_TYPE_UNION:
- // fall through
- default: { return "void"; }
+ // fall through
+ default: {
+ return "void";
+ }
}
}
@@ -562,7 +697,7 @@ class CppGenerator : public BaseGenerator {
}
std::string NullableExtension() {
- return parser_.opts.gen_nullable ? " _Nullable " : "";
+ return opts_.gen_nullable ? " _Nullable " : "";
}
static std::string NativeName(const std::string &name, const StructDef *sd,
@@ -573,12 +708,12 @@ class CppGenerator : public BaseGenerator {
const std::string &PtrType(const FieldDef *field) {
auto attr = field ? field->attributes.Lookup("cpp_ptr_type") : nullptr;
- return attr ? attr->constant : parser_.opts.cpp_object_api_pointer_type;
+ return attr ? attr->constant : opts_.cpp_object_api_pointer_type;
}
const std::string NativeString(const FieldDef *field) {
auto attr = field ? field->attributes.Lookup("cpp_str_type") : nullptr;
- auto &ret = attr ? attr->constant : parser_.opts.cpp_object_api_string_type;
+ auto &ret = attr ? attr->constant : opts_.cpp_object_api_string_type;
if (ret.empty()) { return "std::string"; }
return ret;
}
@@ -587,8 +722,7 @@ class CppGenerator : public BaseGenerator {
auto attr = field
? (field->attributes.Lookup("cpp_str_flex_ctor") != nullptr)
: false;
- auto ret =
- attr ? attr : parser_.opts.cpp_object_api_string_flexible_constructor;
+ auto ret = attr ? attr : opts_.cpp_object_api_string_flexible_constructor;
return ret && NativeString(field) !=
"std::string"; // Only for custom string types.
}
@@ -599,7 +733,7 @@ class CppGenerator : public BaseGenerator {
if (ptr_type != "naked") {
return (ptr_type != "default_ptr_type"
? ptr_type
- : parser_.opts.cpp_object_api_pointer_type) +
+ : opts_.cpp_object_api_pointer_type) +
"<" + type + ">";
} else if (is_constructor) {
return "";
@@ -643,15 +777,17 @@ class CppGenerator : public BaseGenerator {
return GenTypeNativePtr(type_name, &field, false);
}
} else {
- return GenTypeNativePtr(
- NativeName(type_name, type.struct_def, parser_.opts), &field,
- false);
+ return GenTypeNativePtr(NativeName(type_name, type.struct_def, opts_),
+ &field, false);
}
}
case BASE_TYPE_UNION: {
- return type.enum_def->name + "Union";
+ auto type_name = WrapInNameSpace(*type.enum_def);
+ return type_name + "Union";
+ }
+ default: {
+ return GenTypeBasic(type, true);
}
- default: { return GenTypeBasic(type, true); }
}
}
@@ -662,28 +798,34 @@ class CppGenerator : public BaseGenerator {
bool user_facing_type) {
if (IsScalar(type.base_type)) {
return GenTypeBasic(type, user_facing_type) + afterbasic;
+ } else if (IsArray(type)) {
+ auto element_type = type.VectorType();
+ // Check if enum arrays are used in C++ without specifying --scoped-enums
+ if (IsEnum(element_type) && !opts_.g_only_fixed_enums) {
+ LogCompilerError(
+ "--scoped-enums must be enabled to use enum arrays in C++");
+ FLATBUFFERS_ASSERT(true);
+ }
+ return beforeptr +
+ (IsScalar(element_type.base_type)
+ ? GenTypeBasic(element_type, user_facing_type)
+ : GenTypePointer(element_type)) +
+ afterptr;
} else {
return beforeptr + GenTypePointer(type) + afterptr;
}
}
- std::string GenEnumDecl(const EnumDef &enum_def) const {
- const IDLOptions &opts = parser_.opts;
- return (opts.scoped_enums ? "enum class " : "enum ") + Name(enum_def);
- }
-
std::string GenEnumValDecl(const EnumDef &enum_def,
const std::string &enum_val) const {
- const IDLOptions &opts = parser_.opts;
- return opts.prefixed_enums ? Name(enum_def) + "_" + enum_val : enum_val;
+ return opts_.prefixed_enums ? Name(enum_def) + "_" + enum_val : enum_val;
}
std::string GetEnumValUse(const EnumDef &enum_def,
const EnumVal &enum_val) const {
- const IDLOptions &opts = parser_.opts;
- if (opts.scoped_enums) {
+ if (opts_.scoped_enums) {
return Name(enum_def) + "::" + Name(enum_val);
- } else if (opts.prefixed_enums) {
+ } else if (opts_.prefixed_enums) {
return Name(enum_def) + "_" + Name(enum_val);
} else {
return Name(enum_val);
@@ -789,7 +931,7 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("NUM_FIELDS", NumToString(num_fields));
std::vector<std::string> names;
std::vector<Type> types;
- bool consecutive_enum_from_zero = true;
+
if (struct_def) {
for (auto it = struct_def->fields.vec.begin();
it != struct_def->fields.vec.end(); ++it) {
@@ -804,9 +946,6 @@ class CppGenerator : public BaseGenerator {
names.push_back(Name(ev));
types.push_back(enum_def->is_union ? ev.union_type
: Type(enum_def->underlying_type));
- if (static_cast<int64_t>(it - enum_def->Vals().begin()) != ev.value) {
- consecutive_enum_from_zero = false;
- }
}
}
std::string ts;
@@ -851,12 +990,16 @@ class CppGenerator : public BaseGenerator {
ns += "\"" + *it + "\"";
}
std::string vs;
+ const auto consecutive_enum_from_zero =
+ enum_def && enum_def->MinValue()->IsZero() &&
+ ((enum_def->size() - 1) == enum_def->Distance());
if (enum_def && !consecutive_enum_from_zero) {
for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end();
++it) {
const auto &ev = **it;
if (!vs.empty()) vs += ", ";
- vs += NumToString(ev.value);
+ vs += NumToStringCpp(enum_def->ToString(ev),
+ enum_def->underlying_type.base_type);
}
} else if (struct_def && struct_def->fixed) {
for (auto it = struct_def->fields.vec.begin();
@@ -883,10 +1026,11 @@ class CppGenerator : public BaseGenerator {
code_ += " };";
}
if (!vs.empty()) {
+ // Problem with uint64_t values greater than 9223372036854775807ULL.
code_ += " static const int64_t values[] = { {{VALUES}} };";
}
auto has_names =
- num_fields && parser_.opts.mini_reflect == IDLOptions::kTypesAndNames;
+ num_fields && opts_.mini_reflect == IDLOptions::kTypesAndNames;
if (has_names) {
code_ += " static const char * const names[] = {";
code_ += " {{NAMES}}";
@@ -907,33 +1051,34 @@ class CppGenerator : public BaseGenerator {
// Generate an enum declaration,
// an enum string lookup table,
// and an enum array of values
+
void GenEnum(const EnumDef &enum_def) {
code_.SetValue("ENUM_NAME", Name(enum_def));
code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false));
- code_.SetValue("SEP", "");
GenComment(enum_def.doc_comment);
- code_ += GenEnumDecl(enum_def) + "\\";
- if (parser_.opts.scoped_enums) code_ += " : {{BASE_TYPE}}\\";
+ code_ +=
+ (opts_.scoped_enums ? "enum class " : "enum ") + Name(enum_def) + "\\";
+ if (opts_.g_only_fixed_enums) { code_ += " : {{BASE_TYPE}}\\"; }
code_ += " {";
- int64_t anyv = 0;
- const EnumVal *minv = nullptr, *maxv = nullptr;
+ code_.SetValue("SEP", ",");
+ auto add_sep = false;
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
const auto &ev = **it;
-
+ if (add_sep) code_ += "{{SEP}}";
GenComment(ev.doc_comment, " ");
code_.SetValue("KEY", GenEnumValDecl(enum_def, Name(ev)));
- code_.SetValue("VALUE", NumToString(ev.value));
- code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\";
- code_.SetValue("SEP", ",\n");
-
- minv = !minv || minv->value > ev.value ? &ev : minv;
- maxv = !maxv || maxv->value < ev.value ? &ev : maxv;
- anyv |= ev.value;
+ code_.SetValue("VALUE",
+ NumToStringCpp(enum_def.ToString(ev),
+ enum_def.underlying_type.base_type));
+ code_ += " {{KEY}} = {{VALUE}}\\";
+ add_sep = true;
}
+ const EnumVal *minv = enum_def.MinValue();
+ const EnumVal *maxv = enum_def.MaxValue();
- if (parser_.opts.scoped_enums || parser_.opts.prefixed_enums) {
+ if (opts_.scoped_enums || opts_.prefixed_enums) {
FLATBUFFERS_ASSERT(minv && maxv);
code_.SetValue("SEP", ",\n");
@@ -943,22 +1088,24 @@ class CppGenerator : public BaseGenerator {
code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\";
code_.SetValue("KEY", GenEnumValDecl(enum_def, "ANY"));
- code_.SetValue("VALUE", NumToString(anyv));
+ code_.SetValue("VALUE",
+ NumToStringCpp(enum_def.AllFlags(),
+ enum_def.underlying_type.base_type));
code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\";
} else { // MIN & MAX are useless for bit_flags
code_.SetValue("KEY", GenEnumValDecl(enum_def, "MIN"));
- code_.SetValue("VALUE", GenEnumValDecl(enum_def, minv->name));
+ code_.SetValue("VALUE", GenEnumValDecl(enum_def, Name(*minv)));
code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\";
code_.SetValue("KEY", GenEnumValDecl(enum_def, "MAX"));
- code_.SetValue("VALUE", GenEnumValDecl(enum_def, maxv->name));
+ code_.SetValue("VALUE", GenEnumValDecl(enum_def, Name(*maxv)));
code_ += "{{SEP}} {{KEY}} = {{VALUE}}\\";
}
}
code_ += "";
code_ += "};";
- if (parser_.opts.scoped_enums && enum_def.attributes.Lookup("bit_flags")) {
+ if (opts_.scoped_enums && enum_def.attributes.Lookup("bit_flags")) {
code_ +=
"FLATBUFFERS_DEFINE_BITMASK_OPERATORS({{ENUM_NAME}}, {{BASE_TYPE}})";
}
@@ -984,22 +1131,24 @@ class CppGenerator : public BaseGenerator {
// Problem is, if values are very sparse that could generate really big
// tables. Ideally in that case we generate a map lookup instead, but for
// the moment we simply don't output a table at all.
- auto range =
- enum_def.vals.vec.back()->value - enum_def.vals.vec.front()->value + 1;
+ auto range = enum_def.Distance();
// Average distance between values above which we consider a table
// "too sparse". Change at will.
- static const int kMaxSparseness = 5;
- if (range / static_cast<int64_t>(enum_def.vals.vec.size()) <
- kMaxSparseness) {
+ static const uint64_t kMaxSparseness = 5;
+ if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
code_ += "inline const char * const *EnumNames{{ENUM_NAME}}() {";
- code_ += " static const char * const names[] = {";
+ code_ += " static const char * const names[" +
+ NumToString(range + 1 + 1) + "] = {";
- auto val = enum_def.Vals().front()->value;
+ auto val = enum_def.Vals().front();
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) {
- const auto &ev = **it;
- while (val++ != ev.value) { code_ += " \"\","; }
- code_ += " \"" + Name(ev) + "\",";
+ auto ev = *it;
+ for (auto k = enum_def.Distance(val, ev); k > 1; --k) {
+ code_ += " \"\",";
+ }
+ val = ev;
+ code_ += " \"" + Name(*ev) + "\",";
}
code_ += " nullptr";
code_ += " };";
@@ -1010,14 +1159,14 @@ class CppGenerator : public BaseGenerator {
code_ += "inline const char *EnumName{{ENUM_NAME}}({{ENUM_NAME}} e) {";
- code_ += " if (e < " +
- GetEnumValUse(enum_def, *enum_def.vals.vec.front()) +
- " || e > " + GetEnumValUse(enum_def, *enum_def.vals.vec.back()) +
- ") return \"\";";
+ code_ += " if (flatbuffers::IsOutRange(e, " +
+ GetEnumValUse(enum_def, *enum_def.MinValue()) + ", " +
+ GetEnumValUse(enum_def, *enum_def.MaxValue()) +
+ ")) return \"\";";
code_ += " const size_t index = static_cast<size_t>(e)\\";
- if (enum_def.vals.vec.front()->value) {
- auto vals = GetEnumValUse(enum_def, *enum_def.vals.vec.front());
+ if (enum_def.MinValue()->IsNonZero()) {
+ auto vals = GetEnumValUse(enum_def, *enum_def.MinValue());
code_ += " - static_cast<size_t>(" + vals + ")\\";
}
code_ += ";";
@@ -1064,11 +1213,11 @@ class CppGenerator : public BaseGenerator {
}
}
- if (parser_.opts.generate_object_based_api && enum_def.is_union) {
+ if (opts_.generate_object_based_api && enum_def.is_union) {
// Generate a union type
code_.SetValue("NAME", Name(enum_def));
- code_.SetValue("NONE",
- GetEnumValUse(enum_def, *enum_def.vals.Lookup("NONE")));
+ FLATBUFFERS_ASSERT(enum_def.Lookup("NONE"));
+ code_.SetValue("NONE", GetEnumValUse(enum_def, *enum_def.Lookup("NONE")));
code_ += "struct {{NAME}}Union {";
code_ += " {{NAME}} type;";
@@ -1078,10 +1227,8 @@ class CppGenerator : public BaseGenerator {
code_ += " {{NAME}}Union({{NAME}}Union&& u) FLATBUFFERS_NOEXCEPT :";
code_ += " type({{NONE}}), value(nullptr)";
code_ += " { std::swap(type, u.type); std::swap(value, u.value); }";
- code_ += " {{NAME}}Union(const {{NAME}}Union &) FLATBUFFERS_NOEXCEPT;";
- code_ +=
- " {{NAME}}Union &operator=(const {{NAME}}Union &u) "
- "FLATBUFFERS_NOEXCEPT";
+ code_ += " {{NAME}}Union(const {{NAME}}Union &);";
+ code_ += " {{NAME}}Union &operator=(const {{NAME}}Union &u)";
code_ +=
" { {{NAME}}Union t(u); std::swap(type, t.type); std::swap(value, "
"t.value); return *this; }";
@@ -1100,7 +1247,8 @@ class CppGenerator : public BaseGenerator {
code_ += " void Set(T&& val) {";
code_ += " using RT = typename std::remove_reference<T>::type;";
code_ += " Reset();";
- code_ += " type = {{NAME}}Traits<typename RT::TableType>::enum_value;";
+ code_ +=
+ " type = {{NAME}}Traits<typename RT::TableType>::enum_value;";
code_ += " if (type != {{NONE}}) {";
code_ += " value = new RT(std::forward<T>(val));";
code_ += " }";
@@ -1119,7 +1267,7 @@ class CppGenerator : public BaseGenerator {
const auto native_type =
NativeName(GetUnionElement(ev, true, true, true),
- ev.union_type.struct_def, parser_.opts);
+ ev.union_type.struct_def, opts_);
code_.SetValue("NATIVE_TYPE", native_type);
code_.SetValue("NATIVE_NAME", Name(ev));
code_.SetValue("NATIVE_ID", GetEnumValUse(enum_def, ev));
@@ -1138,7 +1286,7 @@ class CppGenerator : public BaseGenerator {
code_ += "};";
code_ += "";
- if (parser_.opts.gen_compare) {
+ if (opts_.gen_compare) {
code_ += "";
code_ +=
"inline bool operator==(const {{NAME}}Union &lhs, const "
@@ -1153,7 +1301,7 @@ class CppGenerator : public BaseGenerator {
if (ev.IsNonZero()) {
const auto native_type =
NativeName(GetUnionElement(ev, true, true, true),
- ev.union_type.struct_def, parser_.opts);
+ ev.union_type.struct_def, opts_);
code_.SetValue("NATIVE_TYPE", native_type);
code_ += " case {{NATIVE_ID}}: {";
code_ +=
@@ -1213,8 +1361,9 @@ class CppGenerator : public BaseGenerator {
" auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);";
if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
if (ev.union_type.struct_def->fixed) {
- code_ += " return verifier.Verify<{{TYPE}}>(static_cast<const "
- "uint8_t *>(obj), 0);";
+ code_ +=
+ " return verifier.Verify<{{TYPE}}>(static_cast<const "
+ "uint8_t *>(obj), 0);";
} else {
code_ += getptr;
code_ += " return verifier.VerifyTable(ptr);";
@@ -1232,7 +1381,7 @@ class CppGenerator : public BaseGenerator {
code_ += " }";
}
}
- code_ += " default: return false;";
+ code_ += " default: return true;"; // unknown values are OK.
code_ += " }";
code_ += "}";
code_ += "";
@@ -1251,7 +1400,7 @@ class CppGenerator : public BaseGenerator {
code_ += "}";
code_ += "";
- if (parser_.opts.generate_object_based_api) {
+ if (opts_.generate_object_based_api) {
// Generate union Unpack() and Pack() functions.
code_ += "inline " + UnionUnPackSignature(enum_def, false) + " {";
code_ += " switch (type) {";
@@ -1291,9 +1440,8 @@ class CppGenerator : public BaseGenerator {
if (ev.IsZero()) { continue; }
code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
- code_.SetValue("TYPE",
- NativeName(GetUnionElement(ev, true, true, true),
- ev.union_type.struct_def, parser_.opts));
+ code_.SetValue("TYPE", NativeName(GetUnionElement(ev, true, true, true),
+ ev.union_type.struct_def, opts_));
code_.SetValue("NAME", GetUnionElement(ev, false, true));
code_ += " case {{LABEL}}: {";
code_ += " auto ptr = reinterpret_cast<const {{TYPE}} *>(value);";
@@ -1319,17 +1467,15 @@ class CppGenerator : public BaseGenerator {
// Union copy constructor
code_ +=
"inline {{ENUM_NAME}}Union::{{ENUM_NAME}}Union(const "
- "{{ENUM_NAME}}Union &u) FLATBUFFERS_NOEXCEPT : type(u.type), "
- "value(nullptr) {";
+ "{{ENUM_NAME}}Union &u) : type(u.type), value(nullptr) {";
code_ += " switch (type) {";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) {
const auto &ev = **it;
if (ev.IsZero()) { continue; }
code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
- code_.SetValue("TYPE",
- NativeName(GetUnionElement(ev, true, true, true),
- ev.union_type.struct_def, parser_.opts));
+ code_.SetValue("TYPE", NativeName(GetUnionElement(ev, true, true, true),
+ ev.union_type.struct_def, opts_));
code_ += " case {{LABEL}}: {";
bool copyable = true;
if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
@@ -1363,8 +1509,8 @@ class CppGenerator : public BaseGenerator {
code_ += "";
// Union Reset() function.
- code_.SetValue("NONE",
- GetEnumValUse(enum_def, *enum_def.vals.Lookup("NONE")));
+ FLATBUFFERS_ASSERT(enum_def.Lookup("NONE"));
+ code_.SetValue("NONE", GetEnumValUse(enum_def, *enum_def.Lookup("NONE")));
code_ += "inline void {{ENUM_NAME}}Union::Reset() {";
code_ += " switch (type) {";
@@ -1373,9 +1519,8 @@ class CppGenerator : public BaseGenerator {
const auto &ev = **it;
if (ev.IsZero()) { continue; }
code_.SetValue("LABEL", GetEnumValUse(enum_def, ev));
- code_.SetValue("TYPE",
- NativeName(GetUnionElement(ev, true, true, true),
- ev.union_type.struct_def, parser_.opts));
+ code_.SetValue("TYPE", NativeName(GetUnionElement(ev, true, true, true),
+ ev.union_type.struct_def, opts_));
code_ += " case {{LABEL}}: {";
code_ += " auto ptr = reinterpret_cast<{{TYPE}} *>(value);";
code_ += " delete ptr;";
@@ -1417,7 +1562,7 @@ class CppGenerator : public BaseGenerator {
void GenFullyQualifiedNameGetter(const StructDef &struct_def,
const std::string &name) {
- if (!parser_.opts.generate_name_strings) { return; }
+ if (!opts_.generate_name_strings) { return; }
auto fullname = struct_def.defined_namespace->GetFullyQualifiedName(name);
code_.SetValue("NAME", fullname);
code_.SetValue("CONSTEXPR", "FLATBUFFERS_CONSTEXPR");
@@ -1430,18 +1575,19 @@ class CppGenerator : public BaseGenerator {
if (IsFloat(field.value.type.base_type))
return float_const_gen_.GenFloatConstant(field);
else
- return field.value.constant;
+ return NumToStringCpp(field.value.constant, field.value.type.base_type);
}
std::string GetDefaultScalarValue(const FieldDef &field, bool is_ctor) {
if (field.value.type.enum_def && IsScalar(field.value.type.base_type)) {
- auto ev = field.value.type.enum_def->ReverseLookup(
- StringToInt(field.value.constant.c_str()), false);
+ auto ev = field.value.type.enum_def->FindByValue(field.value.constant);
if (ev) {
return WrapInNameSpace(field.value.type.enum_def->defined_namespace,
GetEnumValUse(*field.value.type.enum_def, *ev));
} else {
- return GenUnderlyingCast(field, true, field.value.constant);
+ return GenUnderlyingCast(
+ field, true,
+ NumToStringCpp(field.value.constant, field.value.type.base_type));
}
} else if (field.value.type.base_type == BASE_TYPE_BOOL) {
return field.value.constant == "0" ? "false" : "true";
@@ -1472,9 +1618,13 @@ class CppGenerator : public BaseGenerator {
if (IsStruct(vtype)) {
type = WrapInNameSpace(*vtype.struct_def);
} else {
- type = GenTypeWire(vtype, "", false);
+ type = GenTypeWire(vtype, "", VectorElementUserFacing(vtype));
+ }
+ if (TypeHasKey(vtype)) {
+ code_.SetValue("PARAM_TYPE", "std::vector<" + type + "> *");
+ } else {
+ code_.SetValue("PARAM_TYPE", "const std::vector<" + type + "> *");
}
- code_.SetValue("PARAM_TYPE", "const std::vector<" + type + "> *");
code_.SetValue("PARAM_VALUE", "nullptr");
} else {
code_.SetValue("PARAM_TYPE", GenTypeWire(field.value.type, " ", true));
@@ -1547,7 +1697,7 @@ class CppGenerator : public BaseGenerator {
}
code_.SetValue("NATIVE_NAME",
- NativeName(Name(struct_def), &struct_def, parser_.opts));
+ NativeName(Name(struct_def), &struct_def, opts_));
code_.SetValue("INIT_LIST", initializer_list);
code_ += " {{NATIVE_NAME}}(){{INIT_LIST}} {";
@@ -1617,8 +1767,7 @@ class CppGenerator : public BaseGenerator {
}
void GenNativeTable(const StructDef &struct_def) {
- const auto native_name =
- NativeName(Name(struct_def), &struct_def, parser_.opts);
+ const auto native_name = NativeName(Name(struct_def), &struct_def, opts_);
code_.SetValue("STRUCT_NAME", Name(struct_def));
code_.SetValue("NATIVE_NAME", native_name);
@@ -1633,7 +1782,7 @@ class CppGenerator : public BaseGenerator {
GenOperatorNewDelete(struct_def);
GenDefaultConstructor(struct_def);
code_ += "};";
- if (parser_.opts.gen_compare) GenCompareOperator(struct_def);
+ if (opts_.gen_compare) GenCompareOperator(struct_def);
code_ += "";
}
@@ -1695,7 +1844,9 @@ class CppGenerator : public BaseGenerator {
}
break;
}
- default: { break; }
+ default: {
+ break;
+ }
}
}
@@ -1720,7 +1871,7 @@ class CppGenerator : public BaseGenerator {
} else {
FLATBUFFERS_ASSERT(IsScalar(field.value.type.base_type));
auto type = GenTypeBasic(field.value.type, false);
- if (parser_.opts.scoped_enums && field.value.type.enum_def &&
+ if (opts_.scoped_enums && field.value.type.enum_def &&
IsScalar(field.value.type.base_type)) {
type = GenTypeGet(field.value.type, " ", "const ", " *", true);
}
@@ -1736,7 +1887,7 @@ class CppGenerator : public BaseGenerator {
// Generate an accessor struct, builder structs & function for a table.
void GenTable(const StructDef &struct_def) {
- if (parser_.opts.generate_object_based_api) { GenNativeTable(struct_def); }
+ if (opts_.generate_object_based_api) { GenNativeTable(struct_def); }
// Generate an accessor struct, with methods of the form:
// type name() const { return GetField<type>(offset, defaultval); }
@@ -1746,10 +1897,12 @@ class CppGenerator : public BaseGenerator {
code_ +=
"struct {{STRUCT_NAME}} FLATBUFFERS_FINAL_CLASS"
" : private flatbuffers::Table {";
- if (parser_.opts.generate_object_based_api) {
+ if (opts_.generate_object_based_api) {
code_ += " typedef {{NATIVE_NAME}} NativeTableType;";
}
- if (parser_.opts.mini_reflect != IDLOptions::kNone) {
+ code_ += " typedef {{STRUCT_NAME}}Builder Builder;";
+ if (opts_.g_cpp_std >= cpp::CPP_STD_17) { code_ += " struct Traits;"; }
+ if (opts_.mini_reflect != IDLOptions::kNone) {
code_ +=
" static const flatbuffers::TypeTable *MiniReflectTypeTable() {";
code_ += " return {{STRUCT_NAME}}TypeTable();";
@@ -1857,7 +2010,7 @@ class CppGenerator : public BaseGenerator {
}
}
- if (parser_.opts.mutable_buffer) {
+ if (opts_.mutable_buffer && !(is_scalar && IsUnion(field.value.type))) {
if (is_scalar) {
const auto type = GenTypeWire(field.value.type, "", false);
code_.SetValue("SET_FN", "SetField<" + type + ">");
@@ -1939,13 +2092,11 @@ class CppGenerator : public BaseGenerator {
code_ += " &&\n verifier.EndTable();";
code_ += " }";
- if (parser_.opts.generate_object_based_api) {
+ if (opts_.generate_object_based_api) {
// Generate the UnPack() pre declaration.
- code_ +=
- " " + TableUnPackSignature(struct_def, true, parser_.opts) + ";";
- code_ +=
- " " + TableUnPackToSignature(struct_def, true, parser_.opts) + ";";
- code_ += " " + TablePackSignature(struct_def, true, parser_.opts) + ";";
+ code_ += " " + TableUnPackSignature(struct_def, true, opts_) + ";";
+ code_ += " " + TableUnPackToSignature(struct_def, true, opts_) + ";";
+ code_ += " " + TablePackSignature(struct_def, true, opts_) + ";";
}
code_ += "};"; // End of table.
@@ -1990,19 +2141,39 @@ class CppGenerator : public BaseGenerator {
GenBuilders(struct_def);
- if (parser_.opts.generate_object_based_api) {
+ if (opts_.generate_object_based_api) {
// Generate a pre-declaration for a CreateX method that works with an
// unpacked C++ object.
- code_ += TableCreateSignature(struct_def, true, parser_.opts) + ";";
+ code_ += TableCreateSignature(struct_def, true, opts_) + ";";
code_ += "";
}
}
+ // Generate code to force vector alignment. Return empty string for vector
+ // that doesn't need alignment code.
+ std::string GenVectorForceAlign(const FieldDef &field,
+ const std::string &field_size) {
+ FLATBUFFERS_ASSERT(field.value.type.base_type == BASE_TYPE_VECTOR);
+ // Get the value of the force_align attribute.
+ const auto *force_align = field.attributes.Lookup("force_align");
+ const int align = force_align ? atoi(force_align->constant.c_str()) : 1;
+ // Generate code to do force_align for the vector.
+ if (align > 1) {
+ const auto vtype = field.value.type.VectorType();
+ const auto type = IsStruct(vtype) ? WrapInNameSpace(*vtype.struct_def)
+ : GenTypeWire(vtype, "", false);
+ return "_fbb.ForceVectorAlignment(" + field_size + ", sizeof(" + type +
+ "), " + std::to_string(static_cast<long long>(align)) + ");";
+ }
+ return "";
+ }
+
void GenBuilders(const StructDef &struct_def) {
code_.SetValue("STRUCT_NAME", Name(struct_def));
// Generate a builder struct:
code_ += "struct {{STRUCT_NAME}}Builder {";
+ code_ += " typedef {{STRUCT_NAME}} Table;";
code_ += " flatbuffers::FlatBufferBuilder &fbb_;";
code_ += " flatbuffers::uoffset_t start_;";
@@ -2111,6 +2282,16 @@ class CppGenerator : public BaseGenerator {
code_ += "}";
code_ += "";
+ // Definition for type traits for this table type. This allows querying var-
+ // ious compile-time traits of the table.
+ if (opts_.g_cpp_std >= cpp::CPP_STD_17) {
+ code_ += "struct {{STRUCT_NAME}}::Traits {";
+ code_ += " using type = {{STRUCT_NAME}};";
+ code_ += " static auto constexpr Create = Create{{STRUCT_NAME}};";
+ code_ += "};";
+ code_ += "";
+ }
+
// Generate a CreateXDirect function with vector types as parameters
if (has_string_or_vector_fields) {
code_ +=
@@ -2142,16 +2323,29 @@ class CppGenerator : public BaseGenerator {
" auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? "
"_fbb.{{CREATE_STRING}}({{FIELD_NAME}}) : 0;";
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ const std::string force_align_code =
+ GenVectorForceAlign(field, Name(field) + "->size()");
+ if (!force_align_code.empty()) {
+ code_ += " if ({{FIELD_NAME}}) { " + force_align_code + " }";
+ }
code_ += " auto {{FIELD_NAME}}__ = {{FIELD_NAME}} ? \\";
const auto vtype = field.value.type.VectorType();
+ const auto has_key = TypeHasKey(vtype);
if (IsStruct(vtype)) {
const auto type = WrapInNameSpace(*vtype.struct_def);
- code_ += "_fbb.CreateVectorOfStructs<" + type + ">\\";
+ code_ += (has_key ? "_fbb.CreateVectorOfSortedStructs<"
+ : "_fbb.CreateVectorOfStructs<") +
+ type + ">\\";
+ } else if (has_key) {
+ const auto type = WrapInNameSpace(*vtype.struct_def);
+ code_ += "_fbb.CreateVectorOfSortedTables<" + type + ">\\";
} else {
- const auto type = GenTypeWire(vtype, "", false);
+ const auto type =
+ GenTypeWire(vtype, "", VectorElementUserFacing(vtype));
code_ += "_fbb.CreateVector<" + type + ">\\";
}
- code_ += "(*{{FIELD_NAME}}) : 0;";
+ code_ +=
+ has_key ? "({{FIELD_NAME}}) : 0;" : "(*{{FIELD_NAME}}) : 0;";
}
}
}
@@ -2178,8 +2372,8 @@ class CppGenerator : public BaseGenerator {
std::string GenUnionUnpackVal(const FieldDef &afield,
const char *vec_elem_access,
const char *vec_type_access) {
- return afield.value.type.enum_def->name + "Union::UnPack(" + "_e" +
- vec_elem_access + ", " +
+ auto type_name = WrapInNameSpace(*afield.value.type.enum_def);
+ return type_name + "Union::UnPack(" + "_e" + vec_elem_access + ", " +
EscapeKeyword(afield.name + UnionTypeFieldSuffix()) + "()" +
vec_type_access + ", _resolver)";
}
@@ -2209,7 +2403,7 @@ class CppGenerator : public BaseGenerator {
}
} else {
const auto ptype = GenTypeNativePtr(
- NativeName(name, type.struct_def, parser_.opts), &afield, true);
+ NativeName(name, type.struct_def, opts_), &afield, true);
return ptype + "(" + val + "->UnPack(_resolver))";
}
}
@@ -2336,8 +2530,6 @@ class CppGenerator : public BaseGenerator {
}
std::string GenCreateParam(const FieldDef &field) {
- const IDLOptions &opts = parser_.opts;
-
std::string value = "_o->";
if (field.value.type.base_type == BASE_TYPE_UTYPE) {
value += StripUnionType(Name(field));
@@ -2371,22 +2563,24 @@ class CppGenerator : public BaseGenerator {
// For optional fields, check to see if there actually is any data
// in _o->field before attempting to access it. If there isn't,
- // depending on set_empty_to_null either set it to 0 or an empty string.
+ // depending on set_empty_strings_to_null either set it to 0 or an empty
+ // string.
if (!field.required) {
- auto empty_value =
- opts.set_empty_to_null ? "0" : "_fbb.CreateSharedString(\"\")";
+ auto empty_value = opts_.set_empty_strings_to_null
+ ? "0"
+ : "_fbb.CreateSharedString(\"\")";
code = value + ".empty() ? " + empty_value + " : " + code;
}
break;
}
- // Vector fields come in several flavours, of the forms:
- // _fbb.CreateVector(_o->field);
- // _fbb.CreateVector((const utype*)_o->field.data(), _o->field.size());
- // _fbb.CreateVectorOfStrings(_o->field)
- // _fbb.CreateVectorOfStructs(_o->field)
- // _fbb.CreateVector<Offset<T>>(_o->field.size() [&](size_t i) {
- // return CreateT(_fbb, _o->Get(i), rehasher);
- // });
+ // Vector fields come in several flavours, of the forms:
+ // _fbb.CreateVector(_o->field);
+ // _fbb.CreateVector((const utype*)_o->field.data(),
+ // _o->field.size()); _fbb.CreateVectorOfStrings(_o->field)
+ // _fbb.CreateVectorOfStructs(_o->field)
+ // _fbb.CreateVector<Offset<T>>(_o->field.size() [&](size_t i) {
+ // return CreateT(_fbb, _o->Get(i), rehasher);
+ // });
case BASE_TYPE_VECTOR: {
auto vector_type = field.value.type.VectorType();
switch (vector_type.base_type) {
@@ -2453,7 +2647,8 @@ class CppGenerator : public BaseGenerator {
break;
}
default: {
- if (field.value.type.enum_def) {
+ if (field.value.type.enum_def &&
+ !VectorElementUserFacing(vector_type)) {
// For enumerations, we need to get access to the array data for
// the underlying storage type (eg. uint8_t).
const auto basetype = GenTypeBasic(
@@ -2476,10 +2671,10 @@ class CppGenerator : public BaseGenerator {
}
}
- // If set_empty_to_null option is enabled, for optional fields, check to
- // see if there actually is any data in _o->field before attempting to
- // access it.
- if (opts.set_empty_to_null && !field.required) {
+ // If set_empty_vectors_to_null option is enabled, for optional fields,
+ // check to see if there actually is any data in _o->field before
+ // attempting to access it.
+ if (opts_.set_empty_vectors_to_null && !field.required) {
code = value + ".size() ? " + code + " : 0";
}
break;
@@ -2521,20 +2716,27 @@ class CppGenerator : public BaseGenerator {
void GenTablePost(const StructDef &struct_def) {
code_.SetValue("STRUCT_NAME", Name(struct_def));
code_.SetValue("NATIVE_NAME",
- NativeName(Name(struct_def), &struct_def, parser_.opts));
+ NativeName(Name(struct_def), &struct_def, opts_));
+ auto native_name =
+ NativeName(WrapInNameSpace(struct_def), &struct_def, parser_.opts);
+ code_.SetValue("POINTER_TYPE",
+ GenTypeNativePtr(native_name, nullptr, false));
- if (parser_.opts.generate_object_based_api) {
+ if (opts_.generate_object_based_api) {
// Generate the X::UnPack() method.
- code_ += "inline " +
- TableUnPackSignature(struct_def, false, parser_.opts) + " {";
- code_ += " auto _o = new {{NATIVE_NAME}}();";
- code_ += " UnPackTo(_o, _resolver);";
- code_ += " return _o;";
+ code_ +=
+ "inline " + TableUnPackSignature(struct_def, false, opts_) + " {";
+
+ code_ +=
+ " {{POINTER_TYPE}} _o = {{POINTER_TYPE}}(new {{NATIVE_NAME}}());";
+ code_ += " UnPackTo(_o.get(), _resolver);";
+ code_ += " return _o.release();";
+
code_ += "}";
code_ += "";
- code_ += "inline " +
- TableUnPackToSignature(struct_def, false, parser_.opts) + " {";
+ code_ +=
+ "inline " + TableUnPackToSignature(struct_def, false, opts_) + " {";
code_ += " (void)_o;";
code_ += " (void)_resolver;";
@@ -2553,7 +2755,7 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("FIELD_NAME", Name(field));
auto prefix = " { auto _e = {{FIELD_NAME}}(); ";
auto check = IsScalar(field.value.type.base_type) ? "" : "if (_e) ";
- auto postfix = " };";
+ auto postfix = " }";
code_ += std::string(prefix) + check + statement + postfix;
}
code_ += "}";
@@ -2561,15 +2763,14 @@ class CppGenerator : public BaseGenerator {
// Generate the X::Pack member function that simply calls the global
// CreateX function.
- code_ += "inline " + TablePackSignature(struct_def, false, parser_.opts) +
- " {";
+ code_ += "inline " + TablePackSignature(struct_def, false, opts_) + " {";
code_ += " return Create{{STRUCT_NAME}}(_fbb, _o, _rehasher);";
code_ += "}";
code_ += "";
// Generate a CreateX method that works with an unpacked C++ object.
- code_ += "inline " +
- TableCreateSignature(struct_def, false, parser_.opts) + " {";
+ code_ +=
+ "inline " + TableCreateSignature(struct_def, false, opts_) + " {";
code_ += " (void)_rehasher;";
code_ += " (void)_o;";
@@ -2577,7 +2778,7 @@ class CppGenerator : public BaseGenerator {
" struct _VectorArgs "
"{ flatbuffers::FlatBufferBuilder *__fbb; "
"const " +
- NativeName(Name(struct_def), &struct_def, parser_.opts) +
+ NativeName(Name(struct_def), &struct_def, opts_) +
"* __o; "
"const flatbuffers::rehasher_function_t *__rehasher; } _va = { "
"&_fbb, _o, _rehasher}; (void)_va;";
@@ -2586,6 +2787,11 @@ class CppGenerator : public BaseGenerator {
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) { continue; }
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ const std::string force_align_code =
+ GenVectorForceAlign(field, "_o->" + Name(field) + ".size()");
+ if (!force_align_code.empty()) { code_ += " " + force_align_code; }
+ }
code_ += " auto _" + Name(field) + " = " + GenCreateParam(field) + ";";
}
// Need to call "Create" with the struct namespace.
@@ -2642,7 +2848,8 @@ class CppGenerator : public BaseGenerator {
static void PaddingInitializer(int bits, std::string *code_ptr, int *id) {
(void)bits;
- *code_ptr += ",\n padding" + NumToString((*id)++) + "__(0)";
+ if (*code_ptr != "") *code_ptr += ",\n ";
+ *code_ptr += "padding" + NumToString((*id)++) + "__(0)";
}
static void PaddingNoop(int bits, std::string *code_ptr, int *id) {
@@ -2670,10 +2877,14 @@ class CppGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
- code_.SetValue("FIELD_TYPE",
- GenTypeGet(field.value.type, " ", "", " ", false));
+ const auto &field_type = field.value.type;
+ code_.SetValue("FIELD_TYPE", GenTypeGet(field_type, " ", "", " ", false));
code_.SetValue("FIELD_NAME", Name(field));
- code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}_;";
+ code_.SetValue("ARRAY",
+ IsArray(field_type)
+ ? "[" + NumToString(field_type.fixed_length) + "]"
+ : "");
+ code_ += (" {{FIELD_TYPE}}{{FIELD_NAME}}_{{ARRAY}};");
if (field.padding) {
std::string padding;
@@ -2687,7 +2898,7 @@ class CppGenerator : public BaseGenerator {
code_ += " public:";
// Make TypeTable accessible via the generated struct.
- if (parser_.opts.mini_reflect != IDLOptions::kNone) {
+ if (opts_.mini_reflect != IDLOptions::kNone) {
code_ +=
" static const flatbuffers::TypeTable *MiniReflectTypeTable() {";
code_ += " return {{STRUCT_NAME}}TypeTable();";
@@ -2698,33 +2909,40 @@ class CppGenerator : public BaseGenerator {
// Generate a default constructor.
code_ += " {{STRUCT_NAME}}() {";
- code_ += " memset(static_cast<void *>(this), 0, sizeof({{STRUCT_NAME}}));";
+ code_ +=
+ " memset(static_cast<void *>(this), 0, sizeof({{STRUCT_NAME}}));";
code_ += " }";
- // Generate a constructor that takes all fields as arguments.
+ // Generate a constructor that takes all fields as arguments,
+ // excluding arrays
std::string arg_list;
std::string init_list;
padding_id = 0;
+ auto first = struct_def.fields.vec.begin();
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
+ if (IsArray(field.value.type)) {
+ first++;
+ continue;
+ }
const auto member_name = Name(field) + "_";
const auto arg_name = "_" + Name(field);
const auto arg_type =
GenTypeGet(field.value.type, " ", "const ", " &", true);
- if (it != struct_def.fields.vec.begin()) {
- arg_list += ", ";
- init_list += ",\n ";
- }
+ if (it != first) { arg_list += ", "; }
arg_list += arg_type;
arg_list += arg_name;
- init_list += member_name;
- if (IsScalar(field.value.type.base_type)) {
- auto type = GenUnderlyingCast(field, false, arg_name);
- init_list += "(flatbuffers::EndianScalar(" + type + "))";
- } else {
- init_list += "(" + arg_name + ")";
+ if (!IsArray(field.value.type)) {
+ if (it != first && init_list != "") { init_list += ",\n "; }
+ init_list += member_name;
+ if (IsScalar(field.value.type.base_type)) {
+ auto type = GenUnderlyingCast(field, false, arg_name);
+ init_list += "(flatbuffers::EndianScalar(" + type + "))";
+ } else {
+ init_list += "(" + arg_name + ")";
+ }
}
if (field.padding) {
GenPadding(field, &init_list, &padding_id, PaddingInitializer);
@@ -2734,12 +2952,21 @@ class CppGenerator : public BaseGenerator {
if (!arg_list.empty()) {
code_.SetValue("ARG_LIST", arg_list);
code_.SetValue("INIT_LIST", init_list);
- code_ += " {{STRUCT_NAME}}({{ARG_LIST}})";
- code_ += " : {{INIT_LIST}} {";
+ if (!init_list.empty()) {
+ code_ += " {{STRUCT_NAME}}({{ARG_LIST}})";
+ code_ += " : {{INIT_LIST}} {";
+ } else {
+ code_ += " {{STRUCT_NAME}}({{ARG_LIST}}) {";
+ }
padding_id = 0;
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
+ if (IsArray(field.value.type)) {
+ const auto &member = Name(field) + "_";
+ code_ +=
+ " std::memset(" + member + ", 0, sizeof(" + member + "));";
+ }
if (field.padding) {
std::string padding;
GenPadding(field, &padding, &padding_id, PaddingNoop);
@@ -2755,7 +2982,9 @@ class CppGenerator : public BaseGenerator {
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
- auto field_type = GenTypeGet(field.value.type, " ", "const ", " &", true);
+ auto field_type = GenTypeGet(field.value.type, " ",
+ IsArray(field.value.type) ? "" : "const ",
+ IsArray(field.value.type) ? "" : " &", true);
auto is_scalar = IsScalar(field.value.type.base_type);
auto member = Name(field) + "_";
auto value =
@@ -2766,12 +2995,29 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("FIELD_VALUE", GenUnderlyingCast(field, true, value));
GenComment(field.doc_comment, " ");
- code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
- code_ += " return {{FIELD_VALUE}};";
- code_ += " }";
- if (parser_.opts.mutable_buffer) {
- auto mut_field_type = GenTypeGet(field.value.type, " ", "", " &", true);
+ // Generate a const accessor function.
+ if (IsArray(field.value.type)) {
+ auto underlying = GenTypeGet(field.value.type, "", "", "", false);
+ code_ += " const flatbuffers::Array<" + field_type + ", " +
+ NumToString(field.value.type.fixed_length) + "> *" +
+ "{{FIELD_NAME}}() const {";
+ code_ += " return reinterpret_cast<const flatbuffers::Array<" +
+ field_type + ", " +
+ NumToString(field.value.type.fixed_length) +
+ "> *>({{FIELD_VALUE}});";
+ code_ += " }";
+ } else {
+ code_ += " {{FIELD_TYPE}}{{FIELD_NAME}}() const {";
+ code_ += " return {{FIELD_VALUE}};";
+ code_ += " }";
+ }
+
+ // Generate a mutable accessor function.
+ if (opts_.mutable_buffer) {
+ auto mut_field_type =
+ GenTypeGet(field.value.type, " ", "",
+ IsArray(field.value.type) ? "" : " &", true);
code_.SetValue("FIELD_TYPE", mut_field_type);
if (is_scalar) {
code_.SetValue("ARG", GenTypeBasic(field.value.type, true));
@@ -2783,9 +3029,19 @@ class CppGenerator : public BaseGenerator {
" flatbuffers::WriteScalar(&{{FIELD_NAME}}_, "
"{{FIELD_VALUE}});";
code_ += " }";
+ } else if (IsArray(field.value.type)) {
+ auto underlying = GenTypeGet(field.value.type, "", "", "", false);
+ code_ += " flatbuffers::Array<" + mut_field_type + ", " +
+ NumToString(field.value.type.fixed_length) + "> *" +
+ "mutable_{{FIELD_NAME}}() {";
+ code_ += " return reinterpret_cast<flatbuffers::Array<" +
+ mut_field_type + ", " +
+ NumToString(field.value.type.fixed_length) +
+ "> *>({{FIELD_VALUE}});";
+ code_ += " }";
} else {
code_ += " {{FIELD_TYPE}}mutable_{{FIELD_NAME}}() {";
- code_ += " return {{FIELD_NAME}}_;";
+ code_ += " return {{FIELD_VALUE}};";
code_ += " }";
}
}
@@ -2799,7 +3055,7 @@ class CppGenerator : public BaseGenerator {
code_.SetValue("STRUCT_BYTE_SIZE", NumToString(struct_def.bytesize));
code_ += "FLATBUFFERS_STRUCT_END({{STRUCT_NAME}}, {{STRUCT_BYTE_SIZE}});";
- if (parser_.opts.gen_compare) GenCompareOperator(struct_def, "()");
+ if (opts_.gen_compare) GenCompareOperator(struct_def, "()");
code_ += "";
}
@@ -2841,15 +3097,39 @@ class CppGenerator : public BaseGenerator {
cur_name_space_ = ns;
}
-
- const TypedFloatConstantGenerator float_const_gen_;
};
} // namespace cpp
bool GenerateCPP(const Parser &parser, const std::string &path,
const std::string &file_name) {
- cpp::CppGenerator generator(parser, path, file_name);
+ cpp::IDLOptionsCpp opts(parser.opts);
+ // The '--cpp_std' argument could be extended (like ASAN):
+ // Example: "flatc --cpp_std c++17:option1:option2".
+ auto cpp_std = !opts.cpp_std.empty() ? opts.cpp_std : "C++0X";
+ std::transform(cpp_std.begin(), cpp_std.end(), cpp_std.begin(), ToUpper);
+ if (cpp_std == "C++0X") {
+ opts.g_cpp_std = cpp::CPP_STD_X0;
+ opts.g_only_fixed_enums = false;
+ } else if (cpp_std == "C++11") {
+ // Use the standard C++11 code generator.
+ opts.g_cpp_std = cpp::CPP_STD_11;
+ opts.g_only_fixed_enums = true;
+ } else if (cpp_std == "C++17") {
+ opts.g_cpp_std = cpp::CPP_STD_17;
+ // With c++17 generate strong enums only.
+ opts.scoped_enums = true;
+ // By default, prefixed_enums==true, reset it.
+ opts.prefixed_enums = false;
+ } else {
+ LogCompilerError("Unknown value of the '--cpp-std' switch: " +
+ opts.cpp_std);
+ return false;
+ }
+ // The opts.scoped_enums has priority.
+ opts.g_only_fixed_enums |= opts.scoped_enums;
+
+ cpp::CppGenerator generator(parser, path, file_name, opts);
return generator.generate();
}
@@ -2857,8 +3137,10 @@ std::string CPPMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) {
const auto filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
+ cpp::CppGenerator geneartor(parser, path, file_name, parser.opts);
const auto included_files = parser.GetIncludedFilesRecursive(file_name);
- std::string make_rule = GeneratedFileName(path, filebase) + ": ";
+ std::string make_rule =
+ geneartor.GeneratedFileName(path, filebase, parser.opts) + ": ";
for (auto it = included_files.begin(); it != included_files.end(); ++it) {
make_rule += " " + *it;
}
diff --git a/src/idl_gen_csharp.cpp b/src/idl_gen_csharp.cpp
new file mode 100644
index 00000000..7db40fab
--- /dev/null
+++ b/src/idl_gen_csharp.cpp
@@ -0,0 +1,2021 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#if defined(FLATBUFFERS_CPP98_STL)
+# include <cctype>
+#endif // defined(FLATBUFFERS_CPP98_STL)
+
+namespace flatbuffers {
+
+static TypedFloatConstantGenerator CSharpFloatGen("Double.", "Single.", "NaN",
+ "PositiveInfinity",
+ "NegativeInfinity");
+static CommentConfig comment_config = {
+ nullptr,
+ "///",
+ nullptr,
+};
+
+namespace csharp {
+class CSharpGenerator : public BaseGenerator {
+ public:
+ CSharpGenerator(const Parser &parser, const std::string &path,
+ const std::string &file_name)
+ : BaseGenerator(parser, path, file_name, "", ".", "cs"),
+ cur_name_space_(nullptr) {}
+
+ CSharpGenerator &operator=(const CSharpGenerator &);
+
+ bool generate() {
+ std::string one_file_code;
+ cur_name_space_ = parser_.current_namespace_;
+
+ for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+ ++it) {
+ std::string enumcode;
+ auto &enum_def = **it;
+ if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
+ GenEnum(enum_def, &enumcode, parser_.opts);
+ if (parser_.opts.one_file) {
+ one_file_code += enumcode;
+ } else {
+ if (!SaveType(enum_def.name, *enum_def.defined_namespace, enumcode,
+ false))
+ return false;
+ }
+ }
+
+ for (auto it = parser_.structs_.vec.begin();
+ it != parser_.structs_.vec.end(); ++it) {
+ std::string declcode;
+ auto &struct_def = **it;
+ if (!parser_.opts.one_file)
+ cur_name_space_ = struct_def.defined_namespace;
+ GenStruct(struct_def, &declcode, parser_.opts);
+ if (parser_.opts.one_file) {
+ one_file_code += declcode;
+ } else {
+ if (!SaveType(struct_def.name, *struct_def.defined_namespace, declcode,
+ true))
+ return false;
+ }
+ }
+
+ if (parser_.opts.one_file) {
+ return SaveType(file_name_, *parser_.current_namespace_, one_file_code,
+ true);
+ }
+ return true;
+ }
+
+ // Save out the generated code for a single class while adding
+ // declaration boilerplate.
+ bool SaveType(const std::string &defname, const Namespace &ns,
+ const std::string &classcode, bool needs_includes) const {
+ if (!classcode.length()) return true;
+
+ std::string code =
+ "// <auto-generated>\n"
+ "// " +
+ std::string(FlatBuffersGeneratedWarning()) +
+ "\n"
+ "// </auto-generated>\n\n";
+
+ std::string namespace_name = FullNamespace(".", ns);
+ if (!namespace_name.empty()) {
+ code += "namespace " + namespace_name + "\n{\n\n";
+ }
+ if (needs_includes) {
+ code += "using global::System;\n";
+ code += "using global::System.Collections.Generic;\n";
+ code += "using global::FlatBuffers;\n\n";
+ }
+ code += classcode;
+ if (!namespace_name.empty()) { code += "\n}\n"; }
+ auto filename = NamespaceDir(ns) + defname + ".cs";
+ return SaveFile(filename.c_str(), code, false);
+ }
+
+ const Namespace *CurrentNameSpace() const { return cur_name_space_; }
+
+ std::string GenTypeBasic(const Type &type, bool enableLangOverrides) const {
+ // clang-format off
+ static const char * const csharp_typename[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, ...) \
+ #NTYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ };
+ // clang-format on
+
+ if (enableLangOverrides) {
+ if (IsEnum(type)) return WrapInNameSpace(*type.enum_def);
+ if (type.base_type == BASE_TYPE_STRUCT) {
+ return "Offset<" + WrapInNameSpace(*type.struct_def) + ">";
+ }
+ }
+
+ return csharp_typename[type.base_type];
+ }
+
+ inline std::string GenTypeBasic(const Type &type) const {
+ return GenTypeBasic(type, true);
+ }
+
+ std::string GenTypePointer(const Type &type) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "string";
+ case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+ case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
+ case BASE_TYPE_UNION: return "TTable";
+ default: return "Table";
+ }
+ }
+
+ std::string GenTypeGet(const Type &type) const {
+ return IsScalar(type.base_type)
+ ? GenTypeBasic(type)
+ : (IsArray(type) ? GenTypeGet(type.VectorType())
+ : GenTypePointer(type));
+ }
+
+ std::string GenOffsetType(const StructDef &struct_def) const {
+ return "Offset<" + WrapInNameSpace(struct_def) + ">";
+ }
+
+ std::string GenOffsetConstruct(const StructDef &struct_def,
+ const std::string &variable_name) const {
+ return "new Offset<" + WrapInNameSpace(struct_def) + ">(" + variable_name +
+ ")";
+ }
+
+ // Casts necessary to correctly read serialized data
+ std::string DestinationCast(const Type &type) const {
+ if (IsSeries(type)) {
+ return DestinationCast(type.VectorType());
+ } else {
+ if (IsEnum(type)) return "(" + WrapInNameSpace(*type.enum_def) + ")";
+ }
+ return "";
+ }
+
+ // Cast statements for mutator method parameters.
+ // In Java, parameters representing unsigned numbers need to be cast down to
+ // their respective type. For example, a long holding an unsigned int value
+ // would be cast down to int before being put onto the buffer. In C#, one cast
+ // directly cast an Enum to its underlying type, which is essential before
+ // putting it onto the buffer.
+ std::string SourceCast(const Type &type) const {
+ if (IsSeries(type)) {
+ return SourceCast(type.VectorType());
+ } else {
+ if (IsEnum(type)) return "(" + GenTypeBasic(type, false) + ")";
+ }
+ return "";
+ }
+
+ std::string SourceCastBasic(const Type &type) const {
+ return IsScalar(type.base_type) ? SourceCast(type) : "";
+ }
+
+ std::string GenEnumDefaultValue(const FieldDef &field) const {
+ auto &value = field.value;
+ FLATBUFFERS_ASSERT(value.type.enum_def);
+ auto &enum_def = *value.type.enum_def;
+ auto enum_val = enum_def.FindByValue(value.constant);
+ return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
+ : value.constant;
+ }
+
+ std::string GenDefaultValue(const FieldDef &field,
+ bool enableLangOverrides) const {
+ auto &value = field.value;
+ if (enableLangOverrides) {
+ // handles both enum case and vector of enum case
+ if (value.type.enum_def != nullptr &&
+ value.type.base_type != BASE_TYPE_UNION) {
+ return GenEnumDefaultValue(field);
+ }
+ }
+
+ auto longSuffix = "";
+ switch (value.type.base_type) {
+ case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
+ case BASE_TYPE_ULONG: return value.constant;
+ case BASE_TYPE_UINT:
+ case BASE_TYPE_LONG: return value.constant + longSuffix;
+ default:
+ if (IsFloat(value.type.base_type))
+ return CSharpFloatGen.GenFloatConstant(field);
+ else
+ return value.constant;
+ }
+ }
+
+ std::string GenDefaultValue(const FieldDef &field) const {
+ return GenDefaultValue(field, true);
+ }
+
+ std::string GenDefaultValueBasic(const FieldDef &field,
+ bool enableLangOverrides) const {
+ auto &value = field.value;
+ if (!IsScalar(value.type.base_type)) {
+ if (enableLangOverrides) {
+ switch (value.type.base_type) {
+ case BASE_TYPE_STRING: return "default(StringOffset)";
+ case BASE_TYPE_STRUCT:
+ return "default(Offset<" + WrapInNameSpace(*value.type.struct_def) +
+ ">)";
+ case BASE_TYPE_VECTOR: return "default(VectorOffset)";
+ default: break;
+ }
+ }
+ return "0";
+ }
+ return GenDefaultValue(field, enableLangOverrides);
+ }
+
+ std::string GenDefaultValueBasic(const FieldDef &field) const {
+ return GenDefaultValueBasic(field, true);
+ }
+
+ void GenEnum(EnumDef &enum_def, std::string *code_ptr,
+ const IDLOptions &opts) const {
+ std::string &code = *code_ptr;
+ if (enum_def.generated) return;
+
+ // Generate enum definitions of the form:
+ // public static (final) int name = value;
+ // In Java, we use ints rather than the Enum feature, because we want them
+ // to map directly to how they're used in C/C++ and file formats.
+ // That, and Java Enums are expensive, and not universally liked.
+ GenComment(enum_def.doc_comment, code_ptr, &comment_config);
+
+ if (opts.cs_gen_json_serializer && opts.generate_object_based_api) {
+ code +=
+ "[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters."
+ "StringEnumConverter))]\n";
+ }
+ // In C# this indicates enumeration values can be treated as bit flags.
+ if (enum_def.attributes.Lookup("bit_flags")) {
+ code += "[System.FlagsAttribute]\n";
+ }
+ if (enum_def.attributes.Lookup("private")) {
+ code += "internal ";
+ } else {
+ code += "public ";
+ }
+ code += "enum " + enum_def.name;
+ code += " : " + GenTypeBasic(enum_def.underlying_type, false);
+ code += "\n{\n";
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ auto &ev = **it;
+ GenComment(ev.doc_comment, code_ptr, &comment_config, " ");
+ code += " ";
+ code += ev.name + " = ";
+ code += enum_def.ToString(ev);
+ code += ",\n";
+ }
+ // Close the class
+ code += "};\n\n";
+
+ if (opts.generate_object_based_api) {
+ GenEnum_ObjectAPI(enum_def, code_ptr, opts);
+ }
+ }
+
+ bool HasUnionStringValue(const EnumDef &enum_def) const {
+ if (!enum_def.is_union) return false;
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ auto &val = **it;
+ if (val.union_type.base_type == BASE_TYPE_STRING) { return true; }
+ }
+ return false;
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string GenGetter(const Type &type) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "__p.__string";
+ case BASE_TYPE_STRUCT: return "__p.__struct";
+ case BASE_TYPE_UNION: return "__p.__union";
+ case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
+ case BASE_TYPE_ARRAY: return GenGetter(type.VectorType());
+ default: {
+ std::string getter = "__p.bb.Get";
+ if (type.base_type == BASE_TYPE_BOOL) {
+ getter = "0!=" + getter;
+ } else if (GenTypeBasic(type, false) != "byte") {
+ getter += MakeCamel(GenTypeBasic(type, false));
+ }
+ return getter;
+ }
+ }
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string GenGetterForLookupByKey(flatbuffers::FieldDef *key_field,
+ const std::string &data_buffer,
+ const char *num = nullptr) const {
+ auto type = key_field->value.type;
+ auto dest_mask = "";
+ auto dest_cast = DestinationCast(type);
+ auto getter = data_buffer + ".Get";
+ if (GenTypeBasic(type, false) != "byte") {
+ getter += MakeCamel(GenTypeBasic(type, false));
+ }
+ getter = dest_cast + getter + "(" + GenOffsetGetter(key_field, num) + ")" +
+ dest_mask;
+ return getter;
+ }
+
+ // Direct mutation is only allowed for scalar fields.
+ // Hence a setter method will only be generated for such fields.
+ std::string GenSetter(const Type &type) const {
+ if (IsScalar(type.base_type)) {
+ std::string setter = "__p.bb.Put";
+ if (GenTypeBasic(type, false) != "byte" &&
+ type.base_type != BASE_TYPE_BOOL) {
+ setter += MakeCamel(GenTypeBasic(type, false));
+ }
+ return setter;
+ } else {
+ return "";
+ }
+ }
+
+ // Returns the method name for use with add/put calls.
+ std::string GenMethod(const Type &type) const {
+ return IsScalar(type.base_type) ? MakeCamel(GenTypeBasic(type, false))
+ : (IsStruct(type) ? "Struct" : "Offset");
+ }
+
+ // Recursively generate arguments for a constructor, to deal with nested
+ // structs.
+ void GenStructArgs(const StructDef &struct_def, std::string *code_ptr,
+ const char *nameprefix, size_t array_count = 0) const {
+ std::string &code = *code_ptr;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ const auto &field_type = field.value.type;
+ const auto array_field = IsArray(field_type);
+ const auto &type = array_field ? field_type.VectorType() : field_type;
+ const auto array_cnt = array_field ? (array_count + 1) : array_count;
+ if (IsStruct(type)) {
+ // Generate arguments for a struct inside a struct. To ensure names
+ // don't clash, and to make it obvious these arguments are constructing
+ // a nested struct, prefix the name with the field name.
+ GenStructArgs(*field_type.struct_def, code_ptr,
+ (nameprefix + (field.name + "_")).c_str(), array_cnt);
+ } else {
+ code += ", ";
+ code += GenTypeBasic(type);
+ if (array_cnt > 0) {
+ code += "[";
+ for (size_t i = 1; i < array_cnt; i++) code += ",";
+ code += "]";
+ }
+ code += " ";
+ code += nameprefix;
+ code += MakeCamel(field.name, true);
+ }
+ }
+ }
+
+ // Recusively generate struct construction statements of the form:
+ // builder.putType(name);
+ // and insert manual padding.
+ void GenStructBody(const StructDef &struct_def, std::string *code_ptr,
+ const char *nameprefix, size_t index = 0,
+ bool in_array = false) const {
+ std::string &code = *code_ptr;
+ std::string indent((index + 1) * 2, ' ');
+ code += indent + " builder.Prep(";
+ code += NumToString(struct_def.minalign) + ", ";
+ code += NumToString(struct_def.bytesize) + ");\n";
+ for (auto it = struct_def.fields.vec.rbegin();
+ it != struct_def.fields.vec.rend(); ++it) {
+ auto &field = **it;
+ const auto &field_type = field.value.type;
+ if (field.padding) {
+ code += indent + " builder.Pad(";
+ code += NumToString(field.padding) + ");\n";
+ }
+ if (IsStruct(field_type)) {
+ GenStructBody(*field_type.struct_def, code_ptr,
+ (nameprefix + (field.name + "_")).c_str(), index,
+ in_array);
+ } else {
+ const auto &type =
+ IsArray(field_type) ? field_type.VectorType() : field_type;
+ const auto index_var = "_idx" + NumToString(index);
+ if (IsArray(field_type)) {
+ code += indent + " for (int " + index_var + " = ";
+ code += NumToString(field_type.fixed_length);
+ code += "; " + index_var + " > 0; " + index_var + "--) {\n";
+ in_array = true;
+ }
+ if (IsStruct(type)) {
+ GenStructBody(*field_type.struct_def, code_ptr,
+ (nameprefix + (field.name + "_")).c_str(), index + 1,
+ in_array);
+ } else {
+ code += IsArray(field_type) ? " " : "";
+ code += indent + " builder.Put";
+ code += GenMethod(type) + "(";
+ code += SourceCast(type);
+ auto argname = nameprefix + MakeCamel(field.name, true);
+ code += argname;
+ size_t array_cnt = index + (IsArray(field_type) ? 1 : 0);
+ if (array_cnt > 0) {
+ code += "[";
+ for (size_t i = 0; in_array && i < array_cnt; i++) {
+ code += "_idx" + NumToString(i) + "-1";
+ if (i != (array_cnt - 1)) code += ",";
+ }
+ code += "]";
+ }
+ code += ");\n";
+ }
+ if (IsArray(field_type)) { code += indent + " }\n"; }
+ }
+ }
+ }
+ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
+ const char *num = nullptr) const {
+ std::string key_offset =
+ "Table.__offset(" + NumToString(key_field->value.offset) + ", ";
+ if (num) {
+ key_offset += num;
+ key_offset += ".Value, builder.DataBuffer)";
+ } else {
+ key_offset += "bb.Length";
+ key_offset += " - tableOffset, bb)";
+ }
+ return key_offset;
+ }
+
+ std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) const {
+ std::string key_getter = " ";
+ key_getter += "int tableOffset = Table.";
+ key_getter += "__indirect(vectorLocation + 4 * (start + middle)";
+ key_getter += ", bb);\n ";
+ if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+ key_getter += "int comp = Table.";
+ key_getter += "CompareStrings(";
+ key_getter += GenOffsetGetter(key_field);
+ key_getter += ", byteKey, bb);\n";
+ } else {
+ auto get_val = GenGetterForLookupByKey(key_field, "bb");
+ key_getter += "int comp = " + get_val + ".CompareTo(key);\n";
+ }
+ return key_getter;
+ }
+
+ std::string GenKeyGetter(flatbuffers::FieldDef *key_field) const {
+ std::string key_getter = "";
+ auto data_buffer = "builder.DataBuffer";
+ if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+ key_getter += "Table.CompareStrings(";
+ key_getter += GenOffsetGetter(key_field, "o1") + ", ";
+ key_getter += GenOffsetGetter(key_field, "o2") + ", " + data_buffer + ")";
+ } else {
+ auto field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o1");
+ key_getter += field_getter;
+ field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o2");
+ key_getter += ".CompareTo(" + field_getter + ")";
+ }
+ return key_getter;
+ }
+
+ void GenStruct(StructDef &struct_def, std::string *code_ptr,
+ const IDLOptions &opts) const {
+ if (struct_def.generated) return;
+ std::string &code = *code_ptr;
+
+ // Generate a struct accessor class, with methods of the form:
+ // public type name() { return bb.getType(i + offset); }
+ // or for tables of the form:
+ // public type name() {
+ // int o = __offset(offset); return o != 0 ? bb.getType(o + i) : default;
+ // }
+ GenComment(struct_def.doc_comment, code_ptr, &comment_config);
+ if (struct_def.attributes.Lookup("private")) {
+ code += "internal ";
+ } else {
+ code += "public ";
+ }
+ if (struct_def.attributes.Lookup("csharp_partial")) {
+ // generate a partial class for this C# struct/table
+ code += "partial ";
+ }
+ code += "struct " + struct_def.name;
+ code += " : IFlatbufferObject";
+ code += "\n{\n";
+ code += " private ";
+ code += struct_def.fixed ? "Struct" : "Table";
+ code += " __p;\n";
+
+ code += " public ByteBuffer ByteBuffer { get { return __p.bb; } }\n";
+
+ if (!struct_def.fixed) {
+ // Generate verson check method.
+ // Force compile time error if not using the same version runtime.
+ code += " public static void ValidateVersion() {";
+ code += " FlatBufferConstants.";
+ code += "FLATBUFFERS_1_12_0(); ";
+ code += "}\n";
+
+ // Generate a special accessor for the table that when used as the root
+ // of a FlatBuffer
+ std::string method_name = "GetRootAs" + struct_def.name;
+ std::string method_signature =
+ " public static " + struct_def.name + " " + method_name;
+
+ // create convenience method that doesn't require an existing object
+ code += method_signature + "(ByteBuffer _bb) ";
+ code += "{ return " + method_name + "(_bb, new " + struct_def.name +
+ "()); }\n";
+
+ // create method that allows object reuse
+ code +=
+ method_signature + "(ByteBuffer _bb, " + struct_def.name + " obj) { ";
+ code += "return (obj.__assign(_bb.GetInt(_bb.Position";
+ code += ") + _bb.Position";
+ code += ", _bb)); }\n";
+ if (parser_.root_struct_def_ == &struct_def) {
+ if (parser_.file_identifier_.length()) {
+ // Check if a buffer has the identifier.
+ code += " public static ";
+ code += "bool " + struct_def.name;
+ code += "BufferHasIdentifier(ByteBuffer _bb) { return ";
+ code += "Table.__has_identifier(_bb, \"";
+ code += parser_.file_identifier_;
+ code += "\"); }\n";
+ }
+ }
+ }
+ // Generate the __init method that sets the field in a pre-existing
+ // accessor object. This is to allow object reuse.
+ code += " public void __init(int _i, ByteBuffer _bb) ";
+ code += "{ ";
+ code += "__p = new ";
+ code += struct_def.fixed ? "Struct" : "Table";
+ code += "(_i, _bb); ";
+ code += "}\n";
+ code +=
+ " public " + struct_def.name + " __assign(int _i, ByteBuffer _bb) ";
+ code += "{ __init(_i, _bb); return this; }\n\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ GenComment(field.doc_comment, code_ptr, &comment_config, " ");
+ std::string type_name = GenTypeGet(field.value.type);
+ std::string type_name_dest = GenTypeGet(field.value.type);
+ std::string conditional_cast = "";
+ std::string optional = "";
+ if (!struct_def.fixed &&
+ (field.value.type.base_type == BASE_TYPE_STRUCT ||
+ field.value.type.base_type == BASE_TYPE_UNION ||
+ (field.value.type.base_type == BASE_TYPE_VECTOR &&
+ (field.value.type.element == BASE_TYPE_STRUCT ||
+ field.value.type.element == BASE_TYPE_UNION)))) {
+ optional = "?";
+ conditional_cast = "(" + type_name_dest + optional + ")";
+ }
+ std::string dest_mask = "";
+ std::string dest_cast = DestinationCast(field.value.type);
+ std::string src_cast = SourceCast(field.value.type);
+ std::string method_start = " public " + type_name_dest + optional + " " +
+ MakeCamel(field.name, true);
+ std::string obj = "(new " + type_name + "())";
+
+ // Most field accessors need to retrieve and test the field offset first,
+ // this is the prefix code for that:
+ auto offset_prefix =
+ IsArray(field.value.type)
+ ? " { return "
+ : (" { int o = __p.__offset(" + NumToString(field.value.offset) +
+ "); return o != 0 ? ");
+ // Generate the accessors that don't do object reuse.
+ if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+ } else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
+ field.value.type.element == BASE_TYPE_STRUCT) {
+ } else if (field.value.type.base_type == BASE_TYPE_UNION ||
+ (field.value.type.base_type == BASE_TYPE_VECTOR &&
+ field.value.type.VectorType().base_type == BASE_TYPE_UNION)) {
+ method_start += "<TTable>";
+ type_name = type_name_dest;
+ }
+ std::string getter = dest_cast + GenGetter(field.value.type);
+ code += method_start;
+ std::string default_cast = "";
+ // only create default casts for c# scalars or vectors of scalars
+ if ((IsScalar(field.value.type.base_type) ||
+ (field.value.type.base_type == BASE_TYPE_VECTOR &&
+ IsScalar(field.value.type.element)))) {
+ // For scalars, default value will be returned by GetDefaultValue().
+ // If the scalar is an enum, GetDefaultValue() returns an actual c# enum
+ // that doesn't need to be casted. However, default values for enum
+ // elements of vectors are integer literals ("0") and are still casted
+ // for clarity.
+ if (field.value.type.enum_def == nullptr ||
+ field.value.type.base_type == BASE_TYPE_VECTOR) {
+ default_cast = "(" + type_name_dest + ")";
+ }
+ }
+ std::string member_suffix = "; ";
+ if (IsScalar(field.value.type.base_type)) {
+ code += " { get";
+ member_suffix += "} ";
+ if (struct_def.fixed) {
+ code += " { return " + getter;
+ code += "(__p.bb_pos + ";
+ code += NumToString(field.value.offset) + ")";
+ code += dest_mask;
+ } else {
+ code += offset_prefix + getter;
+ code += "(o + __p.bb_pos)" + dest_mask;
+ code += " : " + default_cast;
+ code += GenDefaultValue(field);
+ }
+ } else {
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT:
+ code += " { get";
+ member_suffix += "} ";
+ if (struct_def.fixed) {
+ code += " { return " + obj + ".__assign(" + "__p.";
+ code += "bb_pos + " + NumToString(field.value.offset) + ", ";
+ code += "__p.bb)";
+ } else {
+ code += offset_prefix + conditional_cast;
+ code += obj + ".__assign(";
+ code += field.value.type.struct_def->fixed
+ ? "o + __p.bb_pos"
+ : "__p.__indirect(o + __p.bb_pos)";
+ code += ", __p.bb) : null";
+ }
+ break;
+ case BASE_TYPE_STRING:
+ code += " { get";
+ member_suffix += "} ";
+ code += offset_prefix + getter + "(o + " + "__p.";
+ code += "bb_pos) : null";
+ break;
+ case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_VECTOR: {
+ auto vectortype = field.value.type.VectorType();
+ if (vectortype.base_type == BASE_TYPE_UNION) {
+ conditional_cast = "(TTable?)";
+ getter += "<TTable>";
+ }
+ code += "(";
+ if (vectortype.base_type == BASE_TYPE_STRUCT) {
+ getter = obj + ".__assign";
+ } else if (vectortype.base_type == BASE_TYPE_UNION) {
+ }
+ code += "int j)";
+ const auto body = offset_prefix + conditional_cast + getter + "(";
+ if (vectortype.base_type == BASE_TYPE_UNION) {
+ code += " where TTable : struct, IFlatbufferObject" + body;
+ } else {
+ code += body;
+ }
+ std::string index = "__p.";
+ if (IsArray(field.value.type)) {
+ index += "bb_pos + " + NumToString(field.value.offset) + " + ";
+ } else {
+ index += "__vector(o) + ";
+ }
+ index += "j * " + NumToString(InlineSize(vectortype));
+ if (vectortype.base_type == BASE_TYPE_STRUCT) {
+ code += vectortype.struct_def->fixed
+ ? index
+ : "__p.__indirect(" + index + ")";
+ code += ", __p.bb";
+ } else {
+ code += index;
+ }
+ code += ")" + dest_mask;
+ if (!IsArray(field.value.type)) {
+ code += " : ";
+ code +=
+ field.value.type.element == BASE_TYPE_BOOL
+ ? "false"
+ : (IsScalar(field.value.type.element) ? default_cast + "0"
+ : "null");
+ }
+ if (vectortype.base_type == BASE_TYPE_UNION &&
+ HasUnionStringValue(*vectortype.enum_def)) {
+ code += member_suffix;
+ code += "}\n";
+ code += " public string " + MakeCamel(field.name, true) +
+ "AsString(int j)";
+ code += offset_prefix + GenGetter(Type(BASE_TYPE_STRING));
+ code += "(" + index + ") : null";
+ }
+ break;
+ }
+ case BASE_TYPE_UNION:
+ code += "() where TTable : struct, IFlatbufferObject";
+ code += offset_prefix + "(TTable?)" + getter;
+ code += "<TTable>(o + __p.bb_pos) : null";
+ if (HasUnionStringValue(*field.value.type.enum_def)) {
+ code += member_suffix;
+ code += "}\n";
+ code += " public string " + MakeCamel(field.name, true) +
+ "AsString()";
+ code += offset_prefix + GenGetter(Type(BASE_TYPE_STRING));
+ code += "(o + __p.bb_pos) : null";
+ }
+ break;
+ default: FLATBUFFERS_ASSERT(0);
+ }
+ }
+ code += member_suffix;
+ code += "}\n";
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ code += " public int " + MakeCamel(field.name, true);
+ code += "Length";
+ code += " { get";
+ code += offset_prefix;
+ code += "__p.__vector_len(o) : 0; ";
+ code += "} ";
+ code += "}\n";
+ // See if we should generate a by-key accessor.
+ if (field.value.type.element == BASE_TYPE_STRUCT &&
+ !field.value.type.struct_def->fixed) {
+ auto &sd = *field.value.type.struct_def;
+ auto &fields = sd.fields.vec;
+ for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+ auto &key_field = **kit;
+ if (key_field.key) {
+ auto qualified_name = WrapInNameSpace(sd);
+ code += " public " + qualified_name + "? ";
+ code += MakeCamel(field.name, true) + "ByKey(";
+ code += GenTypeGet(key_field.value.type) + " key)";
+ code += offset_prefix;
+ code += qualified_name + ".__lookup_by_key(";
+ code += "__p.__vector(o), key, ";
+ code += "__p.bb) : null; ";
+ code += "}\n";
+ break;
+ }
+ }
+ }
+ }
+ // Generate a ByteBuffer accessor for strings & vectors of scalars.
+ if ((field.value.type.base_type == BASE_TYPE_VECTOR &&
+ IsScalar(field.value.type.VectorType().base_type)) ||
+ field.value.type.base_type == BASE_TYPE_STRING) {
+ code += "#if ENABLE_SPAN_T\n";
+ code += " public Span<" + GenTypeBasic(field.value.type.VectorType()) +
+ "> Get";
+ code += MakeCamel(field.name, true);
+ code += "Bytes() { return ";
+ code += "__p.__vector_as_span<" +
+ GenTypeBasic(field.value.type.VectorType()) + ">(";
+ code += NumToString(field.value.offset);
+ code +=
+ ", " + NumToString(SizeOf(field.value.type.VectorType().base_type));
+ code += "); }\n";
+ code += "#else\n";
+ code += " public ArraySegment<byte>? Get";
+ code += MakeCamel(field.name, true);
+ code += "Bytes() { return ";
+ code += "__p.__vector_as_arraysegment(";
+ code += NumToString(field.value.offset);
+ code += "); }\n";
+ code += "#endif\n";
+
+ // For direct blockcopying the data into a typed array
+ code += " public ";
+ code += GenTypeBasic(field.value.type.VectorType());
+ code += "[] Get";
+ code += MakeCamel(field.name, true);
+ 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 = __p.__offset(";
+ code += NumToString(field.value.offset);
+ code += "); if (o == 0) return null; int p = ";
+ code += "__p.__vector(o); int l = ";
+ code += "__p.__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 += "__p.__vector_as_array<";
+ code += GenTypeBasic(field.value.type.VectorType());
+ code += ">(";
+ code += NumToString(field.value.offset);
+ code += ");";
+ }
+ code += " }\n";
+ }
+ // generate object accessors if is nested_flatbuffer
+ if (field.nested_flatbuffer) {
+ auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
+ auto nested_method_name =
+ MakeCamel(field.name, true) + "As" + field.nested_flatbuffer->name;
+ auto get_nested_method_name = nested_method_name;
+ get_nested_method_name = "Get" + nested_method_name;
+ conditional_cast = "(" + nested_type_name + "?)";
+ obj = "(new " + nested_type_name + "())";
+ code += " public " + nested_type_name + "? ";
+ code += get_nested_method_name + "(";
+ code += ") { int o = __p.__offset(";
+ code += NumToString(field.value.offset) + "); ";
+ code += "return o != 0 ? " + conditional_cast + obj + ".__assign(";
+ code += "__p.";
+ code += "__indirect(__p.__vector(o)), ";
+ code += "__p.bb) : null; }\n";
+ }
+ // Generate mutators for scalar fields or vectors of scalars.
+ if (parser_.opts.mutable_buffer) {
+ auto is_series = (IsSeries(field.value.type));
+ const auto &underlying_type =
+ is_series ? field.value.type.VectorType() : field.value.type;
+ // Boolean parameters have to be explicitly converted to byte
+ // representation.
+ auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL
+ ? "(byte)(" + field.name + " ? 1 : 0)"
+ : field.name;
+ auto mutator_prefix = MakeCamel("mutate", true);
+ // A vector mutator also needs the index of the vector element it should
+ // mutate.
+ auto mutator_params = (is_series ? "(int j, " : "(") +
+ GenTypeGet(underlying_type) + " " + field.name +
+ ") { ";
+ auto setter_index =
+ is_series
+ ? "__p." +
+ (IsArray(field.value.type)
+ ? "bb_pos + " + NumToString(field.value.offset)
+ : "__vector(o)") +
+ +" + j * " + NumToString(InlineSize(underlying_type))
+ : (struct_def.fixed
+ ? "__p.bb_pos + " + NumToString(field.value.offset)
+ : "o + __p.bb_pos");
+ if (IsScalar(underlying_type.base_type) && !IsUnion(field.value.type)) {
+ code += " public ";
+ code += struct_def.fixed ? "void " : "bool ";
+ code += mutator_prefix + MakeCamel(field.name, true);
+ code += mutator_params;
+ if (struct_def.fixed) {
+ code += GenSetter(underlying_type) + "(" + setter_index + ", ";
+ code += src_cast + setter_parameter + "); }\n";
+ } else {
+ code += "int o = __p.__offset(";
+ code += NumToString(field.value.offset) + ");";
+ code += " if (o != 0) { " + GenSetter(underlying_type);
+ code += "(" + setter_index + ", " + src_cast + setter_parameter +
+ "); return true; } else { return false; } }\n";
+ }
+ }
+ }
+ if (parser_.opts.java_primitive_has_method &&
+ IsScalar(field.value.type.base_type) && !struct_def.fixed) {
+ auto vt_offset_constant = " public static final int VT_" +
+ MakeScreamingCamel(field.name) + " = " +
+ NumToString(field.value.offset) + ";";
+
+ code += vt_offset_constant;
+ code += "\n";
+ }
+ }
+ code += "\n";
+ auto struct_has_create = false;
+ std::set<flatbuffers::FieldDef *> field_has_create_set;
+ flatbuffers::FieldDef *key_field = nullptr;
+ if (struct_def.fixed) {
+ struct_has_create = true;
+ // create a struct constructor function
+ code += " public static " + GenOffsetType(struct_def) + " ";
+ code += "Create";
+ code += struct_def.name + "(FlatBufferBuilder builder";
+ GenStructArgs(struct_def, code_ptr, "");
+ code += ") {\n";
+ GenStructBody(struct_def, code_ptr, "");
+ code += " return ";
+ code += GenOffsetConstruct(struct_def, "builder.Offset");
+ code += ";\n }\n";
+ } else {
+ // Generate a method that creates a table in one go. This is only possible
+ // when the table has no struct fields, since those have to be created
+ // inline, and there's no way to do so in Java.
+ bool has_no_struct_fields = true;
+ int num_fields = 0;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (IsStruct(field.value.type)) {
+ has_no_struct_fields = false;
+ } else {
+ num_fields++;
+ }
+ }
+ // JVM specifications restrict default constructor params to be < 255.
+ // Longs and doubles take up 2 units, so we set the limit to be < 127.
+ if (has_no_struct_fields && num_fields && num_fields < 127) {
+ struct_has_create = true;
+ // Generate a table constructor of the form:
+ // public static int createName(FlatBufferBuilder builder, args...)
+ code += " public static " + GenOffsetType(struct_def) + " ";
+ code += "Create" + struct_def.name;
+ code += "(FlatBufferBuilder builder";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ code += ",\n ";
+ code += GenTypeBasic(field.value.type);
+ code += " ";
+ code += field.name;
+ if (!IsScalar(field.value.type.base_type)) code += "Offset";
+
+ code += " = ";
+ code += GenDefaultValueBasic(field);
+ }
+ code += ") {\n builder.";
+ code += "StartTable(";
+ code += NumToString(struct_def.fields.vec.size()) + ");\n";
+ for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1;
+ size; size /= 2) {
+ for (auto it = struct_def.fields.vec.rbegin();
+ it != struct_def.fields.vec.rend(); ++it) {
+ auto &field = **it;
+ if (!field.deprecated &&
+ (!struct_def.sortbysize ||
+ size == SizeOf(field.value.type.base_type))) {
+ code += " " + struct_def.name + ".";
+ code += "Add";
+ code += MakeCamel(field.name) + "(builder, " + field.name;
+ if (!IsScalar(field.value.type.base_type)) code += "Offset";
+ code += ");\n";
+ }
+ }
+ }
+ code += " return " + struct_def.name + ".";
+ code += "End" + struct_def.name;
+ code += "(builder);\n }\n\n";
+ }
+ // Generate a set of static methods that allow table construction,
+ // of the form:
+ // public static void addName(FlatBufferBuilder builder, short name)
+ // { builder.addShort(id, name, default); }
+ // Unlike the Create function, these always work.
+ code += " public static void Start";
+ code += struct_def.name;
+ code += "(FlatBufferBuilder builder) { builder.";
+ code += "StartTable(";
+ code += NumToString(struct_def.fields.vec.size()) + "); }\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (field.key) key_field = &field;
+ code += " public static void Add";
+ code += MakeCamel(field.name);
+ code += "(FlatBufferBuilder builder, ";
+ code += GenTypeBasic(field.value.type);
+ auto argname = MakeCamel(field.name, false);
+ if (!IsScalar(field.value.type.base_type)) argname += "Offset";
+ code += " " + argname + ") { builder.Add";
+ code += GenMethod(field.value.type) + "(";
+ code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
+ code += SourceCastBasic(field.value.type);
+ code += argname;
+ if (!IsScalar(field.value.type.base_type) &&
+ field.value.type.base_type != BASE_TYPE_UNION) {
+ code += ".Value";
+ }
+ code += ", ";
+ code += GenDefaultValue(field, false);
+ code += "); }\n";
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ auto vector_type = field.value.type.VectorType();
+ auto alignment = InlineAlignment(vector_type);
+ auto elem_size = InlineSize(vector_type);
+ if (!IsStruct(vector_type)) {
+ field_has_create_set.insert(&field);
+ code += " public static VectorOffset ";
+ code += "Create";
+ code += MakeCamel(field.name);
+ code += "Vector(FlatBufferBuilder builder, ";
+ code += GenTypeBasic(vector_type) + "[] data) ";
+ code += "{ builder.StartVector(";
+ code += NumToString(elem_size);
+ code += ", data.Length, ";
+ code += NumToString(alignment);
+ code += "); for (int i = data.";
+ code += "Length - 1; i >= 0; i--) builder.";
+ code += "Add";
+ code += GenMethod(vector_type);
+ code += "(";
+ code += SourceCastBasic(vector_type);
+ code += "data[i]";
+ if ((vector_type.base_type == BASE_TYPE_STRUCT ||
+ vector_type.base_type == BASE_TYPE_STRING))
+ code += ".Value";
+ code += "); return ";
+ code += "builder.EndVector(); }\n";
+
+ code += " public static VectorOffset ";
+ code += "Create";
+ code += MakeCamel(field.name);
+ code += "VectorBlock(FlatBufferBuilder builder, ";
+ code += GenTypeBasic(vector_type) + "[] data) ";
+ code += "{ builder.StartVector(";
+ code += NumToString(elem_size);
+ code += ", data.Length, ";
+ code += NumToString(alignment);
+ code += "); builder.Add(data); return builder.EndVector(); }\n";
+ }
+ // Generate a method to start a vector, data to be added manually
+ // after.
+ code += " public static void Start";
+ code += MakeCamel(field.name);
+ code += "Vector(FlatBufferBuilder builder, int numElems) ";
+ code += "{ builder.StartVector(";
+ code += NumToString(elem_size);
+ code += ", numElems, " + NumToString(alignment);
+ code += "); }\n";
+ }
+ }
+ code += " public static " + GenOffsetType(struct_def) + " ";
+ code += "End" + struct_def.name;
+ code += "(FlatBufferBuilder builder) {\n int o = builder.";
+ code += "EndTable();\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (!field.deprecated && field.required) {
+ code += " builder.Required(o, ";
+ code += NumToString(field.value.offset);
+ code += "); // " + field.name + "\n";
+ }
+ }
+ code += " return " + GenOffsetConstruct(struct_def, "o") + ";\n }\n";
+ if (parser_.root_struct_def_ == &struct_def) {
+ std::string size_prefix[] = { "", "SizePrefixed" };
+ for (int i = 0; i < 2; ++i) {
+ code += " public static void ";
+ code += "Finish" + size_prefix[i] + struct_def.name;
+ code +=
+ "Buffer(FlatBufferBuilder builder, " + GenOffsetType(struct_def);
+ code += " offset) {";
+ code += " builder.Finish" + size_prefix[i] + "(offset";
+ code += ".Value";
+
+ if (parser_.file_identifier_.length())
+ code += ", \"" + parser_.file_identifier_ + "\"";
+ code += "); }\n";
+ }
+ }
+ }
+ // Only generate key compare function for table,
+ // because `key_field` is not set for struct
+ if (struct_def.has_key && !struct_def.fixed) {
+ FLATBUFFERS_ASSERT(key_field);
+ code += "\n public static VectorOffset ";
+ code += "CreateSortedVectorOf" + struct_def.name;
+ code += "(FlatBufferBuilder builder, ";
+ code += "Offset<" + struct_def.name + ">";
+ code += "[] offsets) {\n";
+ code += " Array.Sort(offsets, (Offset<" + struct_def.name +
+ "> o1, Offset<" + struct_def.name + "> o2) => " +
+ GenKeyGetter(key_field);
+ code += ");\n";
+ code += " return builder.CreateVectorOfTables(offsets);\n }\n";
+
+ code += "\n public static " + struct_def.name + "?";
+ code += " __lookup_by_key(";
+ code += "int vectorLocation, ";
+ code += GenTypeGet(key_field->value.type);
+ code += " key, ByteBuffer bb) {\n";
+ if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+ code += " byte[] byteKey = ";
+ code += "System.Text.Encoding.UTF8.GetBytes(key);\n";
+ }
+ code += " int span = ";
+ code += "bb.GetInt(vectorLocation - 4);\n";
+ code += " int start = 0;\n";
+ code += " while (span != 0) {\n";
+ code += " int middle = span / 2;\n";
+ code += GenLookupKeyGetter(key_field);
+ code += " if (comp > 0) {\n";
+ code += " span = middle;\n";
+ code += " } else if (comp < 0) {\n";
+ code += " middle++;\n";
+ code += " start += middle;\n";
+ code += " span -= middle;\n";
+ code += " } else {\n";
+ code += " return ";
+ code += "new " + struct_def.name + "()";
+ code += ".__assign(tableOffset, bb);\n";
+ code += " }\n }\n";
+ code += " return null;\n";
+ code += " }\n";
+ }
+
+ if (opts.generate_object_based_api) {
+ GenPackUnPack_ObjectAPI(struct_def, code_ptr, opts, struct_has_create,
+ field_has_create_set);
+ }
+ code += "};\n\n";
+
+ if (opts.generate_object_based_api) {
+ GenStruct_ObjectAPI(struct_def, code_ptr, opts);
+ }
+ }
+
+ void GenVectorAccessObject(StructDef &struct_def,
+ std::string *code_ptr) const {
+ auto &code = *code_ptr;
+ // Generate a vector of structs accessor class.
+ code += "\n";
+ code += " ";
+ if (!struct_def.attributes.Lookup("private")) code += "public ";
+ code += "static struct Vector : BaseVector\n{\n";
+
+ // Generate the __assign method that sets the field in a pre-existing
+ // accessor object. This is to allow object reuse.
+ std::string method_indent = " ";
+ code += method_indent + "public Vector ";
+ code += "__assign(int _vector, int _element_size, ByteBuffer _bb) { ";
+ code += "__reset(_vector, _element_size, _bb); return this; }\n\n";
+
+ auto type_name = struct_def.name;
+ auto method_start = method_indent + "public " + type_name + " Get";
+ // Generate the accessors that don't do object reuse.
+ code += method_start + "(int j) { return Get";
+ code += "(new " + type_name + "(), j); }\n";
+ code += method_start + "(" + type_name + " obj, int j) { ";
+ code += " return obj.__assign(";
+ code += struct_def.fixed ? "__p.__element(j)"
+ : "__p.__indirect(__p.__element(j), bb)";
+ code += ", __p.bb); }\n";
+ // See if we should generate a by-key accessor.
+ if (!struct_def.fixed) {
+ auto &fields = struct_def.fields.vec;
+ for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+ auto &key_field = **kit;
+ if (key_field.key) {
+ auto nullable_annotation =
+ parser_.opts.gen_nullable ? "@Nullable " : "";
+ code += method_indent + nullable_annotation;
+ code += "public " + type_name + "? ";
+ code += "GetByKey(";
+ code += GenTypeGet(key_field.value.type) + " key) { ";
+ code += " return __lookup_by_key(null, ";
+ code += "__p.__vector(), key, ";
+ code += "__p.bb); ";
+ code += "}\n";
+ code += method_indent + nullable_annotation;
+ code += "public " + type_name + "?" + " ";
+ code += "GetByKey(";
+ code += type_name + "? obj, ";
+ code += GenTypeGet(key_field.value.type) + " key) { ";
+ code += " return __lookup_by_key(obj, ";
+ code += "__p.__vector(), key, ";
+ code += "__p.bb); ";
+ code += "}\n";
+ break;
+ }
+ }
+ }
+ code += " }\n";
+ }
+
+ void GenEnum_ObjectAPI(EnumDef &enum_def, std::string *code_ptr,
+ const IDLOptions &opts) const {
+ auto &code = *code_ptr;
+ if (enum_def.generated) return;
+ if (!enum_def.is_union) return;
+ if (enum_def.attributes.Lookup("private")) {
+ code += "internal ";
+ } else {
+ code += "public ";
+ }
+ auto union_name = enum_def.name + "Union";
+ code += "class " + union_name + " {\n";
+ // Type
+ code += " public " + enum_def.name + " Type { get; set; }\n";
+ // Value
+ code += " public object Value { get; set; }\n";
+ code += "\n";
+ // Constructor
+ code += " public " + union_name + "() {\n";
+ code += " this.Type = " + enum_def.name + "." +
+ enum_def.Vals()[0]->name + ";\n";
+ code += " this.Value = null;\n";
+ code += " }\n\n";
+ // As<T>
+ code += " public T As<T>() where T : class { return this.Value as T; }\n";
+ // As
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ auto &ev = **it;
+ if (ev.union_type.base_type == BASE_TYPE_NONE) continue;
+ auto type_name = GenTypeGet_ObjectAPI(ev.union_type, opts);
+ if (ev.union_type.base_type == BASE_TYPE_STRUCT &&
+ ev.union_type.struct_def->attributes.Lookup("private")) {
+ code += " internal ";
+ } else {
+ code += " public ";
+ }
+ code += type_name + " As" + ev.name + "() { return this.As<" + type_name +
+ ">(); }\n";
+ }
+ code += "\n";
+ // Pack()
+ code += " public static int Pack(FlatBuffers.FlatBufferBuilder builder, " +
+ union_name + " _o) {\n";
+ code += " switch (_o.Type) {\n";
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ auto &ev = **it;
+ if (ev.union_type.base_type == BASE_TYPE_NONE) {
+ code += " default: return 0;\n";
+ } else {
+ code += " case " + enum_def.name + "." + ev.name + ": return ";
+ if (ev.union_type.base_type == BASE_TYPE_STRING) {
+ code += "builder.CreateString(_o.As" + ev.name + "()).Value;\n";
+ } else {
+ code += GenTypeGet(ev.union_type) + ".Pack(builder, _o.As" + ev.name +
+ "()).Value;\n";
+ }
+ }
+ }
+ code += " }\n";
+ code += " }\n";
+ code += "}\n\n";
+ // JsonConverter
+ if (opts.cs_gen_json_serializer) {
+ if (enum_def.attributes.Lookup("private")) {
+ code += "internal ";
+ } else {
+ code += "public ";
+ }
+ code += "class " + union_name +
+ "_JsonConverter : Newtonsoft.Json.JsonConverter {\n";
+ code += " public override bool CanConvert(System.Type objectType) {\n";
+ code += " return objectType == typeof(" + union_name +
+ ") || objectType == typeof(System.Collections.Generic.List<" +
+ union_name + ">);\n";
+ code += " }\n";
+ code +=
+ " public override void WriteJson(Newtonsoft.Json.JsonWriter writer, "
+ "object value, "
+ "Newtonsoft.Json.JsonSerializer serializer) {\n";
+ code += " var _olist = value as System.Collections.Generic.List<" +
+ union_name + ">;\n";
+ code += " if (_olist != null) {\n";
+ code += " writer.WriteStartArray();\n";
+ code +=
+ " foreach (var _o in _olist) { this.WriteJson(writer, _o, "
+ "serializer); }\n";
+ code += " writer.WriteEndArray();\n";
+ code += " } else {\n";
+ code += " this.WriteJson(writer, value as " + union_name +
+ ", serializer);\n";
+ code += " }\n";
+ code += " }\n";
+ code += " public void WriteJson(Newtonsoft.Json.JsonWriter writer, " +
+ union_name +
+ " _o, "
+ "Newtonsoft.Json.JsonSerializer serializer) {\n";
+ code += " if (_o == null) return;\n";
+ code += " serializer.Serialize(writer, _o.Value);\n";
+ code += " }\n";
+ code +=
+ " public override object ReadJson(Newtonsoft.Json.JsonReader "
+ "reader, "
+ "System.Type objectType, "
+ "object existingValue, Newtonsoft.Json.JsonSerializer serializer) "
+ "{\n";
+ code +=
+ " var _olist = existingValue as System.Collections.Generic.List<" +
+ union_name + ">;\n";
+ code += " if (_olist != null) {\n";
+ code += " for (var _j = 0; _j < _olist.Count; ++_j) {\n";
+ code += " reader.Read();\n";
+ code +=
+ " _olist[_j] = this.ReadJson(reader, _olist[_j], "
+ "serializer);\n";
+ code += " }\n";
+ code += " reader.Read();\n";
+ code += " return _olist;\n";
+ code += " } else {\n";
+ code += " return this.ReadJson(reader, existingValue as " +
+ union_name + ", serializer);\n";
+ code += " }\n";
+ code += " }\n";
+ code += " public " + union_name +
+ " ReadJson(Newtonsoft.Json.JsonReader reader, " + union_name +
+ " _o, Newtonsoft.Json.JsonSerializer serializer) {\n";
+ code += " if (_o == null) return null;\n";
+ code += " switch (_o.Type) {\n";
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+ ++it) {
+ auto &ev = **it;
+ if (ev.union_type.base_type == BASE_TYPE_NONE) {
+ code += " default: break;\n";
+ } else {
+ auto type_name = GenTypeGet_ObjectAPI(ev.union_type, opts);
+ code += " case " + enum_def.name + "." + ev.name +
+ ": _o.Value = serializer.Deserialize<" + type_name +
+ ">(reader); break;\n";
+ }
+ }
+ code += " }\n";
+ code += " return _o;\n";
+ code += " }\n";
+ code += "}\n\n";
+ }
+ }
+
+ std::string GenTypeName_ObjectAPI(const std::string &name,
+ const IDLOptions &opts) const {
+ return opts.object_prefix + name + opts.object_suffix;
+ }
+
+ void GenUnionUnPack_ObjectAPI(const EnumDef &enum_def, std::string *code_ptr,
+ const std::string &camel_name,
+ bool is_vector) const {
+ auto &code = *code_ptr;
+ std::string varialbe_name = "_o." + camel_name;
+ std::string type_suffix = "";
+ std::string func_suffix = "()";
+ std::string indent = " ";
+ if (is_vector) {
+ varialbe_name = "_o_" + camel_name;
+ type_suffix = "(_j)";
+ func_suffix = "(_j)";
+ indent = " ";
+ }
+ if (is_vector) {
+ code += indent + "var " + varialbe_name + " = new ";
+ } else {
+ code += indent + varialbe_name + " = new ";
+ }
+ code += WrapInNameSpace(enum_def) + "Union();\n";
+ code += indent + varialbe_name + ".Type = this." + camel_name + "Type" +
+ type_suffix + ";\n";
+ code +=
+ indent + "switch (this." + camel_name + "Type" + type_suffix + ") {\n";
+ for (auto eit = enum_def.Vals().begin(); eit != enum_def.Vals().end();
+ ++eit) {
+ auto &ev = **eit;
+ if (ev.union_type.base_type == BASE_TYPE_NONE) {
+ code += indent + " default: break;\n";
+ } else {
+ code += indent + " case " + WrapInNameSpace(enum_def) + "." + ev.name +
+ ":\n";
+ code += indent + " " + varialbe_name + ".Value = this." + camel_name;
+ if (ev.union_type.base_type == BASE_TYPE_STRING) {
+ code += "AsString" + func_suffix + ";\n";
+ } else {
+ code += "<" + GenTypeGet(ev.union_type) + ">" + func_suffix;
+ code += ".HasValue ? this." + camel_name;
+ code += "<" + GenTypeGet(ev.union_type) + ">" + func_suffix +
+ ".Value.UnPack() : null;\n";
+ }
+ code += indent + " break;\n";
+ }
+ }
+ code += indent + "}\n";
+ if (is_vector) {
+ code += indent + "_o." + camel_name + ".Add(" + varialbe_name + ");\n";
+ }
+ }
+
+ void GenPackUnPack_ObjectAPI(
+ StructDef &struct_def, std::string *code_ptr, const IDLOptions &opts,
+ bool struct_has_create,
+ const std::set<FieldDef *> &field_has_create) const {
+ auto &code = *code_ptr;
+ auto struct_name = GenTypeName_ObjectAPI(struct_def.name, opts);
+ // UnPack()
+ code += " public " + struct_name + " UnPack() {\n";
+ code += " var _o = new " + struct_name + "();\n";
+ code += " this.UnPackTo(_o);\n";
+ code += " return _o;\n";
+ code += " }\n";
+ // UnPackTo()
+ code += " public void UnPackTo(" + struct_name + " _o) {\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ auto camel_name = MakeCamel(field.name);
+ auto start = " _o." + camel_name + " = ";
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT: {
+ auto fixed = struct_def.fixed && field.value.type.struct_def->fixed;
+ if (fixed) {
+ code += start + "this." + camel_name + ".UnPack();\n";
+ } else {
+ code += start + "this." + camel_name + ".HasValue ? this." +
+ camel_name + ".Value.UnPack() : null;\n";
+ }
+ break;
+ }
+ case BASE_TYPE_ARRAY: {
+ auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts);
+ auto length_str = NumToString(field.value.type.fixed_length);
+ auto unpack_method = field.value.type.struct_def == nullptr
+ ? ""
+ : field.value.type.struct_def->fixed
+ ? ".UnPack()"
+ : "?.UnPack()";
+ code += start + "new " + type_name.substr(0, type_name.length() - 1) +
+ length_str + "];\n";
+ code += " for (var _j = 0; _j < " + length_str + "; ++_j) { _o." +
+ camel_name + "[_j] = this." + camel_name + "(_j)" +
+ unpack_method + "; }\n";
+ break;
+ }
+ case BASE_TYPE_VECTOR:
+ if (field.value.type.element == BASE_TYPE_UNION) {
+ code += start + "new " +
+ GenTypeGet_ObjectAPI(field.value.type, opts) + "();\n";
+ code += " for (var _j = 0; _j < this." + camel_name +
+ "Length; ++_j) {\n";
+ GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code_ptr,
+ camel_name, true);
+ code += " }\n";
+ } else if (field.value.type.element != BASE_TYPE_UTYPE) {
+ auto fixed = field.value.type.struct_def == nullptr;
+ code += start + "new " +
+ GenTypeGet_ObjectAPI(field.value.type, opts) + "();\n";
+ code += " for (var _j = 0; _j < this." + camel_name +
+ "Length; ++_j) {";
+ code += "_o." + camel_name + ".Add(";
+ if (fixed) {
+ code += "this." + camel_name + "(_j)";
+ } else {
+ code += "this." + camel_name + "(_j).HasValue ? this." +
+ camel_name + "(_j).Value.UnPack() : null";
+ }
+ code += ");}\n";
+ }
+ break;
+ case BASE_TYPE_UTYPE: break;
+ case BASE_TYPE_UNION: {
+ GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code_ptr,
+ camel_name, false);
+ break;
+ }
+ default: {
+ code += start + "this." + camel_name + ";\n";
+ break;
+ }
+ }
+ }
+ code += " }\n";
+ // Pack()
+ code += " public static " + GenOffsetType(struct_def) +
+ " Pack(FlatBufferBuilder builder, " + struct_name + " _o) {\n";
+ code += " if (_o == null) return default(" + GenOffsetType(struct_def) +
+ ");\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ auto camel_name = MakeCamel(field.name);
+ // pre
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT: {
+ if (!field.value.type.struct_def->fixed) {
+ code += " var _" + field.name + " = _o." + camel_name +
+ " == null ? default(" +
+ GenOffsetType(*field.value.type.struct_def) +
+ ") : " + GenTypeGet(field.value.type) +
+ ".Pack(builder, _o." + camel_name + ");\n";
+ }
+ break;
+ }
+ case BASE_TYPE_STRING: {
+ std::string create_string =
+ field.shared ? "CreateSharedString" : "CreateString";
+ code += " var _" + field.name + " = _o." + camel_name +
+ " == null ? default(StringOffset) : "
+ "builder." +
+ create_string + "(_o." + camel_name + ");\n";
+ break;
+ }
+ case BASE_TYPE_VECTOR: {
+ if (field_has_create.find(&field) != field_has_create.end()) {
+ auto property_name = camel_name;
+ auto gen_for_loop = true;
+ std::string array_name = "__" + field.name;
+ std::string array_type = "";
+ std::string to_array = "";
+ switch (field.value.type.element) {
+ case BASE_TYPE_STRING: {
+ std::string create_string =
+ field.shared ? "CreateSharedString" : "CreateString";
+ array_type = "StringOffset";
+ to_array += "builder." + create_string + "(_o." +
+ property_name + "[_j])";
+ break;
+ }
+ case BASE_TYPE_STRUCT:
+ array_type = "Offset<" + GenTypeGet(field.value.type) + ">";
+ to_array = GenTypeGet(field.value.type) + ".Pack(builder, _o." +
+ property_name + "[_j])";
+ break;
+ case BASE_TYPE_UTYPE:
+ property_name = camel_name.substr(0, camel_name.size() - 4);
+ array_type = WrapInNameSpace(*field.value.type.enum_def);
+ to_array = "_o." + property_name + "[_j].Type";
+ break;
+ case BASE_TYPE_UNION:
+ array_type = "int";
+ to_array = WrapInNameSpace(*field.value.type.enum_def) +
+ "Union.Pack(builder, _o." + property_name + "[_j])";
+ break;
+ default: gen_for_loop = false; break;
+ }
+ code += " var _" + field.name + " = default(VectorOffset);\n";
+ code += " if (_o." + property_name + " != null) {\n";
+ if (gen_for_loop) {
+ code += " var " + array_name + " = new " + array_type +
+ "[_o." + property_name + ".Count];\n";
+ code += " for (var _j = 0; _j < " + array_name +
+ ".Length; ++_j) { ";
+ code += array_name + "[_j] = " + to_array + "; }\n";
+ } else {
+ code += " var " + array_name + " = _o." + property_name +
+ ".ToArray();\n";
+ }
+ code += " _" + field.name + " = Create" + camel_name +
+ "Vector(builder, " + array_name + ");\n";
+ code += " }\n";
+ } else {
+ auto pack_method =
+ field.value.type.struct_def == nullptr
+ ? "builder.Add" + GenMethod(field.value.type.VectorType()) +
+ "(_o." + camel_name + "[_j]);"
+ : GenTypeGet(field.value.type) + ".Pack(builder, _o." +
+ camel_name + "[_j]);";
+ code += " var _" + field.name + " = default(VectorOffset);\n";
+ code += " if (_o." + camel_name + " != null) {\n";
+ code += " Start" + camel_name + "Vector(builder, _o." +
+ camel_name + ".Count);\n";
+ code += " for (var _j = _o." + camel_name +
+ ".Count - 1; _j >= 0; --_j) { " + pack_method + " }\n";
+ code += " _" + field.name + " = builder.EndVector();\n";
+ code += " }\n";
+ }
+ break;
+ }
+ case BASE_TYPE_ARRAY: {
+ if (field.value.type.struct_def != nullptr) {
+ std::vector<std::string> name_vec;
+ name_vec.push_back(field.name);
+ std::vector<int> array_length_vec;
+ array_length_vec.push_back(field.value.type.fixed_length);
+ GenArrayPackDecl_ObjectAPI(*field.value.type.struct_def, code_ptr,
+ name_vec, array_length_vec);
+ } else {
+ code += " var _" + field.name + " = _o." + camel_name + ";\n";
+ }
+ break;
+ }
+ case BASE_TYPE_UNION: {
+ code += " var _" + field.name + "_type = _o." + camel_name +
+ " == null ? " + WrapInNameSpace(*field.value.type.enum_def) +
+ ".NONE : " + "_o." + camel_name + ".Type;\n";
+ code +=
+ " var _" + field.name + " = _o." + camel_name +
+ " == null ? 0 : " + GenTypeGet_ObjectAPI(field.value.type, opts) +
+ ".Pack(builder, _o." + camel_name + ");\n";
+ break;
+ }
+ default: break;
+ }
+ }
+ if (struct_has_create) {
+ // Create
+ code += " return Create" + struct_def.name + "(\n";
+ code += " builder";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ auto camel_name = MakeCamel(field.name);
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT: {
+ if (struct_def.fixed) {
+ GenStructArgs_ObjectAPI(*field.value.type.struct_def, code_ptr,
+ " _o." + camel_name + ".");
+ } else {
+ code += ",\n";
+ if (field.value.type.struct_def->fixed) {
+ code += " " + GenTypeGet(field.value.type) +
+ ".Pack(builder, _o." + camel_name + ")";
+ } else {
+ code += " _" + field.name;
+ }
+ }
+ break;
+ }
+ case BASE_TYPE_ARRAY: {
+ if (field.value.type.struct_def != nullptr) {
+ GenArrayPackCall_ObjectAPI(*field.value.type.struct_def, code_ptr,
+ " _" + field.name + "_");
+ } else {
+ code += ",\n";
+ code += " _" + field.name;
+ }
+ break;
+ }
+ case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_UTYPE: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_VECTOR: {
+ code += ",\n";
+ code += " _" + field.name;
+ break;
+ }
+ default: // scalar
+ code += ",\n";
+ code += " _o." + camel_name;
+ break;
+ }
+ }
+ code += ");\n";
+ } else {
+ // Start, End
+ code += " Start" + struct_def.name + "(builder);\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ auto camel_name = MakeCamel(field.name);
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT: {
+ if (field.value.type.struct_def->fixed) {
+ code += " Add" + camel_name + "(builder, " +
+ GenTypeGet(field.value.type) + ".Pack(builder, _o." +
+ camel_name + "));\n";
+ } else {
+ code +=
+ " Add" + camel_name + "(builder, _" + field.name + ");\n";
+ }
+ break;
+ }
+ case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_VECTOR: {
+ code +=
+ " Add" + camel_name + "(builder, _" + field.name + ");\n";
+ break;
+ }
+ case BASE_TYPE_UTYPE: break;
+ case BASE_TYPE_UNION: {
+ code += " Add" + camel_name + "Type(builder, _" + field.name +
+ "_type);\n";
+ code +=
+ " Add" + camel_name + "(builder, _" + field.name + ");\n";
+ break;
+ }
+ // scalar
+ default: {
+ code +=
+ " Add" + camel_name + "(builder, _o." + camel_name + ");\n";
+ break;
+ }
+ }
+ }
+ code += " return End" + struct_def.name + "(builder);\n";
+ }
+ code += " }\n";
+ }
+
+ void GenStructArgs_ObjectAPI(const StructDef &struct_def,
+ std::string *code_ptr,
+ std::string prefix) const {
+ auto &code = *code_ptr;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ const auto &field_type = field.value.type;
+ if (IsStruct(field_type)) {
+ GenStructArgs_ObjectAPI(*field_type.struct_def, code_ptr,
+ prefix + "." + MakeCamel(field.name) + ".");
+ } else {
+ code += ",\n";
+ code += prefix + MakeCamel(field.name);
+ }
+ }
+ }
+
+ void GenArrayPackDecl_ObjectAPI(const StructDef &struct_def,
+ std::string *code_ptr,
+ std::vector<std::string> name_vec,
+ std::vector<int> array_length_vec) const {
+ auto &code = *code_ptr;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ auto is_array = IsArray(field.value.type);
+ const auto &field_type =
+ is_array ? field.value.type.VectorType() : field.value.type;
+ if (!IsStruct(field_type)) {
+ auto tmp_name_vec = name_vec;
+ tmp_name_vec.push_back(field.name);
+ auto tmp_array_length_vec = array_length_vec;
+ if (is_array) {
+ tmp_array_length_vec.push_back(field_type.fixed_length);
+ }
+ std::string name;
+ for (size_t tmp_name_index = 0; tmp_name_index < tmp_name_vec.size();
+ ++tmp_name_index) {
+ name += "_" + tmp_name_vec[tmp_name_index];
+ }
+ code += " var " + name + " = new " + GenTypeBasic(field_type) + "[";
+ code += NumToString(tmp_array_length_vec[0]);
+ for (size_t i = 1; i < tmp_array_length_vec.size(); ++i) {
+ auto array_length = tmp_array_length_vec[i];
+ code += "," + NumToString(array_length);
+ }
+ code += "];\n";
+ code += " ";
+ // initialize array
+ for (size_t i = 0; i < tmp_array_length_vec.size(); ++i) {
+ auto array_length = tmp_array_length_vec[i];
+ auto idx = "idx" + NumToString(i);
+ code += "for (var " + idx + " = 0; " + idx + " < " +
+ NumToString(array_length) + "; ++" + idx + ") {";
+ }
+ code += name + "[idx0";
+ for (size_t i = 1; i < tmp_array_length_vec.size(); ++i) {
+ auto idx = "idx" + NumToString(i);
+ code += "," + idx;
+ }
+ code += "] = _o";
+ for (size_t i = 0; i < tmp_array_length_vec.size(); ++i) {
+ auto idx = "idx" + NumToString(i);
+ code += "." + MakeCamel(tmp_name_vec[i]) + "[" + idx + "]";
+ }
+ if (!is_array) { code += "." + MakeCamel(field.name); }
+ code += ";";
+ for (size_t i = 0; i < tmp_array_length_vec.size(); ++i) {
+ code += "}";
+ }
+ code += "\n";
+ }
+ }
+ }
+
+ void GenArrayPackCall_ObjectAPI(const StructDef &struct_def,
+ std::string *code_ptr,
+ std::string prefix) const {
+ auto &code = *code_ptr;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ const auto &field_type = field.value.type;
+ if (IsStruct(field_type)) {
+ GenArrayPackCall_ObjectAPI(*field_type.struct_def, code_ptr,
+ prefix + field.name + "_");
+ } else {
+ code += ",\n";
+ code += prefix + field.name;
+ }
+ }
+ }
+
+ std::string GenTypeGet_ObjectAPI(flatbuffers::Type type,
+ const IDLOptions &opts) const {
+ auto type_name = GenTypeGet(type);
+ // Replace to ObjectBaseAPI Type Name
+ switch (type.base_type) {
+ case BASE_TYPE_STRUCT: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_VECTOR: {
+ if (type.struct_def != nullptr) {
+ auto type_name_length = type.struct_def->name.length();
+ auto new_type_name =
+ GenTypeName_ObjectAPI(type.struct_def->name, opts);
+ type_name.replace(type_name.length() - type_name_length,
+ type_name_length, new_type_name);
+ } else if (type.element == BASE_TYPE_UNION) {
+ type_name = WrapInNameSpace(*type.enum_def) + "Union";
+ }
+ break;
+ }
+
+ case BASE_TYPE_UNION: {
+ type_name = WrapInNameSpace(*type.enum_def) + "Union";
+ break;
+ }
+ default: break;
+ }
+
+ switch (type.base_type) {
+ case BASE_TYPE_ARRAY: {
+ type_name = type_name + "[]";
+ break;
+ }
+ case BASE_TYPE_VECTOR: {
+ type_name = "List<" + type_name + ">";
+ break;
+ }
+ default: break;
+ }
+ return type_name;
+ }
+
+ void GenStruct_ObjectAPI(StructDef &struct_def, std::string *code_ptr,
+ const IDLOptions &opts) const {
+ auto &code = *code_ptr;
+ if (struct_def.attributes.Lookup("private")) {
+ code += "internal ";
+ } else {
+ code += "public ";
+ }
+ if (struct_def.attributes.Lookup("csharp_partial")) {
+ // generate a partial class for this C# struct/table
+ code += "partial ";
+ }
+ auto class_name = GenTypeName_ObjectAPI(struct_def.name, opts);
+ code += "class " + class_name;
+ code += "\n{\n";
+ // Generate Properties
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
+ if (field.value.type.element == BASE_TYPE_UTYPE) continue;
+ auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts);
+ auto camel_name = MakeCamel(field.name, true);
+ if (opts.cs_gen_json_serializer) {
+ if (IsUnion(field.value.type)) {
+ auto utype_name = WrapInNameSpace(*field.value.type.enum_def);
+ code +=
+ " [Newtonsoft.Json.JsonProperty(\"" + field.name + "_type\")]\n";
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ code += " private " + utype_name + "[] " + camel_name + "Type {\n";
+ code += " get {\n";
+ code += " if (this." + camel_name + " == null) return null;\n";
+ code += " var _o = new " + utype_name + "[this." + camel_name +
+ ".Count];\n";
+ code +=
+ " for (var _j = 0; _j < _o.Length; ++_j) { _o[_j] = "
+ "this." +
+ camel_name + "[_j].Type; }\n";
+ code += " return _o;\n";
+ code += " }\n";
+ code += " set {\n";
+ code += " this." + camel_name + " = new List<" + utype_name +
+ "Union>();\n";
+ code += " for (var _j = 0; _j < value.Length; ++_j) {\n";
+ code += " var _o = new " + utype_name + "Union();\n";
+ code += " _o.Type = value[_j];\n";
+ code += " this." + camel_name + ".Add(_o);\n";
+ code += " }\n";
+ code += " }\n";
+ code += " }\n";
+ } else {
+ code += " private " + utype_name + " " + camel_name + "Type {\n";
+ code += " get {\n";
+ code += " return this." + camel_name + " != null ? this." +
+ camel_name + ".Type : " + utype_name + ".NONE;\n";
+ code += " }\n";
+ code += " set {\n";
+ code += " this." + camel_name + " = new " + utype_name +
+ "Union();\n";
+ code += " this." + camel_name + ".Type = value;\n";
+ code += " }\n";
+ code += " }\n";
+ }
+ }
+ code += " [Newtonsoft.Json.JsonProperty(\"" + field.name + "\")]\n";
+ if (IsUnion(field.value.type)) {
+ auto union_name =
+ (field.value.type.base_type == BASE_TYPE_VECTOR)
+ ? GenTypeGet_ObjectAPI(field.value.type.VectorType(), opts)
+ : type_name;
+ code += " [Newtonsoft.Json.JsonConverter(typeof(" + union_name +
+ "_JsonConverter))]\n";
+ }
+ if (field.attributes.Lookup("hash")) {
+ code += " [Newtonsoft.Json.JsonIgnore()]\n";
+ }
+ }
+ code += " public " + type_name + " " + camel_name + " { get; set; }\n";
+ }
+ // Generate Constructor
+ code += "\n";
+ code += " public " + class_name + "() {\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
+ if (field.value.type.element == BASE_TYPE_UTYPE) continue;
+ code += " this." + MakeCamel(field.name) + " = ";
+ auto type_name = GenTypeGet_ObjectAPI(field.value.type, opts);
+ if (IsScalar(field.value.type.base_type)) {
+ code += GenDefaultValue(field) + ";\n";
+ } else {
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT: {
+ if (IsStruct(field.value.type)) {
+ code += "new " + type_name + "();\n";
+ } else {
+ code += "null;\n";
+ }
+ break;
+ }
+ case BASE_TYPE_ARRAY: {
+ code += "new " + type_name.substr(0, type_name.length() - 1) +
+ NumToString(field.value.type.fixed_length) + "];\n";
+ break;
+ }
+ default: {
+ code += "null;\n";
+ break;
+ }
+ }
+ }
+ }
+ code += " }\n";
+ // Generate Serialization
+ if (opts.cs_gen_json_serializer &&
+ parser_.root_struct_def_ == &struct_def) {
+ code += "\n";
+ code += " public static " + class_name +
+ " DeserializeFromJson(string jsonText) {\n";
+ code += " return Newtonsoft.Json.JsonConvert.DeserializeObject<" +
+ class_name + ">(jsonText);\n";
+ code += " }\n";
+ code += " public string SerializeToJson() {\n";
+ code +=
+ " return Newtonsoft.Json.JsonConvert.SerializeObject(this, "
+ "Newtonsoft.Json.Formatting.Indented);\n";
+ code += " }\n";
+ }
+ if (parser_.root_struct_def_ == &struct_def) {
+ code += " public static " + class_name +
+ " DeserializeFromBinary(byte[] fbBuffer) {\n";
+ code += " return " + struct_def.name + ".GetRootAs" + struct_def.name +
+ "(new ByteBuffer(fbBuffer)).UnPack();\n";
+ code += " }\n";
+ code += " public byte[] SerializeToBinary() {\n";
+ code += " var fbb = new FlatBufferBuilder(0x10000);\n";
+ code +=
+ " fbb.Finish(" + struct_def.name + ".Pack(fbb, this).Value);\n";
+ code += " return fbb.DataBuffer.ToSizedArray();\n";
+ code += " }\n";
+ }
+ code += "}\n\n";
+ }
+
+ // This tracks the current namespace used to determine if a type need to be
+ // prefixed by its namespace
+ const Namespace *cur_name_space_;
+};
+} // namespace csharp
+
+bool GenerateCSharp(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ csharp::CSharpGenerator generator(parser, path, file_name);
+ return generator.generate();
+}
+
+} // namespace flatbuffers
diff --git a/src/idl_gen_dart.cpp b/src/idl_gen_dart.cpp
index 2141eb38..c2b1e42d 100644
--- a/src/idl_gen_dart.cpp
+++ b/src/idl_gen_dart.cpp
@@ -24,11 +24,6 @@
namespace flatbuffers {
-static std::string GeneratedFileName(const std::string &path,
- const std::string &file_name) {
- return path + file_name + "_generated.dart";
-}
-
namespace dart {
const std::string _kFb = "fb";
@@ -55,7 +50,7 @@ class DartGenerator : public BaseGenerator {
DartGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "", ".") {}
+ : BaseGenerator(parser, path, file_name, "", ".", "dart") {}
// Iterate through all definitions we haven't generate code for (enums,
// structs, and tables) and output them to a single file.
bool generate() {
@@ -71,7 +66,7 @@ class DartGenerator : public BaseGenerator {
"// ignore_for_file: unused_import, unused_field, "
"unused_local_variable\n\n";
- code += "library " + kv->first + ";\n\n";
+ if (!kv->first.empty()) { code += "library " + kv->first + ";\n\n"; }
code += "import 'dart:typed_data' show Uint8List;\n";
code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb +
@@ -84,16 +79,24 @@ class DartGenerator : public BaseGenerator {
for (auto kv2 = namespace_code.begin(); kv2 != namespace_code.end();
++kv2) {
if (kv2->first != kv->first) {
- code += "import '" +
- GeneratedFileName("./", file_name_ + "_" + kv2->first) +
- "' as " + ImportAliasName(kv2->first) + ";\n";
+ code +=
+ "import '" +
+ GeneratedFileName(
+ "./",
+ file_name_ + (!kv2->first.empty() ? "_" + kv2->first : ""),
+ parser_.opts) +
+ "' as " + ImportAliasName(kv2->first) + ";\n";
}
}
code += "\n";
code += kv->second;
if (!SaveFile(
- GeneratedFileName(path_, file_name_ + "_" + kv->first).c_str(),
+ GeneratedFileName(
+ path_,
+ file_name_ + (!kv->first.empty() ? "_" + kv->first : ""),
+ parser_.opts)
+ .c_str(),
code, false)) {
return false;
}
@@ -105,22 +108,23 @@ class DartGenerator : public BaseGenerator {
static std::string ImportAliasName(const std::string &ns) {
std::string ret;
ret.assign(ns);
- size_t pos = ret.find(".");
+ size_t pos = ret.find('.');
while (pos != std::string::npos) {
ret.replace(pos, 1, "_");
- pos = ret.find(".", pos + 1);
+ pos = ret.find('.', pos + 1);
}
return ret;
}
static std::string BuildNamespaceName(const Namespace &ns) {
+ if (ns.components.empty()) { return ""; }
std::stringstream sstream;
std::copy(ns.components.begin(), ns.components.end() - 1,
std::ostream_iterator<std::string>(sstream, "."));
auto ret = sstream.str() + ns.components.back();
- for (int i = 0; ret[i]; i++) {
+ for (size_t i = 0; i < ret.size(); i++) {
auto lower = tolower(ret[i]);
if (lower != ret[i]) {
ret[i] = static_cast<char>(lower);
@@ -134,7 +138,8 @@ class DartGenerator : public BaseGenerator {
return ret;
}
- void GenIncludeDependencies(std::string* code, const std::string& the_namespace) {
+ void GenIncludeDependencies(std::string *code,
+ const std::string &the_namespace) {
for (auto it = parser_.included_files_.begin();
it != parser_.included_files_.end(); ++it) {
if (it->second.empty()) continue;
@@ -142,7 +147,12 @@ class DartGenerator : public BaseGenerator {
auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext);
- *code += "import '" + GeneratedFileName("", basename + "_" + the_namespace) + "';\n";
+ *code +=
+ "import '" +
+ GeneratedFileName(
+ "", basename + (the_namespace == "" ? "" : "_" + the_namespace),
+ parser_.opts) +
+ "';\n";
}
}
@@ -181,7 +191,6 @@ class DartGenerator : public BaseGenerator {
}
auto &code = *code_ptr;
- if (indent) code += indent;
for (auto it = dc.begin(); it != dc.end(); ++it) {
if (indent) code += indent;
@@ -242,9 +251,9 @@ class DartGenerator : public BaseGenerator {
// holes.
if (!is_bit_flags) {
code += " static const int minValue = " +
- NumToString(enum_def.vals.vec.front()->value) + ";\n";
+ enum_def.ToString(*enum_def.MinValue()) + ";\n";
code += " static const int maxValue = " +
- NumToString(enum_def.vals.vec.back()->value) + ";\n";
+ enum_def.ToString(*enum_def.MaxValue()) + ";\n";
}
code +=
@@ -259,13 +268,13 @@ class DartGenerator : public BaseGenerator {
GenDocComment(ev.doc_comment, &code, "", " ");
}
code += " static const " + name + " " + ev.name + " = ";
- code += "const " + name + "._(" + NumToString(ev.value) + ");\n";
+ code += "const " + name + "._(" + enum_def.ToString(ev) + ");\n";
}
code += " static get values => {";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
auto &ev = **it;
- code += NumToString(ev.value) + ": " + ev.name + ",";
+ code += enum_def.ToString(ev) + ": " + ev.name + ",";
}
code += "};\n\n";
@@ -410,23 +419,23 @@ class DartGenerator : public BaseGenerator {
auto object_namespace = BuildNamespaceName(*struct_def.defined_namespace);
std::string code;
- auto object_name = struct_def.name;
+ const auto &object_name = struct_def.name;
// Emit constructor
GenDocComment(struct_def.doc_comment, &code, "");
- auto reader_name = "_" + struct_def.name + "Reader";
- auto builder_name = struct_def.name + "Builder";
- auto object_builder_name = struct_def.name + "ObjectBuilder";
+ auto reader_name = "_" + object_name + "Reader";
+ auto builder_name = object_name + "Builder";
+ auto object_builder_name = object_name + "ObjectBuilder";
std::string reader_code, builder_code;
- code += "class " + struct_def.name + " {\n";
+ code += "class " + object_name + " {\n";
- code += " " + struct_def.name + "._(this._bc, this._bcOffset);\n";
+ code += " " + object_name + "._(this._bc, this._bcOffset);\n";
if (!struct_def.fixed) {
- code += " factory " + struct_def.name + "(List<int> bytes) {\n";
+ code += " factory " + object_name + "(List<int> bytes) {\n";
code += " " + _kFb + ".BufferContext rootRef = new " + _kFb +
".BufferContext.fromBytes(bytes);\n";
code += " return reader.read(rootRef, 0);\n";
@@ -434,19 +443,29 @@ class DartGenerator : public BaseGenerator {
}
code += "\n";
- code += " static const " + _kFb + ".Reader<" + struct_def.name +
+ code += " static const " + _kFb + ".Reader<" + object_name +
"> reader = const " + reader_name + "();\n\n";
code += " final " + _kFb + ".BufferContext _bc;\n";
code += " final int _bcOffset;\n\n";
- GenImplementationGetters(struct_def, &code);
+ std::vector<std::pair<int, FieldDef *>> non_deprecated_fields;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ auto offset = static_cast<int>(it - struct_def.fields.vec.begin());
+ non_deprecated_fields.push_back(std::make_pair(offset, &field));
+ }
+
+ GenImplementationGetters(struct_def, non_deprecated_fields, &code);
code += "}\n\n";
GenReader(struct_def, &reader_name, &reader_code);
- GenBuilder(struct_def, &builder_name, &builder_code);
- GenObjectBuilder(struct_def, &object_builder_name, &builder_code);
+ GenBuilder(struct_def, non_deprecated_fields, &builder_name, &builder_code);
+ GenObjectBuilder(struct_def, non_deprecated_fields, &object_builder_name,
+ &builder_code);
code += reader_code;
code += builder_code;
@@ -455,7 +474,7 @@ class DartGenerator : public BaseGenerator {
}
std::string NamespaceAliasFromUnionType(const std::string &in) {
- if (in.find("_") == std::string::npos) { return in; }
+ if (in.find('_') == std::string::npos) { return in; }
std::stringstream ss(in);
std::string item;
@@ -482,20 +501,22 @@ class DartGenerator : public BaseGenerator {
return ns + "." + parts.back();
}
- void GenImplementationGetters(const StructDef &struct_def,
- std::string *code_ptr) {
+ void GenImplementationGetters(
+ const StructDef &struct_def,
+ std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
+ std::string *code_ptr) {
auto &code = *code_ptr;
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
std::string field_name = MakeCamel(field.name, false);
std::string type_name = GenDartTypeName(
field.value.type, struct_def.defined_namespace, field, false);
- GenDocComment(field.doc_comment, &code, "");
+ GenDocComment(field.doc_comment, &code, "", " ");
code += " " + type_name + " get " + field_name;
if (field.value.type.base_type == BASE_TYPE_UNION) {
@@ -507,7 +528,7 @@ class DartGenerator : public BaseGenerator {
auto &ev = **en_it;
auto enum_name = NamespaceAliasFromUnionType(ev.name);
- code += " case " + NumToString(ev.value) + ": return " +
+ code += " case " + enum_def.ToString(ev) + ": return " +
enum_name + ".reader.vTableGet(_bc, _bcOffset, " +
NumToString(field.value.offset) + ", null);\n";
}
@@ -535,6 +556,15 @@ class DartGenerator : public BaseGenerator {
if (!field.value.constant.empty() && field.value.constant != "0") {
if (IsBool(field.value.type.base_type)) {
code += "true";
+ } else if (field.value.constant == "nan" ||
+ field.value.constant == "+nan" ||
+ field.value.constant == "-nan") {
+ code += "double.nan";
+ } else if (field.value.constant == "inf" ||
+ field.value.constant == "+inf") {
+ code += "double.infinity";
+ } else if (field.value.constant == "-inf") {
+ code += "double.negativeInfinity";
} else {
code += field.value.constant;
}
@@ -562,13 +592,13 @@ class DartGenerator : public BaseGenerator {
code += " @override\n";
code += " String toString() {\n";
code += " return '" + struct_def.name + "{";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
code +=
MakeCamel(field.name, false) + ": $" + MakeCamel(field.name, false);
- if (it != struct_def.fields.vec.end() - 1) { code += ", "; }
+ if (it != non_deprecated_fields.end() - 1) { code += ", "; }
}
code += "}';\n";
code += " }\n";
@@ -600,9 +630,10 @@ class DartGenerator : public BaseGenerator {
code += "}\n\n";
}
- void GenBuilder(const StructDef &struct_def, std::string *builder_name_ptr,
- std::string *code_ptr) {
- if (struct_def.fields.vec.size() == 0) { return; }
+ void GenBuilder(const StructDef &struct_def,
+ std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
+ std::string *builder_name_ptr, std::string *code_ptr) {
+ if (non_deprecated_fields.size() == 0) { return; }
auto &code = *code_ptr;
auto &builder_name = *builder_name_ptr;
@@ -613,22 +644,25 @@ class DartGenerator : public BaseGenerator {
code += " final " + _kFb + ".Builder fbBuilder;\n\n";
if (struct_def.fixed) {
- StructBuilderBody(struct_def, code_ptr);
+ StructBuilderBody(struct_def, non_deprecated_fields, code_ptr);
} else {
- TableBuilderBody(struct_def, code_ptr);
+ TableBuilderBody(struct_def, non_deprecated_fields, code_ptr);
}
code += "}\n\n";
}
- void StructBuilderBody(const StructDef &struct_def, std::string *code_ptr) {
+ void StructBuilderBody(
+ const StructDef &struct_def,
+ std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
+ std::string *code_ptr) {
auto &code = *code_ptr;
code += " int finish(";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
if (IsStruct(field.value.type)) {
code += "fb.StructBuilder";
@@ -637,15 +671,14 @@ class DartGenerator : public BaseGenerator {
field);
}
code += " " + field.name;
- if (it != struct_def.fields.vec.end() - 1) { code += ", "; }
+ if (it != non_deprecated_fields.end() - 1) { code += ", "; }
}
code += ") {\n";
- for (auto it = struct_def.fields.vec.rbegin();
- it != struct_def.fields.vec.rend(); ++it) {
- auto &field = **it;
-
- if (field.deprecated) continue;
+ for (auto it = non_deprecated_fields.rbegin();
+ it != non_deprecated_fields.rend(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
if (field.padding) {
code += " fbBuilder.pad(" + NumToString(field.padding) + ");\n";
@@ -664,19 +697,21 @@ class DartGenerator : public BaseGenerator {
code += " }\n\n";
}
- void TableBuilderBody(const StructDef &struct_def, std::string *code_ptr) {
+ void TableBuilderBody(
+ const StructDef &struct_def,
+ std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
+ std::string *code_ptr) {
auto &code = *code_ptr;
code += " void begin() {\n";
code += " fbBuilder.startTable();\n";
code += " }\n\n";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
-
- auto offset = it - struct_def.fields.vec.begin();
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
+ auto offset = pair.first;
if (IsScalar(field.value.type.base_type)) {
code += " int add" + MakeCamel(field.name) + "(";
@@ -707,16 +742,19 @@ class DartGenerator : public BaseGenerator {
code += " }\n";
}
- void GenObjectBuilder(const StructDef &struct_def,
- std::string *builder_name_ptr, std::string *code_ptr) {
+ void GenObjectBuilder(
+ const StructDef &struct_def,
+ std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
+ std::string *builder_name_ptr, std::string *code_ptr) {
auto &code = *code_ptr;
auto &builder_name = *builder_name_ptr;
code += "class " + builder_name + " extends " + _kFb + ".ObjectBuilder {\n";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
+
code += " final " +
GenDartTypeName(field.value.type, struct_def.defined_namespace,
field, true) +
@@ -724,14 +762,14 @@ class DartGenerator : public BaseGenerator {
}
code += "\n";
code += " " + builder_name + "(";
- if (struct_def.fields.vec.size() != 0) {
- code +=
- "{\n";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ if (non_deprecated_fields.size() != 0) {
+ code += "{\n";
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
+
code += " " +
GenDartTypeName(field.value.type, struct_def.defined_namespace,
field, true) +
@@ -739,13 +777,14 @@ class DartGenerator : public BaseGenerator {
}
code += " })\n";
code += " : ";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
+
code += "_" + MakeCamel(field.name, false) + " = " +
MakeCamel(field.name, false);
- if (it == struct_def.fields.vec.end() - 1) {
+ if (it == non_deprecated_fields.end() - 1) {
code += ";\n\n";
} else {
code += ",\n ";
@@ -761,10 +800,11 @@ class DartGenerator : public BaseGenerator {
code += " " + _kFb + ".Builder fbBuilder) {\n";
code += " assert(fbBuilder != null);\n";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
+
if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type))
continue;
@@ -794,7 +834,8 @@ class DartGenerator : public BaseGenerator {
}
code += "\n : null;\n";
} else if (field.value.type.base_type == BASE_TYPE_STRING) {
- code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) + ");\n";
+ code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) +
+ ");\n";
} else {
code += " = _" + MakeCamel(field.name, false) +
"?.getOrCreateOffset(fbBuilder);\n";
@@ -803,9 +844,9 @@ class DartGenerator : public BaseGenerator {
code += "\n";
if (struct_def.fixed) {
- StructObjectBuilderBody(struct_def, code_ptr);
+ StructObjectBuilderBody(non_deprecated_fields, code_ptr);
} else {
- TableObjectBuilderBody(struct_def, code_ptr);
+ TableObjectBuilderBody(non_deprecated_fields, code_ptr);
}
code += " }\n\n";
@@ -820,16 +861,15 @@ class DartGenerator : public BaseGenerator {
code += "}\n";
}
- void StructObjectBuilderBody(const StructDef &struct_def,
- std::string *code_ptr,
- bool prependUnderscore = true) {
+ void StructObjectBuilderBody(
+ std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
+ std::string *code_ptr, bool prependUnderscore = true) {
auto &code = *code_ptr;
- for (auto it = struct_def.fields.vec.rbegin();
- it != struct_def.fields.vec.rend(); ++it) {
- auto &field = **it;
-
- if (field.deprecated) continue;
+ for (auto it = non_deprecated_fields.rbegin();
+ it != non_deprecated_fields.rend(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
if (field.padding) {
code += " fbBuilder.pad(" + NumToString(field.padding) + ");\n";
@@ -851,19 +891,18 @@ class DartGenerator : public BaseGenerator {
code += " return fbBuilder.offset;\n";
}
- void TableObjectBuilderBody(const StructDef &struct_def,
- std::string *code_ptr,
- bool prependUnderscore = true) {
+ void TableObjectBuilderBody(
+ std::vector<std::pair<int, FieldDef *>> non_deprecated_fields,
+ std::string *code_ptr, bool prependUnderscore = true) {
std::string &code = *code_ptr;
code += " fbBuilder.startTable();\n";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
+ for (auto it = non_deprecated_fields.begin();
+ it != non_deprecated_fields.end(); ++it) {
+ auto pair = *it;
+ auto &field = *pair.second;
+ auto offset = pair.first;
- if (field.deprecated) continue;
-
- auto offset = it - struct_def.fields.vec.begin();
if (IsScalar(field.value.type.base_type)) {
code += " fbBuilder.add" + GenType(field.value.type) + "(" +
NumToString(offset) + ", ";
@@ -903,7 +942,9 @@ std::string DartMakeRule(const Parser &parser, const std::string &path,
auto filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
- auto make_rule = GeneratedFileName(path, filebase) + ": ";
+ dart::DartGenerator generator(parser, path, file_name);
+ auto make_rule =
+ generator.GeneratedFileName(path, file_name, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) {
diff --git a/src/idl_gen_fbs.cpp b/src/idl_gen_fbs.cpp
index 5a85a955..e6c8a4a8 100644
--- a/src/idl_gen_fbs.cpp
+++ b/src/idl_gen_fbs.cpp
@@ -63,25 +63,35 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
for (size_t i = 0; i < ns.from_table; i++) {
ns.components[ns.components.size() - 1 - i] += "_";
}
+
+ if (parser.opts.proto_mode && !parser.opts.proto_namespace_suffix.empty()) {
+ // Since we know that all these namespaces come from a .proto, and all are
+ // being converted, we can simply apply this suffix to all of them.
+ ns.components.insert(ns.components.end() - ns.from_table,
+ parser.opts.proto_namespace_suffix);
+ }
}
std::string schema;
schema += "// Generated from " + file_name + ".proto\n\n";
if (parser.opts.include_dependence_headers) {
// clang-format off
- #ifdef FBS_GEN_INCLUDES // TODO: currently all in one file.
int num_includes = 0;
for (auto it = parser.included_files_.begin();
it != parser.included_files_.end(); ++it) {
if (it->second.empty())
continue;
- auto basename = flatbuffers::StripPath(
- flatbuffers::StripExtension(it->second));
+ std::string basename;
+ if(parser.opts.keep_include_path) {
+ basename = flatbuffers::StripExtension(it->second);
+ } else {
+ basename = flatbuffers::StripPath(
+ flatbuffers::StripExtension(it->second));
+ }
schema += "include \"" + basename + ".fbs\";\n";
num_includes++;
}
if (num_includes) schema += "\n";
- #endif
// clang-format on
}
// Generate code for all the enum declarations.
@@ -89,6 +99,9 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
for (auto enum_def_it = parser.enums_.vec.begin();
enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
EnumDef &enum_def = **enum_def_it;
+ if (parser.opts.include_dependence_headers && enum_def.generated) {
+ continue;
+ }
GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
GenComment(enum_def.doc_comment, &schema, nullptr);
if (enum_def.is_union)
@@ -102,7 +115,7 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
if (enum_def.is_union)
schema += " " + GenType(ev.union_type) + ",\n";
else
- schema += " " + ev.name + " = " + NumToString(ev.value) + ",\n";
+ schema += " " + ev.name + " = " + enum_def.ToString(ev) + ",\n";
}
schema += "}\n\n";
}
@@ -110,6 +123,9 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
++it) {
StructDef &struct_def = **it;
+ if (parser.opts.include_dependence_headers && struct_def.generated) {
+ continue;
+ }
GenNameSpace(*struct_def.defined_namespace, &schema, &last_namespace);
GenComment(struct_def.doc_comment, &schema, nullptr);
schema += "table " + struct_def.name + " {\n";
diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp
deleted file mode 100644
index fe793bf3..00000000
--- a/src/idl_gen_general.cpp
+++ /dev/null
@@ -1,1592 +0,0 @@
-/*
- * Copyright 2014 Google Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// independent from idl_parser, since this code is not needed for most clients
-
-#include "flatbuffers/code_generators.h"
-#include "flatbuffers/flatbuffers.h"
-#include "flatbuffers/idl.h"
-#include "flatbuffers/util.h"
-
-#if defined(FLATBUFFERS_CPP98_STL)
-# include <cctype>
-#endif // defined(FLATBUFFERS_CPP98_STL)
-
-namespace flatbuffers {
-
-// These arrays need to correspond to the IDLOptions::k enum.
-
-struct LanguageParameters {
- IDLOptions::Language language;
- // Whether function names in the language typically start with uppercase.
- bool first_camel_upper;
- std::string file_extension;
- std::string string_type;
- std::string bool_type;
- std::string open_curly;
- std::string accessor_type;
- std::string const_decl;
- std::string unsubclassable_decl;
- std::string enum_decl;
- std::string enum_separator;
- std::string getter_prefix;
- std::string getter_suffix;
- std::string inheritance_marker;
- std::string namespace_ident;
- std::string namespace_begin;
- std::string namespace_end;
- std::string set_bb_byteorder;
- std::string get_bb_position;
- std::string get_fbb_offset;
- std::string accessor_prefix;
- std::string accessor_prefix_static;
- std::string optional_suffix;
- std::string includes;
- std::string class_annotation;
- std::string generated_type_annotation;
- CommentConfig comment_config;
- const FloatConstantGenerator *float_gen;
-};
-
-const LanguageParameters &GetLangParams(IDLOptions::Language lang) {
- static TypedFloatConstantGenerator CSharpFloatGen(
- "Double.", "Single.", "NaN", "PositiveInfinity", "NegativeInfinity");
-
- static TypedFloatConstantGenerator JavaFloatGen(
- "Double.", "Float.", "NaN", "POSITIVE_INFINITY", "NEGATIVE_INFINITY");
-
- static const LanguageParameters language_parameters[] = {
- {
- IDLOptions::kJava,
- false,
- ".java",
- "String",
- "boolean ",
- " {\n",
- "class ",
- " final ",
- "final ",
- "final class ",
- ";\n",
- "()",
- "",
- " extends ",
- "package ",
- ";",
- "",
- "_bb.order(ByteOrder.LITTLE_ENDIAN); ",
- "position()",
- "offset()",
- "",
- "",
- "",
- "import java.nio.*;\nimport java.lang.*;\nimport "
- "java.util.*;\nimport com.google.flatbuffers.*;\n",
- "\n@SuppressWarnings(\"unused\")\n",
- "\n@javax.annotation.Generated(value=\"flatc\")\n",
- {
- "/**",
- " *",
- " */",
- },
- &JavaFloatGen
- },
- {
- IDLOptions::kCSharp,
- true,
- ".cs",
- "string",
- "bool ",
- "\n{\n",
- "struct ",
- " readonly ",
- "",
- "enum ",
- ",\n",
- " { get",
- "} ",
- " : ",
- "namespace ",
- "\n{",
- "\n}\n",
- "",
- "Position",
- "Offset",
- "__p.",
- "Table.",
- "?",
- "using global::System;\nusing global::FlatBuffers;\n\n",
- "",
- "",
- {
- nullptr,
- "///",
- nullptr,
- },
- &CSharpFloatGen
- },
- };
-
- if (lang == IDLOptions::kJava) {
- return language_parameters[0];
- } else {
- FLATBUFFERS_ASSERT(lang == IDLOptions::kCSharp);
- return language_parameters[1];
- }
-}
-
-namespace general {
-class GeneralGenerator : public BaseGenerator {
- public:
- GeneralGenerator(const Parser &parser, const std::string &path,
- const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "", "."),
- lang_(GetLangParams(parser_.opts.lang)),
- cur_name_space_(nullptr) {}
-
- GeneralGenerator &operator=(const GeneralGenerator &);
- bool generate() {
- std::string one_file_code;
- cur_name_space_ = parser_.current_namespace_;
-
- for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
- ++it) {
- std::string enumcode;
- auto &enum_def = **it;
- if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
- GenEnum(enum_def, &enumcode);
- if (parser_.opts.one_file) {
- one_file_code += enumcode;
- } else {
- if (!SaveType(enum_def.name, *enum_def.defined_namespace, enumcode,
- false))
- return false;
- }
- }
-
- for (auto it = parser_.structs_.vec.begin();
- it != parser_.structs_.vec.end(); ++it) {
- std::string declcode;
- auto &struct_def = **it;
- if (!parser_.opts.one_file)
- cur_name_space_ = struct_def.defined_namespace;
- GenStruct(struct_def, &declcode);
- if (parser_.opts.one_file) {
- one_file_code += declcode;
- } else {
- if (!SaveType(struct_def.name, *struct_def.defined_namespace, declcode,
- true))
- return false;
- }
- }
-
- if (parser_.opts.one_file) {
- return SaveType(file_name_, *parser_.current_namespace_, one_file_code,
- true);
- }
- return true;
- }
-
- // Save out the generated code for a single class while adding
- // declaration boilerplate.
- bool SaveType(const std::string &defname, const Namespace &ns,
- const std::string &classcode, bool needs_includes) const {
- if (!classcode.length()) return true;
-
- std::string code;
- if (lang_.language == IDLOptions::kCSharp) {
- code =
- "// <auto-generated>\n"
- "// " +
- std::string(FlatBuffersGeneratedWarning()) +
- "\n"
- "// </auto-generated>\n\n";
- } else {
- code = "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
- }
-
- std::string namespace_name = FullNamespace(".", ns);
- if (!namespace_name.empty()) {
- code += lang_.namespace_ident + namespace_name + lang_.namespace_begin;
- code += "\n\n";
- }
- if (needs_includes) {
- code += lang_.includes;
- if (parser_.opts.gen_nullable) {
- code += "\nimport javax.annotation.Nullable;\n";
- }
- code += lang_.class_annotation;
- }
- if (parser_.opts.gen_generated) {
- code += lang_.generated_type_annotation;
- }
- code += classcode;
- if (!namespace_name.empty()) code += lang_.namespace_end;
- auto filename = NamespaceDir(ns) + defname + lang_.file_extension;
- return SaveFile(filename.c_str(), code, false);
- }
-
- const Namespace *CurrentNameSpace() const { return cur_name_space_; }
-
- std::string FunctionStart(char upper) const {
- return std::string() + (lang_.language == IDLOptions::kJava
- ? static_cast<char>(tolower(upper))
- : upper);
- }
-
- std::string GenNullableAnnotation(const Type &t) const {
- return lang_.language == IDLOptions::kJava && parser_.opts.gen_nullable &&
- !IsScalar(DestinationType(t, true).base_type)
- ? " @Nullable "
- : "";
- }
-
- static bool IsEnum(const Type &type) {
- return type.enum_def != nullptr && IsInteger(type.base_type);
- }
-
- std::string GenTypeBasic(const Type &type, bool enableLangOverrides) const {
- // clang-format off
- static const char * const java_typename[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
- #JTYPE,
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
- #undef FLATBUFFERS_TD
- };
-
- static const char * const csharp_typename[] = {
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
- #NTYPE,
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
- #undef FLATBUFFERS_TD
- };
- // clang-format on
-
- if (enableLangOverrides) {
- if (lang_.language == IDLOptions::kCSharp) {
- if (IsEnum(type)) return WrapInNameSpace(*type.enum_def);
- if (type.base_type == BASE_TYPE_STRUCT) {
- return "Offset<" + WrapInNameSpace(*type.struct_def) + ">";
- }
- }
- }
-
- if (lang_.language == IDLOptions::kJava) {
- return java_typename[type.base_type];
- } else {
- FLATBUFFERS_ASSERT(lang_.language == IDLOptions::kCSharp);
- return csharp_typename[type.base_type];
- }
- }
-
- std::string GenTypeBasic(const Type &type) const {
- return GenTypeBasic(type, true);
- }
-
- std::string GenTypePointer(const Type &type) const {
- switch (type.base_type) {
- case BASE_TYPE_STRING: return lang_.string_type;
- case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
- case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
- case BASE_TYPE_UNION:
- // Unions in C# use a generic Table-derived type for better type safety
- if (lang_.language == IDLOptions::kCSharp) return "TTable";
- FLATBUFFERS_FALLTHROUGH(); // else fall thru
- default: return "Table";
- }
- }
-
- std::string GenTypeGet(const Type &type) const {
- return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
- }
-
- // Find the destination type the user wants to receive the value in (e.g.
- // one size higher signed types for unsigned serialized values in Java).
- Type DestinationType(const Type &type, bool vectorelem) const {
- if (lang_.language != IDLOptions::kJava) return type;
- switch (type.base_type) {
- // We use int for both uchar/ushort, since that generally means less
- // casting than using short for uchar.
- case BASE_TYPE_UCHAR: return Type(BASE_TYPE_INT);
- case BASE_TYPE_USHORT: return Type(BASE_TYPE_INT);
- case BASE_TYPE_UINT: return Type(BASE_TYPE_LONG);
- case BASE_TYPE_VECTOR:
- if (vectorelem) return DestinationType(type.VectorType(), vectorelem);
- FLATBUFFERS_FALLTHROUGH(); // else fall thru
- default: return type;
- }
- }
-
- std::string GenOffsetType(const StructDef &struct_def) const {
- if (lang_.language == IDLOptions::kCSharp) {
- return "Offset<" + WrapInNameSpace(struct_def) + ">";
- } else {
- return "int";
- }
- }
-
- std::string GenOffsetConstruct(const StructDef &struct_def,
- const std::string &variable_name) const {
- if (lang_.language == IDLOptions::kCSharp) {
- return "new Offset<" + WrapInNameSpace(struct_def) + ">(" +
- variable_name + ")";
- }
- return variable_name;
- }
-
- std::string GenVectorOffsetType() const {
- if (lang_.language == IDLOptions::kCSharp) {
- return "VectorOffset";
- } else {
- return "int";
- }
- }
-
- // Generate destination type name
- std::string GenTypeNameDest(const Type &type) const {
- return GenTypeGet(DestinationType(type, true));
- }
-
- // Mask to turn serialized value into destination type value.
- std::string DestinationMask(const Type &type, bool vectorelem) const {
- if (lang_.language != IDLOptions::kJava) return "";
- switch (type.base_type) {
- case BASE_TYPE_UCHAR: return " & 0xFF";
- case BASE_TYPE_USHORT: return " & 0xFFFF";
- case BASE_TYPE_UINT: return " & 0xFFFFFFFFL";
- case BASE_TYPE_VECTOR:
- if (vectorelem) return DestinationMask(type.VectorType(), vectorelem);
- FLATBUFFERS_FALLTHROUGH(); // else fall thru
- default: return "";
- }
- }
-
- // Casts necessary to correctly read serialized data
- std::string DestinationCast(const Type &type) const {
- if (type.base_type == BASE_TYPE_VECTOR) {
- return DestinationCast(type.VectorType());
- } else {
- switch (lang_.language) {
- case IDLOptions::kJava:
- // Cast necessary to correctly read serialized unsigned values.
- if (type.base_type == BASE_TYPE_UINT) return "(long)";
- break;
-
- case IDLOptions::kCSharp:
- // Cast from raw integral types to enum.
- if (IsEnum(type)) return "(" + WrapInNameSpace(*type.enum_def) + ")";
- break;
-
- default: break;
- }
- }
- return "";
- }
-
- // Cast statements for mutator method parameters.
- // In Java, parameters representing unsigned numbers need to be cast down to
- // their respective type. For example, a long holding an unsigned int value
- // would be cast down to int before being put onto the buffer. In C#, one cast
- // directly cast an Enum to its underlying type, which is essential before
- // putting it onto the buffer.
- std::string SourceCast(const Type &type, bool castFromDest) const {
- if (type.base_type == BASE_TYPE_VECTOR) {
- return SourceCast(type.VectorType(), castFromDest);
- } else {
- switch (lang_.language) {
- case IDLOptions::kJava:
- if (castFromDest) {
- if (type.base_type == BASE_TYPE_UINT)
- return "(int)";
- else if (type.base_type == BASE_TYPE_USHORT)
- return "(short)";
- else if (type.base_type == BASE_TYPE_UCHAR)
- return "(byte)";
- }
- break;
- case IDLOptions::kCSharp:
- if (IsEnum(type)) return "(" + GenTypeBasic(type, false) + ")";
- break;
- default: break;
- }
- }
- return "";
- }
-
- std::string SourceCast(const Type &type) const { return SourceCast(type, true); }
-
- std::string SourceCastBasic(const Type &type, bool castFromDest) const {
- return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : "";
- }
-
- std::string SourceCastBasic(const Type &type) const {
- return SourceCastBasic(type, true);
- }
-
- std::string GenEnumDefaultValue(const FieldDef &field) const {
- auto& value = field.value;
- auto enum_def = value.type.enum_def;
- auto vec = enum_def->vals.vec;
- auto default_value = StringToInt(value.constant.c_str());
-
- auto result = value.constant;
- for (auto it = vec.begin(); it != vec.end(); ++it) {
- auto enum_val = **it;
- if (enum_val.value == default_value) {
- result = WrapInNameSpace(*enum_def) + "." + enum_val.name;
- break;
- }
- }
-
- return result;
- }
-
- std::string GenDefaultValue(const FieldDef &field, bool enableLangOverrides) const {
- auto& value = field.value;
- if (enableLangOverrides) {
- // handles both enum case and vector of enum case
- if (lang_.language == IDLOptions::kCSharp &&
- value.type.enum_def != nullptr &&
- value.type.base_type != BASE_TYPE_UNION) {
- return GenEnumDefaultValue(field);
- }
- }
-
- auto longSuffix = lang_.language == IDLOptions::kJava ? "L" : "";
- switch (value.type.base_type) {
- case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
- case BASE_TYPE_ULONG: {
- if (lang_.language != IDLOptions::kJava) return value.constant;
- // Converts the ulong into its bits signed equivalent
- uint64_t defaultValue = StringToUInt(value.constant.c_str());
- return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix;
- }
- case BASE_TYPE_UINT:
- case BASE_TYPE_LONG: return value.constant + longSuffix;
- default:
- if(IsFloat(value.type.base_type))
- return lang_.float_gen->GenFloatConstant(field);
- else
- return value.constant;
- }
- }
-
- std::string GenDefaultValue(const FieldDef &field) const {
- return GenDefaultValue(field, true);
- }
-
- std::string GenDefaultValueBasic(const FieldDef &field,
- bool enableLangOverrides) const {
- auto& value = field.value;
- if (!IsScalar(value.type.base_type)) {
- if (enableLangOverrides) {
- if (lang_.language == IDLOptions::kCSharp) {
- switch (value.type.base_type) {
- case BASE_TYPE_STRING: return "default(StringOffset)";
- case BASE_TYPE_STRUCT:
- return "default(Offset<" +
- WrapInNameSpace(*value.type.struct_def) + ">)";
- case BASE_TYPE_VECTOR: return "default(VectorOffset)";
- default: break;
- }
- }
- }
- return "0";
- }
- return GenDefaultValue(field, enableLangOverrides);
- }
-
- std::string GenDefaultValueBasic(const FieldDef &field) const {
- return GenDefaultValueBasic(field, true);
- }
-
- void GenEnum(EnumDef &enum_def, std::string *code_ptr) const {
- std::string &code = *code_ptr;
- if (enum_def.generated) return;
-
- // Generate enum definitions of the form:
- // public static (final) int name = value;
- // In Java, we use ints rather than the Enum feature, because we want them
- // to map directly to how they're used in C/C++ and file formats.
- // That, and Java Enums are expensive, and not universally liked.
- GenComment(enum_def.doc_comment, code_ptr, &lang_.comment_config);
- if (enum_def.attributes.Lookup("private")) {
- // For Java, we leave the enum unmarked to indicate package-private
- // For C# we mark the enum as internal
- if (lang_.language == IDLOptions::kCSharp) {
- code += "internal ";
- }
- } else {
- code += "public ";
- }
- code += lang_.enum_decl + enum_def.name;
- if (lang_.language == IDLOptions::kCSharp) {
- code += lang_.inheritance_marker +
- GenTypeBasic(enum_def.underlying_type, false);
- }
- code += lang_.open_curly;
- if (lang_.language == IDLOptions::kJava) {
- code += " private " + enum_def.name + "() { }\n";
- }
- for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
- auto &ev = **it;
- GenComment(ev.doc_comment, code_ptr, &lang_.comment_config, " ");
- if (lang_.language != IDLOptions::kCSharp) {
- code += " public static";
- code += lang_.const_decl;
- code += GenTypeBasic(enum_def.underlying_type, false);
- }
- code += " " + ev.name + " = ";
- code += NumToString(ev.value);
- code += lang_.enum_separator;
- }
-
- // Generate a generate string table for enum values.
- // We do not do that for C# where this functionality is native.
- if (lang_.language != IDLOptions::kCSharp) {
- // Problem is, if values are very sparse that could generate really big
- // tables. Ideally in that case we generate a map lookup instead, but for
- // the moment we simply don't output a table at all.
- auto range = enum_def.vals.vec.back()->value -
- enum_def.vals.vec.front()->value + 1;
- // Average distance between values above which we consider a table
- // "too sparse". Change at will.
- static const int kMaxSparseness = 5;
- if (range / static_cast<int64_t>(enum_def.vals.vec.size()) <
- kMaxSparseness) {
- code += "\n public static";
- code += lang_.const_decl;
- code += lang_.string_type;
- code += "[] names = { ";
- auto val = enum_def.Vals().front()->value;
- for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
- ++it) {
- while (val++ != (*it)->value) code += "\"\", ";
- code += "\"" + (*it)->name + "\", ";
- }
- code += "};\n\n";
- code += " public static ";
- code += lang_.string_type;
- code += " " + MakeCamel("name", lang_.first_camel_upper);
- code += "(int e) { return names[e";
- if (enum_def.vals.vec.front()->value)
- code += " - " + enum_def.vals.vec.front()->name;
- code += "]; }\n";
- }
- }
-
- // Close the class
- code += "}";
- // Java does not need the closing semi-colon on class definitions.
- code += (lang_.language != IDLOptions::kJava) ? ";" : "";
- code += "\n\n";
- }
-
- // Returns the function name that is able to read a value of the given type.
- std::string GenGetter(const Type &type) const {
- switch (type.base_type) {
- case BASE_TYPE_STRING: return lang_.accessor_prefix + "__string";
- case BASE_TYPE_STRUCT: return lang_.accessor_prefix + "__struct";
- case BASE_TYPE_UNION: return lang_.accessor_prefix + "__union";
- case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
- default: {
- std::string getter =
- lang_.accessor_prefix + "bb." + FunctionStart('G') + "et";
- if (type.base_type == BASE_TYPE_BOOL) {
- getter = "0!=" + getter;
- } else if (GenTypeBasic(type, false) != "byte") {
- getter += MakeCamel(GenTypeBasic(type, false));
- }
- return getter;
- }
- }
- }
-
- // Returns the function name that is able to read a value of the given type.
- std::string GenGetterForLookupByKey(flatbuffers::FieldDef *key_field,
- const std::string &data_buffer,
- const char *num = nullptr) const {
- auto type = key_field->value.type;
- auto dest_mask = DestinationMask(type, true);
- auto dest_cast = DestinationCast(type);
- auto getter = data_buffer + "." + FunctionStart('G') + "et";
- if (GenTypeBasic(type, false) != "byte") {
- getter += MakeCamel(GenTypeBasic(type, false));
- }
- getter = dest_cast + getter + "(" + GenOffsetGetter(key_field, num) + ")" +
- dest_mask;
- return getter;
- }
-
- // Direct mutation is only allowed for scalar fields.
- // Hence a setter method will only be generated for such fields.
- std::string GenSetter(const Type &type) const {
- if (IsScalar(type.base_type)) {
- std::string setter =
- lang_.accessor_prefix + "bb." + FunctionStart('P') + "ut";
- if (GenTypeBasic(type, false) != "byte" &&
- type.base_type != BASE_TYPE_BOOL) {
- setter += MakeCamel(GenTypeBasic(type, false));
- }
- return setter;
- } else {
- return "";
- }
- }
-
- // Returns the method name for use with add/put calls.
- std::string GenMethod(const Type &type) const {
- return IsScalar(type.base_type) ? MakeCamel(GenTypeBasic(type, false))
- : (IsStruct(type) ? "Struct" : "Offset");
- }
-
- // Recursively generate arguments for a constructor, to deal with nested
- // structs.
- void GenStructArgs(const StructDef &struct_def, std::string *code_ptr,
- const char *nameprefix) const {
- std::string &code = *code_ptr;
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (IsStruct(field.value.type)) {
- // Generate arguments for a struct inside a struct. To ensure names
- // don't clash, and to make it obvious these arguments are constructing
- // a nested struct, prefix the name with the field name.
- GenStructArgs(*field.value.type.struct_def, code_ptr,
- (nameprefix + (field.name + "_")).c_str());
- } else {
- code += ", ";
- code += GenTypeBasic(DestinationType(field.value.type, false));
- code += " ";
- code += nameprefix;
- code += MakeCamel(field.name, lang_.first_camel_upper);
- }
- }
- }
-
- // Recusively generate struct construction statements of the form:
- // builder.putType(name);
- // and insert manual padding.
- void GenStructBody(const StructDef &struct_def, std::string *code_ptr,
- const char *nameprefix) const {
- std::string &code = *code_ptr;
- code += " builder." + FunctionStart('P') + "rep(";
- code += NumToString(struct_def.minalign) + ", ";
- code += NumToString(struct_def.bytesize) + ");\n";
- for (auto it = struct_def.fields.vec.rbegin();
- it != struct_def.fields.vec.rend(); ++it) {
- auto &field = **it;
- if (field.padding) {
- code += " builder." + FunctionStart('P') + "ad(";
- code += NumToString(field.padding) + ");\n";
- }
- if (IsStruct(field.value.type)) {
- GenStructBody(*field.value.type.struct_def, code_ptr,
- (nameprefix + (field.name + "_")).c_str());
- } else {
- code += " builder." + FunctionStart('P') + "ut";
- code += GenMethod(field.value.type) + "(";
- code += SourceCast(field.value.type);
- auto argname =
- nameprefix + MakeCamel(field.name, lang_.first_camel_upper);
- code += argname;
- code += ");\n";
- }
- }
- }
-
- std::string GenByteBufferLength(const char *bb_name) const {
- std::string bb_len = bb_name;
- if (lang_.language == IDLOptions::kCSharp)
- bb_len += ".Length";
- else
- bb_len += ".capacity()";
- return bb_len;
- }
-
- std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
- const char *num = nullptr) const {
- std::string key_offset = "";
- key_offset += lang_.accessor_prefix_static + "__offset(" +
- NumToString(key_field->value.offset) + ", ";
- if (num) {
- key_offset += num;
- key_offset +=
- (lang_.language == IDLOptions::kCSharp ? ".Value, builder.DataBuffer)"
- : ", _bb)");
- } else {
- key_offset += GenByteBufferLength("bb");
- key_offset += " - tableOffset, bb)";
- }
- return key_offset;
- }
-
- std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) const {
- std::string key_getter = " ";
- key_getter += "int tableOffset = " + lang_.accessor_prefix_static;
- key_getter += "__indirect(vectorLocation + 4 * (start + middle)";
- key_getter += ", bb);\n ";
- if (key_field->value.type.base_type == BASE_TYPE_STRING) {
- key_getter += "int comp = " + lang_.accessor_prefix_static;
- key_getter += FunctionStart('C') + "ompareStrings(";
- key_getter += GenOffsetGetter(key_field);
- key_getter += ", byteKey, bb);\n";
- } else {
- auto get_val = GenGetterForLookupByKey(key_field, "bb");
- if (lang_.language == IDLOptions::kCSharp) {
- key_getter += "int comp = " + get_val + ".CompareTo(key);\n";
- } else {
- key_getter += GenTypeNameDest(key_field->value.type) + " val = ";
- key_getter += get_val + ";\n";
- key_getter += " int comp = val > key ? 1 : val < key ? -1 : 0;\n";
- }
- }
- return key_getter;
- }
-
- std::string GenKeyGetter(flatbuffers::FieldDef *key_field) const {
- std::string key_getter = "";
- auto data_buffer =
- (lang_.language == IDLOptions::kCSharp) ? "builder.DataBuffer" : "_bb";
- if (key_field->value.type.base_type == BASE_TYPE_STRING) {
- if (lang_.language == IDLOptions::kJava) key_getter += " return ";
- key_getter += lang_.accessor_prefix_static;
- key_getter += FunctionStart('C') + "ompareStrings(";
- key_getter += GenOffsetGetter(key_field, "o1") + ", ";
- key_getter += GenOffsetGetter(key_field, "o2") + ", " + data_buffer + ")";
- if (lang_.language == IDLOptions::kJava) key_getter += ";";
- } else {
- auto field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o1");
- if (lang_.language == IDLOptions::kCSharp) {
- key_getter += field_getter;
- field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o2");
- key_getter += ".CompareTo(" + field_getter + ")";
- } else {
- key_getter +=
- "\n " + GenTypeNameDest(key_field->value.type) + " val_1 = ";
- key_getter +=
- field_getter + ";\n " + GenTypeNameDest(key_field->value.type);
- key_getter += " val_2 = ";
- field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o2");
- key_getter += field_getter + ";\n";
- key_getter +=
- " return val_1 > val_2 ? 1 : val_1 < val_2 ? -1 : 0;\n ";
- }
- }
- return key_getter;
- }
-
- void GenStruct(StructDef &struct_def, std::string *code_ptr) const {
- if (struct_def.generated) return;
- std::string &code = *code_ptr;
-
- // Generate a struct accessor class, with methods of the form:
- // public type name() { return bb.getType(i + offset); }
- // or for tables of the form:
- // public type name() {
- // int o = __offset(offset); return o != 0 ? bb.getType(o + i) : default;
- // }
- GenComment(struct_def.doc_comment, code_ptr, &lang_.comment_config);
- if (struct_def.attributes.Lookup("private")) {
- // For Java, we leave the struct unmarked to indicate package-private
- // For C# we mark the struct as internal
- if (lang_.language == IDLOptions::kCSharp) {
- code += "internal ";
- }
- } else {
- code += "public ";
- }
- if (lang_.language == IDLOptions::kCSharp &&
- struct_def.attributes.Lookup("csharp_partial")) {
- // generate a partial class for this C# struct/table
- code += "partial ";
- } else {
- code += lang_.unsubclassable_decl;
- }
- code += lang_.accessor_type + struct_def.name;
- if (lang_.language == IDLOptions::kCSharp) {
- code += " : IFlatbufferObject";
- code += lang_.open_curly;
- code += " private ";
- code += struct_def.fixed ? "Struct" : "Table";
- code += " __p;\n";
-
- if (lang_.language == IDLOptions::kCSharp) {
- code += " public ByteBuffer ByteBuffer { get { return __p.bb; } }\n";
- }
-
- } else {
- code += lang_.inheritance_marker;
- code += struct_def.fixed ? "Struct" : "Table";
- code += lang_.open_curly;
- }
- if (!struct_def.fixed) {
- // Generate a special accessor for the table that when used as the root
- // of a FlatBuffer
- std::string method_name =
- FunctionStart('G') + "etRootAs" + struct_def.name;
- std::string method_signature =
- " public static " + struct_def.name + " " + method_name;
-
- // create convenience method that doesn't require an existing object
- code += method_signature + "(ByteBuffer _bb) ";
- code += "{ return " + method_name + "(_bb, new " + struct_def.name +
- "()); }\n";
-
- // create method that allows object reuse
- code +=
- method_signature + "(ByteBuffer _bb, " + struct_def.name + " obj) { ";
- code += lang_.set_bb_byteorder;
- code += "return (obj.__assign(_bb." + FunctionStart('G') + "etInt(_bb.";
- code += lang_.get_bb_position;
- code += ") + _bb.";
- code += lang_.get_bb_position;
- code += ", _bb)); }\n";
- if (parser_.root_struct_def_ == &struct_def) {
- if (parser_.file_identifier_.length()) {
- // Check if a buffer has the identifier.
- code += " public static ";
- code += lang_.bool_type + struct_def.name;
- code += "BufferHasIdentifier(ByteBuffer _bb) { return ";
- code += lang_.accessor_prefix_static + "__has_identifier(_bb, \"";
- code += parser_.file_identifier_;
- code += "\"); }\n";
- }
- }
- }
- // Generate the __init method that sets the field in a pre-existing
- // accessor object. This is to allow object reuse.
- code += " public void __init(int _i, ByteBuffer _bb) ";
- code += "{ " + lang_.accessor_prefix + "bb_pos = _i; ";
- code += lang_.accessor_prefix + "bb = _bb; ";
- if (!struct_def.fixed && lang_.language == IDLOptions::kJava) {
- code += lang_.accessor_prefix + "vtable_start = " + lang_.accessor_prefix + "bb_pos - ";
- code += lang_.accessor_prefix + "bb." + FunctionStart('G') + "etInt(";
- code += lang_.accessor_prefix + "bb_pos); " + lang_.accessor_prefix + "vtable_size = ";
- code += lang_.accessor_prefix + "bb." + FunctionStart('G') + "etShort(";
- code += lang_.accessor_prefix + "vtable_start); ";
- }
- code += "}\n";
- code +=
- " public " + struct_def.name + " __assign(int _i, ByteBuffer _bb) ";
- code += "{ __init(_i, _bb); return this; }\n\n";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
- GenComment(field.doc_comment, code_ptr, &lang_.comment_config, " ");
- std::string type_name = GenTypeGet(field.value.type);
- std::string type_name_dest = GenTypeNameDest(field.value.type);
- std::string conditional_cast = "";
- std::string optional = "";
- if (lang_.language == IDLOptions::kCSharp && !struct_def.fixed &&
- (field.value.type.base_type == BASE_TYPE_STRUCT ||
- field.value.type.base_type == BASE_TYPE_UNION ||
- (field.value.type.base_type == BASE_TYPE_VECTOR &&
- (field.value.type.element == BASE_TYPE_STRUCT ||
- field.value.type.element == BASE_TYPE_UNION)))) {
- optional = lang_.optional_suffix;
- conditional_cast = "(" + type_name_dest + optional + ")";
- }
- std::string dest_mask = DestinationMask(field.value.type, true);
- std::string dest_cast = DestinationCast(field.value.type);
- std::string src_cast = SourceCast(field.value.type);
- std::string method_start = " public " +
- (field.required ? "" : GenNullableAnnotation(field.value.type)) +
- type_name_dest + optional + " " +
- MakeCamel(field.name, lang_.first_camel_upper);
- std::string obj = lang_.language == IDLOptions::kCSharp
- ? "(new " + type_name + "())"
- : "obj";
-
- // Most field accessors need to retrieve and test the field offset first,
- // this is the prefix code for that:
- auto offset_prefix = " { int o = " + lang_.accessor_prefix + "__offset(" +
- NumToString(field.value.offset) +
- "); return o != 0 ? ";
- // Generate the accessors that don't do object reuse.
- if (field.value.type.base_type == BASE_TYPE_STRUCT) {
- // Calls the accessor that takes an accessor object with a new object.
- if (lang_.language != IDLOptions::kCSharp) {
- code += method_start + "() { return ";
- code += MakeCamel(field.name, lang_.first_camel_upper);
- code += "(new ";
- code += type_name + "()); }\n";
- }
- } else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
- field.value.type.element == BASE_TYPE_STRUCT) {
- // Accessors for vectors of structs also take accessor objects, this
- // generates a variant without that argument.
- if (lang_.language != IDLOptions::kCSharp) {
- code += method_start + "(int j) { return ";
- code += MakeCamel(field.name, lang_.first_camel_upper);
- code += "(new " + type_name + "(), j); }\n";
- }
- } else if (field.value.type.base_type == BASE_TYPE_UNION ||
- (field.value.type.base_type == BASE_TYPE_VECTOR &&
- field.value.type.VectorType().base_type == BASE_TYPE_UNION)) {
- if (lang_.language == IDLOptions::kCSharp) {
- // Union types in C# use generic Table-derived type for better type
- // safety.
- method_start += "<TTable>";
- type_name = type_name_dest;
- }
- }
- std::string getter = dest_cast + GenGetter(field.value.type);
- code += method_start;
- std::string default_cast = "";
- // only create default casts for c# scalars or vectors of scalars
- if (lang_.language == IDLOptions::kCSharp &&
- (IsScalar(field.value.type.base_type) ||
- (field.value.type.base_type == BASE_TYPE_VECTOR &&
- IsScalar(field.value.type.element)))) {
- // For scalars, default value will be returned by GetDefaultValue().
- // If the scalar is an enum, GetDefaultValue() returns an actual c# enum
- // that doesn't need to be casted. However, default values for enum
- // elements of vectors are integer literals ("0") and are still casted
- // for clarity.
- if (field.value.type.enum_def == nullptr ||
- field.value.type.base_type == BASE_TYPE_VECTOR) {
- default_cast = "(" + type_name_dest + ")";
- }
- }
- std::string member_suffix = "; ";
- if (IsScalar(field.value.type.base_type)) {
- code += lang_.getter_prefix;
- member_suffix += lang_.getter_suffix;
- if (struct_def.fixed) {
- code += " { return " + getter;
- code += "(" + lang_.accessor_prefix + "bb_pos + ";
- code += NumToString(field.value.offset) + ")";
- code += dest_mask;
- } else {
- code += offset_prefix + getter;
- code += "(o + " + lang_.accessor_prefix + "bb_pos)" + dest_mask;
- code += " : " + default_cast;
- code += GenDefaultValue(field);
- }
- } else {
- switch (field.value.type.base_type) {
- case BASE_TYPE_STRUCT:
- if (lang_.language != IDLOptions::kCSharp) {
- code += "(" + type_name + " obj" + ")";
- } else {
- code += lang_.getter_prefix;
- member_suffix += lang_.getter_suffix;
- }
- if (struct_def.fixed) {
- code += " { return " + obj + ".__assign(" + lang_.accessor_prefix;
- code += "bb_pos + " + NumToString(field.value.offset) + ", ";
- code += lang_.accessor_prefix + "bb)";
- } else {
- code += offset_prefix + conditional_cast;
- code += obj + ".__assign(";
- code += field.value.type.struct_def->fixed
- ? "o + " + lang_.accessor_prefix + "bb_pos"
- : lang_.accessor_prefix + "__indirect(o + " +
- lang_.accessor_prefix + "bb_pos)";
- code += ", " + lang_.accessor_prefix + "bb) : null";
- }
- break;
- case BASE_TYPE_STRING:
- code += lang_.getter_prefix;
- member_suffix += lang_.getter_suffix;
- code += offset_prefix + getter + "(o + " + lang_.accessor_prefix;
- code += "bb_pos) : null";
- break;
- case BASE_TYPE_VECTOR: {
- auto vectortype = field.value.type.VectorType();
- if (vectortype.base_type == BASE_TYPE_UNION &&
- lang_.language == IDLOptions::kCSharp) {
- conditional_cast = "(TTable?)";
- getter += "<TTable>";
- }
- code += "(";
- if (vectortype.base_type == BASE_TYPE_STRUCT) {
- if (lang_.language != IDLOptions::kCSharp)
- code += type_name + " obj, ";
- getter = obj + ".__assign";
- } else if (vectortype.base_type == BASE_TYPE_UNION) {
- if (lang_.language != IDLOptions::kCSharp)
- code += type_name + " obj, ";
- }
- code += "int j)";
- const auto body = offset_prefix + conditional_cast + getter + "(";
- if (vectortype.base_type == BASE_TYPE_UNION) {
- if (lang_.language != IDLOptions::kCSharp)
- code += body + "obj, ";
- else
- code += " where TTable : struct, IFlatbufferObject" + body;
- } else {
- code += body;
- }
- auto index = lang_.accessor_prefix + "__vector(o) + j * " +
- NumToString(InlineSize(vectortype));
- if (vectortype.base_type == BASE_TYPE_STRUCT) {
- code += vectortype.struct_def->fixed
- ? index
- : lang_.accessor_prefix + "__indirect(" + index + ")";
- code += ", " + lang_.accessor_prefix + "bb";
- } else if (vectortype.base_type == BASE_TYPE_UNION) {
- code += index + " - " + lang_.accessor_prefix + "bb_pos";
- } else {
- code += index;
- }
- code += ")" + dest_mask + " : ";
-
- code +=
- field.value.type.element == BASE_TYPE_BOOL
- ? "false"
- : (IsScalar(field.value.type.element) ? default_cast + "0"
- : "null");
- break;
- }
- case BASE_TYPE_UNION:
- if (lang_.language == IDLOptions::kCSharp) {
- code += "() where TTable : struct, IFlatbufferObject";
- code += offset_prefix + "(TTable?)" + getter;
- code += "<TTable>(o) : null";
- } else {
- code += "(" + type_name + " obj)" + offset_prefix + getter;
- code += "(obj, o) : null";
- }
- break;
- default: FLATBUFFERS_ASSERT(0);
- }
- }
- code += member_suffix;
- code += "}\n";
- if (field.value.type.base_type == BASE_TYPE_VECTOR) {
- code +=
- " public int " + MakeCamel(field.name, lang_.first_camel_upper);
- code += "Length";
- code += lang_.getter_prefix;
- code += offset_prefix;
- code += lang_.accessor_prefix + "__vector_len(o) : 0; ";
- code += lang_.getter_suffix;
- code += "}\n";
- // See if we should generate a by-key accessor.
- if (field.value.type.element == BASE_TYPE_STRUCT &&
- !field.value.type.struct_def->fixed) {
- auto &sd = *field.value.type.struct_def;
- auto &fields = sd.fields.vec;
- for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
- auto &key_field = **kit;
- if (key_field.key) {
- auto qualified_name = WrapInNameSpace(sd);
- code += " public " + qualified_name + lang_.optional_suffix + " ";
- code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey(";
- code += GenTypeNameDest(key_field.value.type) + " key)";
- code += offset_prefix;
- code += qualified_name + ".__lookup_by_key(";
- if (lang_.language == IDLOptions::kJava)
- code += "null, ";
- code += lang_.accessor_prefix + "__vector(o), key, ";
- code += lang_.accessor_prefix + "bb) : null; ";
- code += "}\n";
- if (lang_.language == IDLOptions::kJava) {
- code += " public " + qualified_name + lang_.optional_suffix + " ";
- code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey(";
- code += qualified_name + lang_.optional_suffix + " obj, ";
- code += GenTypeNameDest(key_field.value.type) + " key)";
- code += offset_prefix;
- code += qualified_name + ".__lookup_by_key(obj, ";
- code += lang_.accessor_prefix + "__vector(o), key, ";
- code += lang_.accessor_prefix + "bb) : null; ";
- code += "}\n";
- }
- break;
- }
- }
- }
- }
- // Generate a ByteBuffer accessor for strings & vectors of scalars.
- if ((field.value.type.base_type == BASE_TYPE_VECTOR &&
- IsScalar(field.value.type.VectorType().base_type)) ||
- field.value.type.base_type == BASE_TYPE_STRING) {
- switch (lang_.language) {
- case IDLOptions::kJava:
- code += " public ByteBuffer ";
- code += MakeCamel(field.name, lang_.first_camel_upper);
- code += "AsByteBuffer() { return ";
- code += lang_.accessor_prefix + "__vector_as_bytebuffer(";
- code += NumToString(field.value.offset) + ", ";
- code +=
- NumToString(field.value.type.base_type == BASE_TYPE_STRING
- ? 1
- : InlineSize(field.value.type.VectorType()));
- code += "); }\n";
- code += " public ByteBuffer ";
- code += MakeCamel(field.name, lang_.first_camel_upper);
- code += "InByteBuffer(ByteBuffer _bb) { return ";
- code += lang_.accessor_prefix + "__vector_in_bytebuffer(_bb, ";
- code += NumToString(field.value.offset) + ", ";
- code +=
- NumToString(field.value.type.base_type == BASE_TYPE_STRING
- ? 1
- : InlineSize(field.value.type.VectorType()));
- code += "); }\n";
- break;
- case IDLOptions::kCSharp:
- code += "#if ENABLE_SPAN_T\n";
- code += " public Span<byte> Get";
- code += MakeCamel(field.name, lang_.first_camel_upper);
- code += "Bytes() { return ";
- code += lang_.accessor_prefix + "__vector_as_span(";
- code += NumToString(field.value.offset);
- code += "); }\n";
- code += "#else\n";
- code += " public ArraySegment<byte>? Get";
- code += MakeCamel(field.name, lang_.first_camel_upper);
- code += "Bytes() { return ";
- code += lang_.accessor_prefix + "__vector_as_arraysegment(";
- code += NumToString(field.value.offset);
- code += "); }\n";
- code += "#endif\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;
- }
- }
- // generate object accessors if is nested_flatbuffer
- if (field.nested_flatbuffer) {
- auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
- auto nested_method_name =
- MakeCamel(field.name, lang_.first_camel_upper) + "As" +
- nested_type_name;
- auto get_nested_method_name = nested_method_name;
- if (lang_.language == IDLOptions::kCSharp) {
- get_nested_method_name = "Get" + nested_method_name;
- conditional_cast =
- "(" + nested_type_name + lang_.optional_suffix + ")";
- }
- if (lang_.language != IDLOptions::kCSharp) {
- code += " public " + nested_type_name + lang_.optional_suffix + " ";
- code += nested_method_name + "() { return ";
- code +=
- get_nested_method_name + "(new " + nested_type_name + "()); }\n";
- } else {
- obj = "(new " + nested_type_name + "())";
- }
- code += " public " + nested_type_name + lang_.optional_suffix + " ";
- code += get_nested_method_name + "(";
- if (lang_.language != IDLOptions::kCSharp)
- code += nested_type_name + " obj";
- code += ") { int o = " + lang_.accessor_prefix + "__offset(";
- code += NumToString(field.value.offset) + "); ";
- code += "return o != 0 ? " + conditional_cast + obj + ".__assign(";
- code += lang_.accessor_prefix;
- code += "__indirect(" + lang_.accessor_prefix + "__vector(o)), ";
- code += lang_.accessor_prefix + "bb) : null; }\n";
- }
- // Generate mutators for scalar fields or vectors of scalars.
- if (parser_.opts.mutable_buffer) {
- auto underlying_type = field.value.type.base_type == BASE_TYPE_VECTOR
- ? field.value.type.VectorType()
- : field.value.type;
- // Boolean parameters have to be explicitly converted to byte
- // representation.
- auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL
- ? "(byte)(" + field.name + " ? 1 : 0)"
- : field.name;
- auto mutator_prefix = MakeCamel("mutate", lang_.first_camel_upper);
- // A vector mutator also needs the index of the vector element it should
- // mutate.
- auto mutator_params =
- (field.value.type.base_type == BASE_TYPE_VECTOR ? "(int j, "
- : "(") +
- GenTypeNameDest(underlying_type) + " " + field.name + ") { ";
- auto setter_index =
- field.value.type.base_type == BASE_TYPE_VECTOR
- ? lang_.accessor_prefix + "__vector(o) + j * " +
- NumToString(InlineSize(underlying_type))
- : (struct_def.fixed
- ? lang_.accessor_prefix + "bb_pos + " +
- NumToString(field.value.offset)
- : "o + " + lang_.accessor_prefix + "bb_pos");
- if (IsScalar(field.value.type.base_type) ||
- (field.value.type.base_type == BASE_TYPE_VECTOR &&
- IsScalar(field.value.type.VectorType().base_type))) {
- code += " public ";
- code += struct_def.fixed ? "void " : lang_.bool_type;
- code += mutator_prefix + MakeCamel(field.name, true);
- code += mutator_params;
- if (struct_def.fixed) {
- code += GenSetter(underlying_type) + "(" + setter_index + ", ";
- code += src_cast + setter_parameter + "); }\n";
- } else {
- code += "int o = " + lang_.accessor_prefix + "__offset(";
- code += NumToString(field.value.offset) + ");";
- code += " if (o != 0) { " + GenSetter(underlying_type);
- code += "(" + setter_index + ", " + src_cast + setter_parameter +
- "); return true; } else { return false; } }\n";
- }
- }
- }
- }
- code += "\n";
- flatbuffers::FieldDef *key_field = nullptr;
- if (struct_def.fixed) {
- // create a struct constructor function
- code += " public static " + GenOffsetType(struct_def) + " ";
- code += FunctionStart('C') + "reate";
- code += struct_def.name + "(FlatBufferBuilder builder";
- GenStructArgs(struct_def, code_ptr, "");
- code += ") {\n";
- GenStructBody(struct_def, code_ptr, "");
- code += " return ";
- code += GenOffsetConstruct(
- struct_def, "builder." + std::string(lang_.get_fbb_offset));
- code += ";\n }\n";
- } else {
- // Generate a method that creates a table in one go. This is only possible
- // when the table has no struct fields, since those have to be created
- // inline, and there's no way to do so in Java.
- bool has_no_struct_fields = true;
- int num_fields = 0;
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
- if (IsStruct(field.value.type)) {
- has_no_struct_fields = false;
- } else {
- num_fields++;
- }
- }
- // JVM specifications restrict default constructor params to be < 255.
- // Longs and doubles take up 2 units, so we set the limit to be < 127.
- if (has_no_struct_fields && num_fields && num_fields < 127) {
- // Generate a table constructor of the form:
- // public static int createName(FlatBufferBuilder builder, args...)
- code += " public static " + GenOffsetType(struct_def) + " ";
- code += FunctionStart('C') + "reate" + struct_def.name;
- code += "(FlatBufferBuilder builder";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
- code += ",\n ";
- code += GenTypeBasic(DestinationType(field.value.type, false));
- code += " ";
- code += field.name;
- if (!IsScalar(field.value.type.base_type)) code += "Offset";
-
- // Java doesn't have defaults, which means this method must always
- // supply all arguments, and thus won't compile when fields are added.
- if (lang_.language != IDLOptions::kJava) {
- code += " = ";
- code += GenDefaultValueBasic(field);
- }
- }
- code += ") {\n builder.";
- code += FunctionStart('S') + "tartObject(";
- code += NumToString(struct_def.fields.vec.size()) + ");\n";
- for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1;
- size; size /= 2) {
- for (auto it = struct_def.fields.vec.rbegin();
- it != struct_def.fields.vec.rend(); ++it) {
- auto &field = **it;
- if (!field.deprecated &&
- (!struct_def.sortbysize ||
- size == SizeOf(field.value.type.base_type))) {
- code += " " + struct_def.name + ".";
- code += FunctionStart('A') + "dd";
- code += MakeCamel(field.name) + "(builder, " + field.name;
- if (!IsScalar(field.value.type.base_type)) code += "Offset";
- code += ");\n";
- }
- }
- }
- code += " return " + struct_def.name + ".";
- code += FunctionStart('E') + "nd" + struct_def.name;
- code += "(builder);\n }\n\n";
- }
- // Generate a set of static methods that allow table construction,
- // of the form:
- // public static void addName(FlatBufferBuilder builder, short name)
- // { builder.addShort(id, name, default); }
- // Unlike the Create function, these always work.
- code += " public static void " + FunctionStart('S') + "tart";
- code += struct_def.name;
- code += "(FlatBufferBuilder builder) { builder.";
- code += FunctionStart('S') + "tartObject(";
- code += NumToString(struct_def.fields.vec.size()) + "); }\n";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
- if (field.key) key_field = &field;
- code += " public static void " + FunctionStart('A') + "dd";
- code += MakeCamel(field.name);
- code += "(FlatBufferBuilder builder, ";
- code += GenTypeBasic(DestinationType(field.value.type, false));
- auto argname = MakeCamel(field.name, false);
- if (!IsScalar(field.value.type.base_type)) argname += "Offset";
- code += " " + argname + ") { builder." + FunctionStart('A') + "dd";
- code += GenMethod(field.value.type) + "(";
- code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
- code += SourceCastBasic(field.value.type);
- code += argname;
- if (!IsScalar(field.value.type.base_type) &&
- field.value.type.base_type != BASE_TYPE_UNION &&
- lang_.language == IDLOptions::kCSharp) {
- code += ".Value";
- }
- code += ", ";
- if (lang_.language == IDLOptions::kJava)
- code += SourceCastBasic(field.value.type);
- code += GenDefaultValue(field, false);
- code += "); }\n";
- if (field.value.type.base_type == BASE_TYPE_VECTOR) {
- auto vector_type = field.value.type.VectorType();
- auto alignment = InlineAlignment(vector_type);
- auto elem_size = InlineSize(vector_type);
- if (!IsStruct(vector_type)) {
- // Generate a method to create a vector from a Java array.
- code += " public static " + GenVectorOffsetType() + " ";
- code += FunctionStart('C') + "reate";
- code += MakeCamel(field.name);
- code += "Vector(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 += "); for (int i = data.";
- code += FunctionStart('L') + "ength - 1; i >= 0; i--) builder.";
- code += FunctionStart('A') + "dd";
- code += GenMethod(vector_type);
- code += "(";
- code += SourceCastBasic(vector_type, false);
- code += "data[i]";
- if (lang_.language == IDLOptions::kCSharp &&
- (vector_type.base_type == BASE_TYPE_STRUCT ||
- vector_type.base_type == BASE_TYPE_STRING))
- 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.
- code += " public static void " + FunctionStart('S') + "tart";
- code += MakeCamel(field.name);
- code += "Vector(FlatBufferBuilder builder, int numElems) ";
- code += "{ builder." + FunctionStart('S') + "tartVector(";
- code += NumToString(elem_size);
- code += ", numElems, " + NumToString(alignment);
- code += "); }\n";
- }
- }
- code += " public static " + GenOffsetType(struct_def) + " ";
- code += FunctionStart('E') + "nd" + struct_def.name;
- code += "(FlatBufferBuilder builder) {\n int o = builder.";
- code += FunctionStart('E') + "ndObject();\n";
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (!field.deprecated && field.required) {
- code += " builder." + FunctionStart('R') + "equired(o, ";
- code += NumToString(field.value.offset);
- code += "); // " + field.name + "\n";
- }
- }
- code += " return " + GenOffsetConstruct(struct_def, "o") + ";\n }\n";
- if (parser_.root_struct_def_ == &struct_def) {
- std::string size_prefix[] = { "", "SizePrefixed" };
- for (int i = 0; i < 2; ++i) {
- code += " public static void ";
- code += FunctionStart('F') + "inish" + size_prefix[i] +
- struct_def.name;
- code += "Buffer(FlatBufferBuilder builder, " +
- GenOffsetType(struct_def);
- code += " offset) {";
- code += " builder." + FunctionStart('F') + "inish" + size_prefix[i] +
- "(offset";
- if (lang_.language == IDLOptions::kCSharp) { code += ".Value"; }
-
- if (parser_.file_identifier_.length())
- code += ", \"" + parser_.file_identifier_ + "\"";
- code += "); }\n";
- }
- }
- }
- // Only generate key compare function for table,
- // because `key_field` is not set for struct
- if (struct_def.has_key && !struct_def.fixed) {
- if (lang_.language == IDLOptions::kJava) {
- code += "\n @Override\n protected int keysCompare(";
- code += "Integer o1, Integer o2, ByteBuffer _bb) {";
- code += GenKeyGetter(key_field);
- code += " }\n";
- } else {
- code += "\n public static VectorOffset ";
- code += "CreateSortedVectorOf" + struct_def.name;
- code += "(FlatBufferBuilder builder, ";
- code += "Offset<" + struct_def.name + ">";
- code += "[] offsets) {\n";
- code += " Array.Sort(offsets, (Offset<" + struct_def.name +
- "> o1, Offset<" + struct_def.name + "> o2) => " +
- GenKeyGetter(key_field);
- code += ");\n";
- code += " return builder.CreateVectorOfTables(offsets);\n }\n";
- }
-
- code += "\n public static " + struct_def.name + lang_.optional_suffix;
- code += " __lookup_by_key(";
- if (lang_.language == IDLOptions::kJava)
- code += struct_def.name + " obj, ";
- code += "int vectorLocation, ";
- code += GenTypeNameDest(key_field->value.type);
- code += " key, ByteBuffer bb) {\n";
- if (key_field->value.type.base_type == BASE_TYPE_STRING) {
- code += " byte[] byteKey = ";
- if (lang_.language == IDLOptions::kJava)
- code += "key.getBytes(Table.UTF8_CHARSET.get());\n";
- else
- code += "System.Text.Encoding.UTF8.GetBytes(key);\n";
- }
- code += " int span = ";
- code += "bb." + FunctionStart('G') + "etInt(vectorLocation - 4);\n";
- code += " int start = 0;\n";
- code += " while (span != 0) {\n";
- code += " int middle = span / 2;\n";
- code += GenLookupKeyGetter(key_field);
- code += " if (comp > 0) {\n";
- code += " span = middle;\n";
- code += " } else if (comp < 0) {\n";
- code += " middle++;\n";
- code += " start += middle;\n";
- code += " span -= middle;\n";
- code += " } else {\n";
- code += " return ";
- if (lang_.language == IDLOptions::kJava)
- code += "(obj == null ? new " + struct_def.name + "() : obj)";
- else
- code += "new " + struct_def.name + "()";
- code += ".__assign(tableOffset, bb);\n";
- code += " }\n }\n";
- code += " return null;\n";
- code += " }\n";
- }
- code += "}";
- // Java does not need the closing semi-colon on class definitions.
- code += (lang_.language != IDLOptions::kJava) ? ";" : "";
- code += "\n\n";
- }
- const LanguageParameters &lang_;
- // This tracks the current namespace used to determine if a type need to be
- // prefixed by its namespace
- const Namespace *cur_name_space_;
-};
-} // namespace general
-
-bool GenerateGeneral(const Parser &parser, const std::string &path,
- const std::string &file_name) {
- general::GeneralGenerator generator(parser, path, file_name);
- return generator.generate();
-}
-
-std::string GeneralMakeRule(const Parser &parser, const std::string &path,
- const std::string &file_name) {
- FLATBUFFERS_ASSERT(parser.opts.lang <= IDLOptions::kMAX);
- const auto &lang = GetLangParams(parser.opts.lang);
-
- std::string make_rule;
-
- for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end();
- ++it) {
- auto &enum_def = **it;
- if (make_rule != "") make_rule += " ";
- std::string directory =
- BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace);
- make_rule += directory + enum_def.name + lang.file_extension;
- }
-
- for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
- ++it) {
- auto &struct_def = **it;
- if (make_rule != "") make_rule += " ";
- std::string directory = BaseGenerator::NamespaceDir(
- parser, path, *struct_def.defined_namespace);
- make_rule += directory + struct_def.name + lang.file_extension;
- }
-
- make_rule += ": ";
- auto included_files = parser.GetIncludedFilesRecursive(file_name);
- for (auto it = included_files.begin(); it != included_files.end(); ++it) {
- make_rule += " " + *it;
- }
- return make_rule;
-}
-
-std::string BinaryFileName(const Parser &parser, const std::string &path,
- const std::string &file_name) {
- auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin";
- return path + file_name + "." + ext;
-}
-
-bool GenerateBinary(const Parser &parser, const std::string &path,
- const std::string &file_name) {
- return !parser.builder_.GetSize() ||
- flatbuffers::SaveFile(
- BinaryFileName(parser, path, file_name).c_str(),
- reinterpret_cast<char *>(parser.builder_.GetBufferPointer()),
- parser.builder_.GetSize(), true);
-}
-
-std::string BinaryMakeRule(const Parser &parser, const std::string &path,
- const std::string &file_name) {
- if (!parser.builder_.GetSize()) return "";
- std::string filebase =
- flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
- std::string make_rule =
- BinaryFileName(parser, path, filebase) + ": " + file_name;
- auto included_files =
- parser.GetIncludedFilesRecursive(parser.root_struct_def_->file);
- for (auto it = included_files.begin(); it != included_files.end(); ++it) {
- make_rule += " " + *it;
- }
- return make_rule;
-}
-
-} // namespace flatbuffers
diff --git a/src/idl_gen_go.cpp b/src/idl_gen_go.cpp
index 412d1e82..a1a277ca 100644
--- a/src/idl_gen_go.cpp
+++ b/src/idl_gen_go.cpp
@@ -35,15 +35,10 @@
namespace flatbuffers {
-static std::string GeneratedFileName(const std::string &path,
- const std::string &file_name) {
- return path + file_name + "_generated.go";
-}
-
namespace go {
// see https://golang.org/ref/spec#Keywords
-static const char * const g_golang_keywords[] = {
+static const char *const g_golang_keywords[] = {
"break", "default", "func", "interface", "select", "case", "defer",
"go", "map", "struct", "chan", "else", "goto", "package",
"switch", "const", "fallthrough", "if", "range", "type", "continue",
@@ -64,7 +59,7 @@ class GoGenerator : public BaseGenerator {
GoGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, const std::string &go_namespace)
: BaseGenerator(parser, path, file_name, "" /* not used*/,
- "" /* not used */),
+ "" /* not used */, "go"),
cur_name_space_(nullptr) {
std::istringstream iss(go_namespace);
std::string component;
@@ -75,15 +70,23 @@ class GoGenerator : public BaseGenerator {
bool generate() {
std::string one_file_code;
+ bool needs_imports = false;
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) {
tracked_imported_namespaces_.clear();
+ needs_imports = false;
std::string enumcode;
GenEnum(**it, &enumcode);
+ if ((*it)->is_union && parser_.opts.generate_object_based_api) {
+ GenNativeUnion(**it, &enumcode);
+ GenNativeUnionPack(**it, &enumcode);
+ GenNativeUnionUnPack(**it, &enumcode);
+ needs_imports = true;
+ }
if (parser_.opts.one_file) {
one_file_code += enumcode;
} else {
- if (!SaveType(**it, enumcode, false)) return false;
+ if (!SaveType(**it, enumcode, needs_imports, true)) return false;
}
}
@@ -95,15 +98,17 @@ class GoGenerator : public BaseGenerator {
if (parser_.opts.one_file) {
one_file_code += declcode;
} else {
- if (!SaveType(**it, declcode, true)) return false;
+ if (!SaveType(**it, declcode, true, false)) return false;
}
}
if (parser_.opts.one_file) {
std::string code = "";
- BeginFile(LastNamespacePart(go_namespace_), true, &code);
+ const bool is_enum = !parser_.enums_.vec.empty();
+ BeginFile(LastNamespacePart(go_namespace_), true, is_enum, &code);
code += one_file_code;
- const std::string filename = GeneratedFileName(path_, file_name_);
+ const std::string filename =
+ GeneratedFileName(path_, file_name_, parser_.opts);
return SaveFile(filename.c_str(), code, false);
}
@@ -113,7 +118,13 @@ class GoGenerator : public BaseGenerator {
private:
Namespace go_namespace_;
Namespace *cur_name_space_;
- std::set<const Namespace*> tracked_imported_namespaces_;
+
+ struct NamespacePtrLess {
+ bool operator()(const Namespace *a, const Namespace *b) const {
+ return *a < *b;
+ }
+ };
+ std::set<const Namespace *, NamespacePtrLess> tracked_imported_namespaces_;
// Most field accessors need to retrieve and test the field offset first,
// this is the prefix code for that.
@@ -134,16 +145,17 @@ class GoGenerator : public BaseGenerator {
code += "\n}\n\n";
}
- // Construct the name of the type alias for this enum.
+ // Construct the name of the type for this enum.
std::string GetEnumTypeName(const EnumDef &enum_def) {
- return WrapInNameSpaceAndTrack(cur_name_space_, GoIdentity(enum_def.name));
+ return WrapInNameSpaceAndTrack(enum_def.defined_namespace,
+ GoIdentity(enum_def.name));
}
// Create a type for the enum values.
void GenEnumType(const EnumDef &enum_def, std::string *code_ptr) {
std::string &code = *code_ptr;
- code += "type " + GetEnumTypeName(enum_def) + " = ";
- code += GenTypeBasic(enum_def.underlying_type) + "\n";
+ code += "type " + GetEnumTypeName(enum_def) + " ";
+ code += GenTypeBasic(enum_def.underlying_type) + "\n\n";
}
// Begin enum code with a class declaration.
@@ -154,15 +166,16 @@ class GoGenerator : public BaseGenerator {
// A single enum member.
void EnumMember(const EnumDef &enum_def, const EnumVal &ev,
- std::string *code_ptr) {
+ size_t max_name_length, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "\t";
code += enum_def.name;
code += ev.name;
code += " ";
+ code += std::string(max_name_length - ev.name.length(), ' ');
code += GetEnumTypeName(enum_def);
code += " = ";
- code += NumToString(ev.value) + "\n";
+ code += enum_def.ToString(ev) + "\n";
}
// End enum code.
@@ -171,7 +184,7 @@ class GoGenerator : public BaseGenerator {
code += ")\n\n";
}
- // Begin enum name code.
+ // Begin enum name map.
void BeginEnumNames(const EnumDef &enum_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "var EnumNames";
@@ -180,23 +193,64 @@ class GoGenerator : public BaseGenerator {
}
// A single enum name member.
- void EnumNameMember(const EnumDef &enum_def, const EnumVal ev,
- std::string *code_ptr) {
+ void EnumNameMember(const EnumDef &enum_def, const EnumVal &ev,
+ size_t max_name_length, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "\t";
code += enum_def.name;
code += ev.name;
- code += ":\"";
+ code += ": ";
+ code += std::string(max_name_length - ev.name.length(), ' ');
+ code += "\"";
code += ev.name;
code += "\",\n";
}
- // End enum name code.
+ // End enum name map.
void EndEnumNames(std::string *code_ptr) {
std::string &code = *code_ptr;
code += "}\n\n";
}
+ // Generate String() method on enum type.
+ void EnumStringer(const EnumDef &enum_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "func (v " + enum_def.name + ") String() string {\n";
+ code += "\tif s, ok := EnumNames" + enum_def.name + "[v]; ok {\n";
+ code += "\t\treturn s\n";
+ code += "\t}\n";
+ code += "\treturn \"" + enum_def.name;
+ code += "(\" + strconv.FormatInt(int64(v), 10) + \")\"\n";
+ code += "}\n\n";
+ }
+
+ // Begin enum value map.
+ void BeginEnumValues(const EnumDef &enum_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "var EnumValues";
+ code += enum_def.name;
+ code += " = map[string]" + GetEnumTypeName(enum_def) + "{\n";
+ }
+
+ // A single enum value member.
+ void EnumValueMember(const EnumDef &enum_def, const EnumVal &ev,
+ size_t max_name_length, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "\t\"";
+ code += ev.name;
+ code += "\": ";
+ code += std::string(max_name_length - ev.name.length(), ' ');
+ code += enum_def.name;
+ code += ev.name;
+ code += ",\n";
+ }
+
+ // End enum value map.
+ void EndEnumValues(std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "}\n\n";
+ }
+
// Initialize a new struct or table from existing data.
void NewRootTypeFromBuffer(const StructDef &struct_def,
std::string *code_ptr) {
@@ -268,29 +322,30 @@ class GoGenerator : public BaseGenerator {
// Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
+ const FieldDef &field, std::string *code_ptr) {
std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name);
code += "() " + TypeName(field) + " {\n";
- code += "\treturn " + getter;
- code += "(rcv._tab.Pos + flatbuffers.UOffsetT(";
- code += NumToString(field.value.offset) + "))\n}\n";
+ code += "\treturn " +
+ CastToEnum(field.value.type,
+ getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" +
+ NumToString(field.value.offset) + "))");
+ code += "\n}\n";
}
// Get the value of a table's scalar.
- void GetScalarFieldOfTable(const StructDef &struct_def,
- const FieldDef &field,
+ void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name);
code += "() " + TypeName(field) + " ";
- code += OffsetPrefix(field) + "\t\treturn " + getter;
- code += "(o + rcv._tab.Pos)\n\t}\n";
+ code += OffsetPrefix(field) + "\t\treturn ";
+ code += CastToEnum(field.value.type, getter + "(o + rcv._tab.Pos)");
+ code += "\n\t}\n";
code += "\treturn " + GenConstant(field) + "\n";
code += "}\n\n";
}
@@ -298,8 +353,7 @@ class GoGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct.
// Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
+ const FieldDef &field, std::string *code_ptr) {
std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name);
@@ -317,8 +371,7 @@ class GoGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct.
// Specific to Table.
- void GetStructFieldOfTable(const StructDef &struct_def,
- const FieldDef &field,
+ void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
@@ -340,8 +393,7 @@ class GoGenerator : public BaseGenerator {
}
// Get the value of a string.
- void GetStringField(const StructDef &struct_def,
- const FieldDef &field,
+ void GetStringField(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
@@ -358,7 +410,7 @@ class GoGenerator : public BaseGenerator {
std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name) + "(";
- code += "obj " + TypeName(field) + ") bool ";
+ code += "obj " + GenTypePointer(field.value.type) + ") bool ";
code += OffsetPrefix(field);
code += "\t\t" + GenGetter(field.value.type);
code += "(obj, o)\n\t\treturn true\n\t}\n";
@@ -368,8 +420,7 @@ class GoGenerator : public BaseGenerator {
// Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
+ const FieldDef &field, std::string *code_ptr) {
std::string &code = *code_ptr;
auto vectortype = field.value.type.VectorType();
@@ -389,8 +440,7 @@ class GoGenerator : public BaseGenerator {
code += "}\n\n";
}
- // Get the value of a vector's non-struct member. Uses a named return
- // argument to conveniently set the zero value for the result.
+ // Get the value of a vector's non-struct member.
void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
const FieldDef &field,
std::string *code_ptr) {
@@ -402,10 +452,12 @@ class GoGenerator : public BaseGenerator {
code += "(j int) " + TypeName(field) + " ";
code += OffsetPrefix(field);
code += "\t\ta := rcv._tab.Vector(o)\n";
- code += "\t\treturn " + GenGetter(field.value.type) + "(";
- code += "a + flatbuffers.UOffsetT(j*";
- code += NumToString(InlineSize(vectortype)) + "))\n";
- code += "\t}\n";
+ code += "\t\treturn " +
+ CastToEnum(field.value.type,
+ GenGetter(field.value.type) +
+ "(a + flatbuffers.UOffsetT(j*" +
+ NumToString(InlineSize(vectortype)) + "))");
+ code += "\n\t}\n";
if (vectortype.base_type == BASE_TYPE_STRING) {
code += "\treturn nil\n";
} else if (vectortype.base_type == BASE_TYPE_BOOL) {
@@ -445,7 +497,7 @@ class GoGenerator : public BaseGenerator {
std::string &code = *code_ptr;
code += std::string(", ") + nameprefix;
code += GoIdentity(field.name);
- code += " " + GenTypeBasic(field.value.type);
+ code += " " + TypeName(field);
}
}
}
@@ -458,8 +510,8 @@ class GoGenerator : public BaseGenerator {
// Recursively generate struct construction statements and instert manual
// padding.
- void StructBuilderBody(const StructDef &struct_def,
- const char *nameprefix, std::string *code_ptr) {
+ void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
+ std::string *code_ptr) {
std::string &code = *code_ptr;
code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", ";
code += NumToString(struct_def.bytesize) + ")\n";
@@ -473,7 +525,9 @@ class GoGenerator : public BaseGenerator {
(nameprefix + (field.name + "_")).c_str(), code_ptr);
} else {
code += "\tbuilder.Prepend" + GenMethod(field) + "(";
- code += nameprefix + GoIdentity(field.name) + ")\n";
+ code += CastToBaseType(field.value.type,
+ nameprefix + GoIdentity(field.name)) +
+ ")\n";
}
}
}
@@ -504,7 +558,7 @@ class GoGenerator : public BaseGenerator {
if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
code += "flatbuffers.UOffsetT";
} else {
- code += GenTypeBasic(field.value.type);
+ code += TypeName(field);
}
code += ") {\n";
code += "\tbuilder.Prepend";
@@ -515,15 +569,15 @@ class GoGenerator : public BaseGenerator {
code += "(";
code += GoIdentity(field.name) + ")";
} else {
- code += GoIdentity(field.name);
+ code += CastToBaseType(field.value.type, GoIdentity(field.name));
}
code += ", " + GenConstant(field);
code += ")\n}\n";
}
// Set the value of one of the members of a table's vector.
- void BuildVectorOfTable(const StructDef &struct_def,
- const FieldDef &field, std::string *code_ptr) {
+ void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
std::string &code = *code_ptr;
code += "func " + struct_def.name + "Start";
code += MakeCamel(field.name);
@@ -552,8 +606,8 @@ class GoGenerator : public BaseGenerator {
}
// Generate a struct field getter, conditioned on its child type(s).
- void GenStructAccessor(const StructDef &struct_def,
- const FieldDef &field, std::string *code_ptr) {
+ void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, nullptr, "");
if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) {
@@ -570,7 +624,9 @@ class GoGenerator : public BaseGenerator {
GetStructFieldOfTable(struct_def, field, code_ptr);
}
break;
- case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break;
+ case BASE_TYPE_STRING:
+ GetStringField(struct_def, field, code_ptr);
+ break;
case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -594,8 +650,7 @@ class GoGenerator : public BaseGenerator {
// Mutate the value of a struct's scalar.
void MutateScalarFieldOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
+ const FieldDef &field, std::string *code_ptr) {
std::string &code = *code_ptr;
std::string type = MakeCamel(GenTypeBasic(field.value.type));
std::string setter = "rcv._tab.Mutate" + type;
@@ -603,20 +658,21 @@ class GoGenerator : public BaseGenerator {
code += " Mutate" + MakeCamel(field.name);
code += "(n " + TypeName(field) + ") bool {\n\treturn " + setter;
code += "(rcv._tab.Pos+flatbuffers.UOffsetT(";
- code += NumToString(field.value.offset) + "), n)\n}\n\n";
+ code += NumToString(field.value.offset) + "), ";
+ code += CastToBaseType(field.value.type, "n") + ")\n}\n\n";
}
// Mutate the value of a table's scalar.
void MutateScalarFieldOfTable(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
+ const FieldDef &field, std::string *code_ptr) {
std::string &code = *code_ptr;
std::string type = MakeCamel(GenTypeBasic(field.value.type));
std::string setter = "rcv._tab.Mutate" + type + "Slot";
GenReceiver(struct_def, code_ptr);
code += " Mutate" + MakeCamel(field.name);
code += "(n " + TypeName(field) + ") bool {\n\treturn ";
- code += setter + "(" + NumToString(field.value.offset) + ", n)\n";
+ code += setter + "(" + NumToString(field.value.offset) + ", ";
+ code += CastToBaseType(field.value.type, "n") + ")\n";
code += "}\n\n";
}
@@ -635,7 +691,8 @@ class GoGenerator : public BaseGenerator {
code += "\t\ta := rcv._tab.Vector(o)\n";
code += "\t\treturn " + setter + "(";
code += "a+flatbuffers.UOffsetT(j*";
- code += NumToString(InlineSize(vectortype)) + "), n)\n";
+ code += NumToString(InlineSize(vectortype)) + "), ";
+ code += CastToBaseType(vectortype, "n") + ")\n";
code += "\t}\n";
code += "\treturn false\n";
code += "}\n\n";
@@ -684,6 +741,9 @@ class GoGenerator : public BaseGenerator {
cur_name_space_ = struct_def.defined_namespace;
GenComment(struct_def.doc_comment, code_ptr, nullptr);
+ if (parser_.opts.generate_object_based_api) {
+ GenNativeStruct(struct_def, code_ptr);
+ }
BeginClass(struct_def, code_ptr);
if (!struct_def.fixed) {
// Generate a special accessor for the table that has been declared as
@@ -716,28 +776,359 @@ class GoGenerator : public BaseGenerator {
}
}
+ void GenNativeStruct(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "type " + NativeName(struct_def) + " struct {\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ const FieldDef &field = **it;
+ if (field.deprecated) continue;
+ if (IsScalar(field.value.type.base_type) &&
+ field.value.type.enum_def != nullptr &&
+ field.value.type.enum_def->is_union)
+ continue;
+ code += "\t" + MakeCamel(field.name) + " " +
+ NativeType(field.value.type) + "\n";
+ }
+ code += "}\n\n";
+
+ if (!struct_def.fixed) {
+ GenNativeTablePack(struct_def, code_ptr);
+ GenNativeTableUnPack(struct_def, code_ptr);
+ } else {
+ GenNativeStructPack(struct_def, code_ptr);
+ GenNativeStructUnPack(struct_def, code_ptr);
+ }
+ }
+
+ void GenNativeUnion(const EnumDef &enum_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "type " + NativeName(enum_def) + " struct {\n";
+ code += "\tType " + enum_def.name + "\n";
+ code += "\tValue interface{}\n";
+ code += "}\n\n";
+ }
+
+ void GenNativeUnionPack(const EnumDef &enum_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "func (t *" + NativeName(enum_def) +
+ ") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n";
+ code += "\tif t == nil {\n\t\treturn 0\n\t}\n";
+
+ code += "\tswitch t.Type {\n";
+ for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end();
+ ++it2) {
+ const EnumVal &ev = **it2;
+ if (ev.IsZero()) continue;
+ code += "\tcase " + enum_def.name + ev.name + ":\n";
+ code += "\t\treturn t.Value.(" + NativeType(ev.union_type) +
+ ").Pack(builder)\n";
+ }
+ code += "\t}\n";
+ code += "\treturn 0\n";
+ code += "}\n\n";
+ }
+
+ void GenNativeUnionUnPack(const EnumDef &enum_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "func (rcv " + enum_def.name +
+ ") UnPack(table flatbuffers.Table) *" + NativeName(enum_def) +
+ " {\n";
+ code += "\tswitch rcv {\n";
+
+ for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end();
+ ++it2) {
+ const EnumVal &ev = **it2;
+ if (ev.IsZero()) continue;
+ code += "\tcase " + enum_def.name + ev.name + ":\n";
+ code += "\t\tx := " + ev.union_type.struct_def->name + "{_tab: table}\n";
+
+ code += "\t\treturn &" +
+ WrapInNameSpaceAndTrack(enum_def.defined_namespace,
+ NativeName(enum_def)) +
+ "{ Type: " + enum_def.name + ev.name + ", Value: x.UnPack() }\n";
+ }
+ code += "\t}\n";
+ code += "\treturn nil\n";
+ code += "}\n\n";
+ }
+
+ void GenNativeTablePack(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "func (t *" + NativeName(struct_def) +
+ ") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n";
+ code += "\tif t == nil { return 0 }\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ const FieldDef &field = **it;
+ if (field.deprecated) continue;
+ if (IsScalar(field.value.type.base_type)) continue;
+
+ std::string offset = MakeCamel(field.name, false) + "Offset";
+
+ if (field.value.type.base_type == BASE_TYPE_STRING) {
+ code += "\t" + offset + " := builder.CreateString(t." +
+ MakeCamel(field.name) + ")\n";
+ } else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
+ field.value.type.element == BASE_TYPE_UCHAR &&
+ field.value.type.enum_def == nullptr) {
+ code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n";
+ code += "\tif t." + MakeCamel(field.name) + " != nil {\n";
+ code += "\t\t" + offset + " = builder.CreateByteString(t." +
+ MakeCamel(field.name) + ")\n";
+ code += "\t}\n";
+ } else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n";
+ code += "\tif t." + MakeCamel(field.name) + " != nil {\n";
+ std::string length = MakeCamel(field.name, false) + "Length";
+ std::string offsets = MakeCamel(field.name, false) + "Offsets";
+ code += "\t\t" + length + " := len(t." + MakeCamel(field.name) + ")\n";
+ if (field.value.type.element == BASE_TYPE_STRING) {
+ code += "\t\t" + offsets + " := make([]flatbuffers.UOffsetT, " +
+ length + ")\n";
+ code += "\t\tfor j := 0; j < " + length + "; j++ {\n";
+ code += "\t\t\t" + offsets + "[j] = builder.CreateString(t." +
+ MakeCamel(field.name) + "[j])\n";
+ code += "\t\t}\n";
+ } else if (field.value.type.element == BASE_TYPE_STRUCT &&
+ !field.value.type.struct_def->fixed) {
+ code += "\t\t" + offsets + " := make([]flatbuffers.UOffsetT, " +
+ length + ")\n";
+ code += "\t\tfor j := 0; j < " + length + "; j++ {\n";
+ code += "\t\t\t" + offsets + "[j] = t." + MakeCamel(field.name) +
+ "[j].Pack(builder)\n";
+ code += "\t\t}\n";
+ }
+ code += "\t\t" + struct_def.name + "Start" + MakeCamel(field.name) +
+ "Vector(builder, " + length + ")\n";
+ code += "\t\tfor j := " + length + " - 1; j >= 0; j-- {\n";
+ if (IsScalar(field.value.type.element)) {
+ code += "\t\t\tbuilder.Prepend" +
+ MakeCamel(GenTypeBasic(field.value.type.VectorType())) + "(" +
+ CastToBaseType(field.value.type.VectorType(),
+ "t." + MakeCamel(field.name) + "[j]") +
+ ")\n";
+ } else if (field.value.type.element == BASE_TYPE_STRUCT &&
+ field.value.type.struct_def->fixed) {
+ code += "\t\t\tt." + MakeCamel(field.name) + "[j].Pack(builder)\n";
+ } else {
+ code += "\t\t\tbuilder.PrependUOffsetT(" + offsets + "[j])\n";
+ }
+ code += "\t\t}\n";
+ code += "\t\t" + offset + " = builder.EndVector(" + length + ")\n";
+ code += "\t}\n";
+ } else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+ if (field.value.type.struct_def->fixed) continue;
+ code += "\t" + offset + " := t." + MakeCamel(field.name) +
+ ".Pack(builder)\n";
+ } else if (field.value.type.base_type == BASE_TYPE_UNION) {
+ code += "\t" + offset + " := t." + MakeCamel(field.name) +
+ ".Pack(builder)\n";
+ code += "\t\n";
+ } else {
+ FLATBUFFERS_ASSERT(0);
+ }
+ }
+ code += "\t" + struct_def.name + "Start(builder)\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ const FieldDef &field = **it;
+ if (field.deprecated) continue;
+
+ std::string offset = MakeCamel(field.name, false) + "Offset";
+ if (IsScalar(field.value.type.base_type)) {
+ if (field.value.type.enum_def == nullptr ||
+ !field.value.type.enum_def->is_union) {
+ code += "\t" + struct_def.name + "Add" + MakeCamel(field.name) +
+ "(builder, t." + MakeCamel(field.name) + ")\n";
+ }
+ } else {
+ if (field.value.type.base_type == BASE_TYPE_STRUCT &&
+ field.value.type.struct_def->fixed) {
+ code += "\t" + offset + " := t." + MakeCamel(field.name) +
+ ".Pack(builder)\n";
+ } else if (field.value.type.enum_def != nullptr &&
+ field.value.type.enum_def->is_union) {
+ code += "\tif t." + MakeCamel(field.name) + " != nil {\n";
+ code += "\t\t" + struct_def.name + "Add" +
+ MakeCamel(field.name + UnionTypeFieldSuffix()) +
+ "(builder, t." + MakeCamel(field.name) + ".Type)\n";
+ code += "\t}\n";
+ }
+ code += "\t" + struct_def.name + "Add" + MakeCamel(field.name) +
+ "(builder, " + offset + ")\n";
+ }
+ }
+ code += "\treturn " + struct_def.name + "End(builder)\n";
+ code += "}\n\n";
+ }
+
+ void GenNativeTableUnPack(const StructDef &struct_def,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" +
+ NativeName(struct_def) + ") {\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ const FieldDef &field = **it;
+ if (field.deprecated) continue;
+ std::string field_name_camel = MakeCamel(field.name);
+ std::string length = MakeCamel(field.name, false) + "Length";
+ if (IsScalar(field.value.type.base_type)) {
+ if (field.value.type.enum_def != nullptr &&
+ field.value.type.enum_def->is_union)
+ continue;
+ code +=
+ "\tt." + field_name_camel + " = rcv." + field_name_camel + "()\n";
+ } else if (field.value.type.base_type == BASE_TYPE_STRING) {
+ code += "\tt." + field_name_camel + " = string(rcv." +
+ field_name_camel + "())\n";
+ } else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
+ field.value.type.element == BASE_TYPE_UCHAR &&
+ field.value.type.enum_def == nullptr) {
+ code += "\tt." + field_name_camel + " = rcv." + field_name_camel +
+ "Bytes()\n";
+ } else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ code += "\t" + length + " := rcv." + field_name_camel + "Length()\n";
+ code += "\tt." + field_name_camel + " = make(" +
+ NativeType(field.value.type) + ", " + length + ")\n";
+ code += "\tfor j := 0; j < " + length + "; j++ {\n";
+ if (field.value.type.element == BASE_TYPE_STRUCT) {
+ code += "\t\tx := " + field.value.type.struct_def->name + "{}\n";
+ code += "\t\trcv." + field_name_camel + "(&x, j)\n";
+ }
+ code += "\t\tt." + field_name_camel + "[j] = ";
+ if (IsScalar(field.value.type.element)) {
+ code += "rcv." + field_name_camel + "(j)";
+ } else if (field.value.type.element == BASE_TYPE_STRING) {
+ code += "string(rcv." + field_name_camel + "(j))";
+ } else if (field.value.type.element == BASE_TYPE_STRUCT) {
+ code += "x.UnPack()";
+ } else {
+ // TODO(iceboy): Support vector of unions.
+ FLATBUFFERS_ASSERT(0);
+ }
+ code += "\n";
+ code += "\t}\n";
+ } else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+ code += "\tt." + field_name_camel + " = rcv." + field_name_camel +
+ "(nil).UnPack()\n";
+ } else if (field.value.type.base_type == BASE_TYPE_UNION) {
+ std::string field_table = MakeCamel(field.name, false) + "Table";
+ code += "\t" + field_table + " := flatbuffers.Table{}\n";
+ code +=
+ "\tif rcv." + MakeCamel(field.name) + "(&" + field_table + ") {\n";
+ code += "\t\tt." + field_name_camel + " = rcv." +
+ MakeCamel(field.name + UnionTypeFieldSuffix()) + "().UnPack(" +
+ field_table + ")\n";
+ code += "\t}\n";
+ } else {
+ FLATBUFFERS_ASSERT(0);
+ }
+ }
+ code += "}\n\n";
+
+ code += "func (rcv *" + struct_def.name + ") UnPack() *" +
+ NativeName(struct_def) + " {\n";
+ code += "\tif rcv == nil { return nil }\n";
+ code += "\tt := &" + NativeName(struct_def) + "{}\n";
+ code += "\trcv.UnPackTo(t)\n";
+ code += "\treturn t\n";
+ code += "}\n\n";
+ }
+
+ void GenNativeStructPack(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "func (t *" + NativeName(struct_def) +
+ ") Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {\n";
+ code += "\tif t == nil { return 0 }\n";
+ code += "\treturn Create" + struct_def.name + "(builder";
+ StructPackArgs(struct_def, "", code_ptr);
+ code += ")\n";
+ code += "}\n";
+ }
+
+ void StructPackArgs(const StructDef &struct_def, const char *nameprefix,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ const FieldDef &field = **it;
+ if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+ StructPackArgs(*field.value.type.struct_def,
+ (nameprefix + MakeCamel(field.name) + ".").c_str(),
+ code_ptr);
+ } else {
+ code += std::string(", t.") + nameprefix + MakeCamel(field.name);
+ }
+ }
+ }
+
+ void GenNativeStructUnPack(const StructDef &struct_def,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" +
+ NativeName(struct_def) + ") {\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ const FieldDef &field = **it;
+ if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+ code += "\tt." + MakeCamel(field.name) + " = rcv." +
+ MakeCamel(field.name) + "(nil).UnPack()\n";
+ } else {
+ code += "\tt." + MakeCamel(field.name) + " = rcv." +
+ MakeCamel(field.name) + "()\n";
+ }
+ }
+ code += "}\n\n";
+
+ code += "func (rcv *" + struct_def.name + ") UnPack() *" +
+ NativeName(struct_def) + " {\n";
+ code += "\tif rcv == nil { return nil }\n";
+ code += "\tt := &" + NativeName(struct_def) + "{}\n";
+ code += "\trcv.UnPackTo(t)\n";
+ code += "\treturn t\n";
+ code += "}\n\n";
+ }
+
// Generate enum declarations.
void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
if (enum_def.generated) return;
+ auto max_name_length = MaxNameLength(enum_def);
cur_name_space_ = enum_def.defined_namespace;
GenComment(enum_def.doc_comment, code_ptr, nullptr);
GenEnumType(enum_def, code_ptr);
BeginEnum(code_ptr);
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
- auto &ev = **it;
+ const EnumVal &ev = **it;
GenComment(ev.doc_comment, code_ptr, nullptr, "\t");
- EnumMember(enum_def, ev, code_ptr);
+ EnumMember(enum_def, ev, max_name_length, code_ptr);
}
EndEnum(code_ptr);
BeginEnumNames(enum_def, code_ptr);
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
- auto &ev = **it;
- EnumNameMember(enum_def, ev, code_ptr);
+ const EnumVal &ev = **it;
+ EnumNameMember(enum_def, ev, max_name_length, code_ptr);
}
EndEnumNames(code_ptr);
+
+ BeginEnumValues(enum_def, code_ptr);
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ auto &ev = **it;
+ EnumValueMember(enum_def, ev, max_name_length, code_ptr);
+ }
+ EndEnumValues(code_ptr);
+
+ EnumStringer(enum_def, code_ptr);
}
// Returns the function name that is able to read a value of the given type.
@@ -758,15 +1149,14 @@ class GoGenerator : public BaseGenerator {
}
std::string GenTypeBasic(const Type &type) {
- static const char *ctypename[] = {
// clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ static const char *ctypename[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, ...) \
#GTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- // clang-format on
};
+ // clang-format on
return ctypename[type.base_type];
}
@@ -782,9 +1172,7 @@ class GoGenerator : public BaseGenerator {
}
std::string GenTypeGet(const Type &type) {
- if (type.enum_def != nullptr && !type.enum_def->is_union) {
- return GetEnumTypeName(*type.enum_def);
- }
+ if (type.enum_def != nullptr) { return GetEnumTypeName(*type.enum_def); }
return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
}
@@ -792,13 +1180,66 @@ class GoGenerator : public BaseGenerator {
return GenTypeGet(field.value.type);
}
+ // If type is an enum, returns value with a cast to the enum type, otherwise
+ // returns value as-is.
+ std::string CastToEnum(const Type &type, std::string value) {
+ if (type.enum_def == nullptr) {
+ return value;
+ } else {
+ return GenTypeGet(type) + "(" + value + ")";
+ }
+ }
+
+ // If type is an enum, returns value with a cast to the enum base type,
+ // otherwise returns value as-is.
+ std::string CastToBaseType(const Type &type, std::string value) {
+ if (type.enum_def == nullptr) {
+ return value;
+ } else {
+ return GenTypeBasic(type) + "(" + value + ")";
+ }
+ }
+
std::string GenConstant(const FieldDef &field) {
switch (field.value.type.base_type) {
- case BASE_TYPE_BOOL: return field.value.constant == "0" ? "false" : "true";;
+ case BASE_TYPE_BOOL:
+ return field.value.constant == "0" ? "false" : "true";
default: return field.value.constant;
}
}
+ std::string NativeName(const StructDef &struct_def) {
+ return parser_.opts.object_prefix + struct_def.name +
+ parser_.opts.object_suffix;
+ }
+
+ std::string NativeName(const EnumDef &enum_def) {
+ return parser_.opts.object_prefix + enum_def.name +
+ parser_.opts.object_suffix;
+ }
+
+ std::string NativeType(const Type &type) {
+ if (IsScalar(type.base_type)) {
+ if (type.enum_def == nullptr) {
+ return GenTypeBasic(type);
+ } else {
+ return GetEnumTypeName(*type.enum_def);
+ }
+ } else if (type.base_type == BASE_TYPE_STRING) {
+ return "string";
+ } else if (type.base_type == BASE_TYPE_VECTOR) {
+ return "[]" + NativeType(type.VectorType());
+ } else if (type.base_type == BASE_TYPE_STRUCT) {
+ return "*" + WrapInNameSpaceAndTrack(type.struct_def->defined_namespace,
+ NativeName(*type.struct_def));
+ } else if (type.base_type == BASE_TYPE_UNION) {
+ return "*" + WrapInNameSpaceAndTrack(type.enum_def->defined_namespace,
+ NativeName(*type.enum_def));
+ }
+ FLATBUFFERS_ASSERT(0);
+ return std::string();
+ }
+
// Create a struct with a builder and the struct's arguments.
void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
BeginBuilderArgs(struct_def, code_ptr);
@@ -809,13 +1250,15 @@ class GoGenerator : public BaseGenerator {
EndBuilderBody(code_ptr);
}
// Begin by declaring namespace and imports.
- void BeginFile(const std::string name_space_name, const bool needs_imports,
- std::string *code_ptr) {
+ void BeginFile(const std::string &name_space_name, const bool needs_imports,
+ const bool is_enum, std::string *code_ptr) {
std::string &code = *code_ptr;
- code = code + "// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n";
+ code = code +
+ "// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n";
code += "package " + name_space_name + "\n\n";
if (needs_imports) {
code += "import (\n";
+ if (is_enum) { code += "\t\"strconv\"\n\n"; }
if (!parser_.opts.go_import.empty()) {
code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n";
} else {
@@ -824,26 +1267,31 @@ class GoGenerator : public BaseGenerator {
if (tracked_imported_namespaces_.size() > 0) {
code += "\n";
for (auto it = tracked_imported_namespaces_.begin();
- it != tracked_imported_namespaces_.end();
- ++it) {
- code += "\t" + NamespaceImportName(*it) + " \"" + \
- NamespaceImportPath(*it) + "\"\n";
+ it != tracked_imported_namespaces_.end(); ++it) {
+ code += "\t" + NamespaceImportName(*it) + " \"" +
+ NamespaceImportPath(*it) + "\"\n";
}
}
code += ")\n\n";
+ } else {
+ if (is_enum) { code += "import \"strconv\"\n\n"; }
}
}
// Save out the generated code for a Go Table type.
bool SaveType(const Definition &def, const std::string &classcode,
- bool needs_imports) {
+ const bool needs_imports, const bool is_enum) {
if (!classcode.length()) return true;
Namespace &ns = go_namespace_.components.empty() ? *def.defined_namespace
: go_namespace_;
std::string code = "";
- BeginFile(LastNamespacePart(ns), needs_imports, &code);
+ BeginFile(LastNamespacePart(ns), needs_imports, is_enum, &code);
code += classcode;
+ // Strip extra newlines at end of file to make it gofmt-clean.
+ while (code.length() > 2 && code.substr(code.length() - 2) == "\n\n") {
+ code.pop_back();
+ }
std::string filename = NamespaceDir(ns) + def.name + ".go";
return SaveFile(filename.c_str(), code, false);
}
@@ -891,6 +1339,14 @@ class GoGenerator : public BaseGenerator {
}
const Namespace *CurrentNameSpace() const { return cur_name_space_; }
+
+ static size_t MaxNameLength(const EnumDef &enum_def) {
+ size_t max = 0;
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ max = std::max((*it)->name.length(), max);
+ }
+ return max;
+ }
};
} // namespace go
diff --git a/src/idl_gen_grpc.cpp b/src/idl_gen_grpc.cpp
index d682a553..d1a71170 100644
--- a/src/idl_gen_grpc.cpp
+++ b/src/idl_gen_grpc.cpp
@@ -20,10 +20,12 @@
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-
#include "src/compiler/cpp_generator.h"
#include "src/compiler/go_generator.h"
#include "src/compiler/java_generator.h"
+#include "src/compiler/python_generator.h"
+#include "src/compiler/python_private_generator.h"
+#include "src/compiler/swift_generator.h"
#if defined(_MSC_VER)
# pragma warning(push)
@@ -35,9 +37,7 @@ namespace flatbuffers {
class FlatBufMethod : public grpc_generator::Method {
public:
- enum Streaming {
- kNone, kClient, kServer, kBiDi
- };
+ enum Streaming { kNone, kClient, kServer, kBiDi };
FlatBufMethod(const RPCCall *method) : method_(method) {
streaming_ = kNone;
@@ -80,6 +80,8 @@ class FlatBufMethod : public grpc_generator::Method {
return true;
}
+ std::string get_fb_builder() const { return "builder"; }
+
std::string input_type_name() const { return GRPCType(*method_->request); }
std::string output_type_name() const { return GRPCType(*method_->response); }
@@ -149,7 +151,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
}
void Print(const char *s) {
- if (s == nullptr || std::strlen(s) == 0) { return; }
+ if (s == nullptr || *s == '\0') { return; }
// Add this string, but for each part separated by \n, add indentation.
for (;;) {
// Current indentation.
@@ -171,7 +173,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
void Outdent() {
indent_--;
- FLATBUFFERS_ASSERT(indent_ >= 0);
+ FLATBUFFERS_ASSERT(indent_ >= 0);
}
private:
@@ -183,7 +185,11 @@ class FlatBufPrinter : public grpc_generator::Printer {
class FlatBufFile : public grpc_generator::File {
public:
enum Language {
- kLanguageGo, kLanguageCpp, kLanguageJava
+ kLanguageGo,
+ kLanguageCpp,
+ kLanguageJava,
+ kLanguagePython,
+ kLanguageSwift
};
FlatBufFile(const Parser &parser, const std::string &file_name,
@@ -229,6 +235,12 @@ class FlatBufFile : public grpc_generator::File {
case kLanguageJava: {
return "import com.google.flatbuffers.grpc.FlatbuffersUtils;";
}
+ case kLanguagePython: {
+ return "";
+ }
+ case kLanguageSwift: {
+ return "";
+ }
}
return "";
}
@@ -257,7 +269,7 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
public:
GoGRPCGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "", "" /*Unused*/),
+ : BaseGenerator(parser, path, file_name, "", "" /*Unused*/, "go"),
parser_(parser),
path_(path),
file_name_(file_name) {}
@@ -270,7 +282,8 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
auto service = file.service(i);
const Definition *def = parser_.services_.vec[i];
p.package_name = LastNamespacePart(*(def->defined_namespace));
- p.service_prefix = def->defined_namespace->GetFullyQualifiedName(""); // file.package();
+ p.service_prefix =
+ def->defined_namespace->GetFullyQualifiedName(""); // file.package();
std::string output =
grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
std::string filename =
@@ -313,27 +326,27 @@ bool GenerateCppGRPC(const Parser &parser, const std::string &path,
std::string header_code =
grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) +
- grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) +
- grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) +
- grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters);
+ grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) +
+ grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) +
+ grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters);
std::string source_code =
grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) +
- grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) +
- grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) +
- grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters);
+ grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) +
+ grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) +
+ grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters);
return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(),
header_code, false) &&
- flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(),
- source_code, false);
+ flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(),
+ source_code, false);
}
class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
public:
JavaGRPCGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "", "." /*separator*/) {}
+ : BaseGenerator(parser, path, file_name, "", "." /*separator*/, "java") {}
bool generate() {
FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageJava);
@@ -364,6 +377,77 @@ bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
return JavaGRPCGenerator(parser, path, file_name).generate();
}
+bool GeneratePythonGRPC(const Parser &parser, const std::string & /*path*/,
+ const std::string &file_name) {
+ int nservices = 0;
+ for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
+ ++it) {
+ if (!(*it)->generated) nservices++;
+ }
+ if (!nservices) return true;
+
+ grpc_python_generator::GeneratorConfiguration config;
+ config.grpc_package_root = "grpc";
+ config.beta_package_root = "grpc.beta";
+ config.import_prefix = "";
+
+ FlatBufFile fbfile(parser, file_name, FlatBufFile::kLanguagePython);
+
+ grpc_python_generator::PrivateGenerator generator(config, &fbfile);
+
+ std::string code = generator.GetGrpcServices();
+ std::string namespace_dir;
+ auto &namespaces = parser.namespaces_.back()->components;
+ for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
+ if (it != namespaces.begin()) namespace_dir += kPathSeparator;
+ namespace_dir += *it;
+ }
+
+ std::string grpc_py_filename =
+ namespace_dir + kPathSeparator + file_name + "_grpc_fb.py";
+ return flatbuffers::SaveFile(grpc_py_filename.c_str(), code, false);
+}
+
+class SwiftGRPCGenerator : public flatbuffers::BaseGenerator {
+ private:
+ CodeWriter code_;
+
+ public:
+ SwiftGRPCGenerator(const Parser &parser, const std::string &path,
+ const std::string &filename)
+ : BaseGenerator(parser, path, filename, "", "" /*Unused*/, "swift") {}
+
+ bool generate() {
+ code_.Clear();
+ code_ += "// Generated GRPC code for FlatBuffers swift!";
+ code_ += grpc_swift_generator::GenerateHeader();
+ FlatBufFile file(parser_, file_name_, FlatBufFile::kLanguageSwift);
+ for (int i = 0; i < file.service_count(); i++) {
+ auto service = file.service(i);
+ code_ += grpc_swift_generator::Generate(&file, service.get());
+ }
+ const auto final_code = code_.ToString();
+ const auto filename = GeneratedFileName(path_, file_name_);
+ return SaveFile(filename.c_str(), final_code, false);
+ }
+
+ static std::string GeneratedFileName(const std::string &path,
+ const std::string &file_name) {
+ return path + file_name + ".grpc.swift";
+ }
+};
+
+bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ int nservices = 0;
+ for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
+ ++it) {
+ if (!(*it)->generated) nservices++;
+ }
+ if (!nservices) return true;
+ return SwiftGRPCGenerator(parser, path, file_name).generate();
+}
+
} // namespace flatbuffers
#if defined(_MSC_VER)
diff --git a/src/idl_gen_java.cpp b/src/idl_gen_java.cpp
new file mode 100644
index 00000000..9679a1aa
--- /dev/null
+++ b/src/idl_gen_java.cpp
@@ -0,0 +1,1237 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+#if defined(FLATBUFFERS_CPP98_STL)
+# include <cctype>
+#endif // defined(FLATBUFFERS_CPP98_STL)
+
+namespace flatbuffers {
+namespace java {
+
+static TypedFloatConstantGenerator JavaFloatGen("Double.", "Float.", "NaN",
+ "POSITIVE_INFINITY",
+ "NEGATIVE_INFINITY");
+
+static CommentConfig comment_config = {
+ "/**",
+ " *",
+ " */",
+};
+
+class JavaGenerator : public BaseGenerator {
+ public:
+ JavaGenerator(const Parser &parser, const std::string &path,
+ const std::string &file_name)
+ : BaseGenerator(parser, path, file_name, "", ".", "java"),
+ cur_name_space_(nullptr) {}
+
+ JavaGenerator &operator=(const JavaGenerator &);
+ bool generate() {
+ std::string one_file_code;
+ cur_name_space_ = parser_.current_namespace_;
+
+ for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+ ++it) {
+ std::string enumcode;
+ auto &enum_def = **it;
+ if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
+ GenEnum(enum_def, &enumcode);
+ if (parser_.opts.one_file) {
+ one_file_code += enumcode;
+ } else {
+ if (!SaveType(enum_def.name, *enum_def.defined_namespace, enumcode,
+ false))
+ return false;
+ }
+ }
+
+ for (auto it = parser_.structs_.vec.begin();
+ it != parser_.structs_.vec.end(); ++it) {
+ std::string declcode;
+ auto &struct_def = **it;
+ if (!parser_.opts.one_file)
+ cur_name_space_ = struct_def.defined_namespace;
+ GenStruct(struct_def, &declcode);
+ if (parser_.opts.one_file) {
+ one_file_code += declcode;
+ } else {
+ if (!SaveType(struct_def.name, *struct_def.defined_namespace, declcode,
+ true))
+ return false;
+ }
+ }
+
+ if (parser_.opts.one_file) {
+ return SaveType(file_name_, *parser_.current_namespace_, one_file_code,
+ true);
+ }
+ return true;
+ }
+
+ // Save out the generated code for a single class while adding
+ // declaration boilerplate.
+ bool SaveType(const std::string &defname, const Namespace &ns,
+ const std::string &classcode, bool needs_includes) const {
+ if (!classcode.length()) return true;
+
+ std::string code;
+ code = "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+
+ std::string namespace_name = FullNamespace(".", ns);
+ if (!namespace_name.empty()) {
+ code += "package " + namespace_name + ";";
+ code += "\n\n";
+ }
+ if (needs_includes) {
+ code +=
+ "import java.nio.*;\nimport java.lang.*;\nimport "
+ "java.util.*;\nimport com.google.flatbuffers.*;\n";
+ if (parser_.opts.gen_nullable) {
+ code += "\nimport javax.annotation.Nullable;\n";
+ }
+ if (parser_.opts.java_checkerframework) {
+ code += "\nimport org.checkerframework.dataflow.qual.Pure;\n";
+ }
+ code += "\n@SuppressWarnings(\"unused\")\n";
+ }
+ if (parser_.opts.gen_generated) {
+ code += "\n@javax.annotation.Generated(value=\"flatc\")\n";
+ }
+ code += classcode;
+ if (!namespace_name.empty()) code += "";
+ auto filename = NamespaceDir(ns) + defname + ".java";
+ return SaveFile(filename.c_str(), code, false);
+ }
+
+ const Namespace *CurrentNameSpace() const { return cur_name_space_; }
+
+ std::string GenNullableAnnotation(const Type &t) const {
+ return parser_.opts.gen_nullable &&
+ !IsScalar(DestinationType(t, true).base_type) &&
+ t.base_type != BASE_TYPE_VECTOR
+ ? " @Nullable "
+ : "";
+ }
+
+ std::string GenPureAnnotation(const Type &t) const {
+ return parser_.opts.java_checkerframework &&
+ !IsScalar(DestinationType(t, true).base_type)
+ ? " @Pure "
+ : "";
+ }
+
+ std::string GenTypeBasic(const Type &type) const {
+ // clang-format off
+ static const char * const java_typename[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, ...) \
+ #JTYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ };
+ // clang-format on
+ return java_typename[type.base_type];
+ }
+
+ std::string GenTypePointer(const Type &type) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "String";
+ case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+ case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
+ case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // else fall thru
+ default: return "Table";
+ }
+ }
+
+ std::string GenTypeGet(const Type &type) const {
+ return IsScalar(type.base_type)
+ ? GenTypeBasic(type)
+ : (IsArray(type) ? GenTypeGet(type.VectorType())
+ : GenTypePointer(type));
+ }
+
+ // Find the destination type the user wants to receive the value in (e.g.
+ // one size higher signed types for unsigned serialized values in Java).
+ Type DestinationType(const Type &type, bool vectorelem) const {
+ switch (type.base_type) {
+ // We use int for both uchar/ushort, since that generally means less
+ // casting than using short for uchar.
+ case BASE_TYPE_UCHAR: return Type(BASE_TYPE_INT);
+ case BASE_TYPE_USHORT: return Type(BASE_TYPE_INT);
+ case BASE_TYPE_UINT: return Type(BASE_TYPE_LONG);
+ case BASE_TYPE_ARRAY:
+ case BASE_TYPE_VECTOR:
+ if (vectorelem) return DestinationType(type.VectorType(), vectorelem);
+ FLATBUFFERS_FALLTHROUGH(); // else fall thru
+ default: return type;
+ }
+ }
+
+ std::string GenOffsetType() const { return "int"; }
+
+ std::string GenOffsetConstruct(const std::string &variable_name) const {
+ return variable_name;
+ }
+
+ std::string GenVectorOffsetType() const { return "int"; }
+
+ // Generate destination type name
+ std::string GenTypeNameDest(const Type &type) const {
+ return GenTypeGet(DestinationType(type, true));
+ }
+
+ // Mask to turn serialized value into destination type value.
+ std::string DestinationMask(const Type &type, bool vectorelem) const {
+ switch (type.base_type) {
+ case BASE_TYPE_UCHAR: return " & 0xFF";
+ case BASE_TYPE_USHORT: return " & 0xFFFF";
+ case BASE_TYPE_UINT: return " & 0xFFFFFFFFL";
+ case BASE_TYPE_VECTOR:
+ if (vectorelem) return DestinationMask(type.VectorType(), vectorelem);
+ FLATBUFFERS_FALLTHROUGH(); // else fall thru
+ default: return "";
+ }
+ }
+
+ // Casts necessary to correctly read serialized data
+ std::string DestinationCast(const Type &type) const {
+ if (IsSeries(type)) {
+ return DestinationCast(type.VectorType());
+ } else {
+ // Cast necessary to correctly read serialized unsigned values.
+ if (type.base_type == BASE_TYPE_UINT) return "(long)";
+ }
+ return "";
+ }
+
+ // Cast statements for mutator method parameters.
+ // In Java, parameters representing unsigned numbers need to be cast down to
+ // their respective type. For example, a long holding an unsigned int value
+ // would be cast down to int before being put onto the buffer. In C#, one cast
+ // directly cast an Enum to its underlying type, which is essential before
+ // putting it onto the buffer.
+ std::string SourceCast(const Type &type, bool castFromDest) const {
+ if (IsSeries(type)) {
+ return SourceCast(type.VectorType(), castFromDest);
+ } else {
+ if (castFromDest) {
+ if (type.base_type == BASE_TYPE_UINT)
+ return "(int)";
+ else if (type.base_type == BASE_TYPE_USHORT)
+ return "(short)";
+ else if (type.base_type == BASE_TYPE_UCHAR)
+ return "(byte)";
+ }
+ }
+ return "";
+ }
+
+ std::string SourceCast(const Type &type) const {
+ return SourceCast(type, true);
+ }
+
+ std::string SourceCastBasic(const Type &type, bool castFromDest) const {
+ return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : "";
+ }
+
+ std::string SourceCastBasic(const Type &type) const {
+ return SourceCastBasic(type, true);
+ }
+
+ std::string GenEnumDefaultValue(const FieldDef &field) const {
+ auto &value = field.value;
+ FLATBUFFERS_ASSERT(value.type.enum_def);
+ auto &enum_def = *value.type.enum_def;
+ auto enum_val = enum_def.FindByValue(value.constant);
+ return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
+ : value.constant;
+ }
+
+ std::string GenDefaultValue(const FieldDef &field) const {
+ auto &value = field.value;
+ auto longSuffix = "L";
+ switch (value.type.base_type) {
+ case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
+ case BASE_TYPE_ULONG: {
+ // Converts the ulong into its bits signed equivalent
+ uint64_t defaultValue = StringToUInt(value.constant.c_str());
+ return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix;
+ }
+ case BASE_TYPE_UINT:
+ case BASE_TYPE_LONG: return value.constant + longSuffix;
+ default:
+ if (IsFloat(value.type.base_type))
+ return JavaFloatGen.GenFloatConstant(field);
+ else
+ return value.constant;
+ }
+ }
+
+ std::string GenDefaultValueBasic(const FieldDef &field) const {
+ auto &value = field.value;
+ if (!IsScalar(value.type.base_type)) { return "0"; }
+ return GenDefaultValue(field);
+ }
+
+ void GenEnum(EnumDef &enum_def, std::string *code_ptr) const {
+ std::string &code = *code_ptr;
+ if (enum_def.generated) return;
+
+ // Generate enum definitions of the form:
+ // public static (final) int name = value;
+ // In Java, we use ints rather than the Enum feature, because we want them
+ // to map directly to how they're used in C/C++ and file formats.
+ // That, and Java Enums are expensive, and not universally liked.
+ GenComment(enum_def.doc_comment, code_ptr, &comment_config);
+
+ if (enum_def.attributes.Lookup("private")) {
+ // For Java, we leave the enum unmarked to indicate package-private
+ // For C# we mark the enum as internal
+ } else {
+ code += "public ";
+ }
+ code += "final class " + enum_def.name;
+ code += " {\n";
+ code += " private " + enum_def.name + "() { }\n";
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ auto &ev = **it;
+ GenComment(ev.doc_comment, code_ptr, &comment_config, " ");
+ code += " public static final ";
+ code += GenTypeBasic(enum_def.underlying_type);
+ code += " ";
+ code += ev.name + " = ";
+ code += enum_def.ToString(ev);
+ code += ";\n";
+ }
+
+ // Generate a generate string table for enum values.
+ // We do not do that for C# where this functionality is native.
+ // Problem is, if values are very sparse that could generate really big
+ // tables. Ideally in that case we generate a map lookup instead, but for
+ // the moment we simply don't output a table at all.
+ auto range = enum_def.Distance();
+ // Average distance between values above which we consider a table
+ // "too sparse". Change at will.
+ static const uint64_t kMaxSparseness = 5;
+ if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+ code += "\n public static final String";
+ code += "[] names = { ";
+ auto val = enum_def.Vals().front();
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
+ ++it) {
+ auto ev = *it;
+ for (auto k = enum_def.Distance(val, ev); k > 1; --k) code += "\"\", ";
+ val = ev;
+ code += "\"" + (*it)->name + "\", ";
+ }
+ code += "};\n\n";
+ code += " public static ";
+ code += "String";
+ code += " " + MakeCamel("name", false);
+ code += "(int e) { return names[e";
+ if (enum_def.MinValue()->IsNonZero())
+ code += " - " + enum_def.MinValue()->name;
+ code += "]; }\n";
+ }
+
+ // Close the class
+ code += "}";
+ // Java does not need the closing semi-colon on class definitions.
+ code += "";
+ code += "\n\n";
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string GenGetter(const Type &type) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "__string";
+ case BASE_TYPE_STRUCT: return "__struct";
+ case BASE_TYPE_UNION: return "__union";
+ case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
+ case BASE_TYPE_ARRAY: return GenGetter(type.VectorType());
+ default: {
+ std::string getter = "bb.get";
+ if (type.base_type == BASE_TYPE_BOOL) {
+ getter = "0!=" + getter;
+ } else if (GenTypeBasic(type) != "byte") {
+ getter += MakeCamel(GenTypeBasic(type));
+ }
+ return getter;
+ }
+ }
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string GenGetterForLookupByKey(flatbuffers::FieldDef *key_field,
+ const std::string &data_buffer,
+ const char *num = nullptr) const {
+ auto type = key_field->value.type;
+ auto dest_mask = DestinationMask(type, true);
+ auto dest_cast = DestinationCast(type);
+ auto getter = data_buffer + ".get";
+ if (GenTypeBasic(type) != "byte") {
+ getter += MakeCamel(GenTypeBasic(type));
+ }
+ getter = dest_cast + getter + "(" + GenOffsetGetter(key_field, num) + ")" +
+ dest_mask;
+ return getter;
+ }
+
+ // Direct mutation is only allowed for scalar fields.
+ // Hence a setter method will only be generated for such fields.
+ std::string GenSetter(const Type &type) const {
+ if (IsScalar(type.base_type)) {
+ std::string setter = "bb.put";
+ if (GenTypeBasic(type) != "byte" && type.base_type != BASE_TYPE_BOOL) {
+ setter += MakeCamel(GenTypeBasic(type));
+ }
+ return setter;
+ } else {
+ return "";
+ }
+ }
+
+ // Returns the method name for use with add/put calls.
+ std::string GenMethod(const Type &type) const {
+ return IsScalar(type.base_type) ? MakeCamel(GenTypeBasic(type))
+ : (IsStruct(type) ? "Struct" : "Offset");
+ }
+
+ // Recursively generate arguments for a constructor, to deal with nested
+ // structs.
+ void GenStructArgs(const StructDef &struct_def, std::string *code_ptr,
+ const char *nameprefix, size_t array_count = 0) const {
+ std::string &code = *code_ptr;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ const auto &field_type = field.value.type;
+ const auto array_field = IsArray(field_type);
+ const auto &type = array_field ? field_type.VectorType()
+ : DestinationType(field_type, false);
+ const auto array_cnt = array_field ? (array_count + 1) : array_count;
+ if (IsStruct(type)) {
+ // Generate arguments for a struct inside a struct. To ensure names
+ // don't clash, and to make it obvious these arguments are constructing
+ // a nested struct, prefix the name with the field name.
+ GenStructArgs(*field_type.struct_def, code_ptr,
+ (nameprefix + (field.name + "_")).c_str(), array_cnt);
+ } else {
+ code += ", ";
+ code += GenTypeBasic(type);
+ for (size_t i = 0; i < array_cnt; i++) code += "[]";
+ code += " ";
+ code += nameprefix;
+ code += MakeCamel(field.name, false);
+ }
+ }
+ }
+
+ // Recusively generate struct construction statements of the form:
+ // builder.putType(name);
+ // and insert manual padding.
+ void GenStructBody(const StructDef &struct_def, std::string *code_ptr,
+ const char *nameprefix, size_t index = 0,
+ bool in_array = false) const {
+ std::string &code = *code_ptr;
+ std::string indent((index + 1) * 2, ' ');
+ code += indent + " builder.prep(";
+ code += NumToString(struct_def.minalign) + ", ";
+ code += NumToString(struct_def.bytesize) + ");\n";
+ for (auto it = struct_def.fields.vec.rbegin();
+ it != struct_def.fields.vec.rend(); ++it) {
+ auto &field = **it;
+ const auto &field_type = field.value.type;
+ if (field.padding) {
+ code += indent + " builder.pad(";
+ code += NumToString(field.padding) + ");\n";
+ }
+ if (IsStruct(field_type)) {
+ GenStructBody(*field_type.struct_def, code_ptr,
+ (nameprefix + (field.name + "_")).c_str(), index,
+ in_array);
+ } else {
+ const auto &type =
+ IsArray(field_type) ? field_type.VectorType() : field_type;
+ const auto index_var = "_idx" + NumToString(index);
+ if (IsArray(field_type)) {
+ code += indent + " for (int " + index_var + " = ";
+ code += NumToString(field_type.fixed_length);
+ code += "; " + index_var + " > 0; " + index_var + "--) {\n";
+ in_array = true;
+ }
+ if (IsStruct(type)) {
+ GenStructBody(*field_type.struct_def, code_ptr,
+ (nameprefix + (field.name + "_")).c_str(), index + 1,
+ in_array);
+ } else {
+ code += IsArray(field_type) ? " " : "";
+ code += indent + " builder.put";
+ code += GenMethod(type) + "(";
+ code += SourceCast(type);
+ auto argname = nameprefix + MakeCamel(field.name, false);
+ code += argname;
+ size_t array_cnt = index + (IsArray(field_type) ? 1 : 0);
+ for (size_t i = 0; in_array && i < array_cnt; i++) {
+ code += "[_idx" + NumToString(i) + "-1]";
+ }
+ code += ");\n";
+ }
+ if (IsArray(field_type)) { code += indent + " }\n"; }
+ }
+ }
+ }
+
+ std::string GenByteBufferLength(const char *bb_name) const {
+ std::string bb_len = bb_name;
+ bb_len += ".capacity()";
+ return bb_len;
+ }
+
+ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
+ const char *num = nullptr) const {
+ std::string key_offset = "";
+ key_offset += "__offset(" + NumToString(key_field->value.offset) + ", ";
+ if (num) {
+ key_offset += num;
+ key_offset += ", _bb)";
+ } else {
+ key_offset += GenByteBufferLength("bb");
+ key_offset += " - tableOffset, bb)";
+ }
+ return key_offset;
+ }
+
+ std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) const {
+ std::string key_getter = " ";
+ key_getter += "int tableOffset = ";
+ key_getter += "__indirect(vectorLocation + 4 * (start + middle)";
+ key_getter += ", bb);\n ";
+ if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+ key_getter += "int comp = ";
+ key_getter += "compareStrings(";
+ key_getter += GenOffsetGetter(key_field);
+ key_getter += ", byteKey, bb);\n";
+ } else {
+ auto get_val = GenGetterForLookupByKey(key_field, "bb");
+ key_getter += GenTypeNameDest(key_field->value.type) + " val = ";
+ key_getter += get_val + ";\n";
+ key_getter += " int comp = val > key ? 1 : val < key ? -1 : 0;\n";
+ }
+ return key_getter;
+ }
+
+ std::string GenKeyGetter(flatbuffers::FieldDef *key_field) const {
+ std::string key_getter = "";
+ auto data_buffer = "_bb";
+ if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+ key_getter += " return ";
+ key_getter += "";
+ key_getter += "compareStrings(";
+ key_getter += GenOffsetGetter(key_field, "o1") + ", ";
+ key_getter += GenOffsetGetter(key_field, "o2") + ", " + data_buffer + ")";
+ key_getter += ";";
+ } else {
+ auto field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o1");
+ key_getter +=
+ "\n " + GenTypeNameDest(key_field->value.type) + " val_1 = ";
+ key_getter +=
+ field_getter + ";\n " + GenTypeNameDest(key_field->value.type);
+ key_getter += " val_2 = ";
+ field_getter = GenGetterForLookupByKey(key_field, data_buffer, "o2");
+ key_getter += field_getter + ";\n";
+ key_getter += " return val_1 > val_2 ? 1 : val_1 < val_2 ? -1 : 0;\n ";
+ }
+ return key_getter;
+ }
+
+ void GenStruct(StructDef &struct_def, std::string *code_ptr) const {
+ if (struct_def.generated) return;
+ std::string &code = *code_ptr;
+
+ // Generate a struct accessor class, with methods of the form:
+ // public type name() { return bb.getType(i + offset); }
+ // or for tables of the form:
+ // public type name() {
+ // int o = __offset(offset); return o != 0 ? bb.getType(o + i) : default;
+ // }
+ GenComment(struct_def.doc_comment, code_ptr, &comment_config);
+ if (struct_def.attributes.Lookup("private")) {
+ // For Java, we leave the struct unmarked to indicate package-private
+ // For C# we mark the struct as internal
+ } else {
+ code += "public ";
+ }
+ code += "final ";
+ code += "class " + struct_def.name;
+ code += " extends ";
+ code += struct_def.fixed ? "Struct" : "Table";
+ code += " {\n";
+
+ if (!struct_def.fixed) {
+ // Generate verson check method.
+ // Force compile time error if not using the same version runtime.
+ code += " public static void ValidateVersion() {";
+ code += " Constants.";
+ code += "FLATBUFFERS_1_12_0(); ";
+ code += "}\n";
+
+ // Generate a special accessor for the table that when used as the root
+ // of a FlatBuffer
+ std::string method_name = "getRootAs" + struct_def.name;
+ std::string method_signature =
+ " public static " + struct_def.name + " " + method_name;
+
+ // create convenience method that doesn't require an existing object
+ code += method_signature + "(ByteBuffer _bb) ";
+ code += "{ return " + method_name + "(_bb, new " + struct_def.name +
+ "()); }\n";
+
+ // create method that allows object reuse
+ code +=
+ method_signature + "(ByteBuffer _bb, " + struct_def.name + " obj) { ";
+ code += "_bb.order(ByteOrder.LITTLE_ENDIAN); ";
+ code += "return (obj.__assign(_bb.getInt(_bb.";
+ code += "position()";
+ code += ") + _bb.";
+ code += "position()";
+ code += ", _bb)); }\n";
+ if (parser_.root_struct_def_ == &struct_def) {
+ if (parser_.file_identifier_.length()) {
+ // Check if a buffer has the identifier.
+ code += " public static ";
+ code += "boolean " + struct_def.name;
+ code += "BufferHasIdentifier(ByteBuffer _bb) { return ";
+ code += "__has_identifier(_bb, \"";
+ code += parser_.file_identifier_;
+ code += "\"); }\n";
+ }
+ }
+ }
+ // Generate the __init method that sets the field in a pre-existing
+ // accessor object. This is to allow object reuse.
+ code += " public void __init(int _i, ByteBuffer _bb) ";
+ code += "{ ";
+ code += "__reset(_i, _bb); ";
+ code += "}\n";
+ code +=
+ " public " + struct_def.name + " __assign(int _i, ByteBuffer _bb) ";
+ code += "{ __init(_i, _bb); return this; }\n\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ GenComment(field.doc_comment, code_ptr, &comment_config, " ");
+ std::string type_name = GenTypeGet(field.value.type);
+ std::string type_name_dest = GenTypeNameDest(field.value.type);
+ std::string conditional_cast = "";
+ std::string optional = "";
+ std::string dest_mask = DestinationMask(field.value.type, true);
+ std::string dest_cast = DestinationCast(field.value.type);
+ std::string src_cast = SourceCast(field.value.type);
+ std::string method_start =
+ " public " +
+ (field.required ? "" : GenNullableAnnotation(field.value.type)) +
+ GenPureAnnotation(field.value.type) + type_name_dest + optional +
+ " " + MakeCamel(field.name, false);
+ std::string obj = "obj";
+
+ // Most field accessors need to retrieve and test the field offset first,
+ // this is the prefix code for that:
+ auto offset_prefix =
+ IsArray(field.value.type)
+ ? " { return "
+ : (" { int o = __offset(" + NumToString(field.value.offset) +
+ "); return o != 0 ? ");
+ // Generate the accessors that don't do object reuse.
+ if (field.value.type.base_type == BASE_TYPE_STRUCT) {
+ // Calls the accessor that takes an accessor object with a new object.
+ code += method_start + "() { return ";
+ code += MakeCamel(field.name, false);
+ code += "(new ";
+ code += type_name + "()); }\n";
+ } else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
+ field.value.type.element == BASE_TYPE_STRUCT) {
+ // Accessors for vectors of structs also take accessor objects, this
+ // generates a variant without that argument.
+ code += method_start + "(int j) { return ";
+ code += MakeCamel(field.name, false);
+ code += "(new " + type_name + "(), j); }\n";
+ }
+
+ std::string getter = dest_cast + GenGetter(field.value.type);
+ code += method_start;
+ std::string default_cast = "";
+ std::string member_suffix = "; ";
+ if (IsScalar(field.value.type.base_type)) {
+ code += "()";
+ member_suffix += "";
+ if (struct_def.fixed) {
+ code += " { return " + getter;
+ code += "(bb_pos + ";
+ code += NumToString(field.value.offset) + ")";
+ code += dest_mask;
+ } else {
+ code += offset_prefix + getter;
+ code += "(o + bb_pos)" + dest_mask;
+ code += " : " + default_cast;
+ code += GenDefaultValue(field);
+ }
+ } else {
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT:
+ code += "(" + type_name + " obj)";
+ if (struct_def.fixed) {
+ code += " { return " + obj + ".__assign(";
+ code += "bb_pos + " + NumToString(field.value.offset) + ", ";
+ code += "bb)";
+ } else {
+ code += offset_prefix + conditional_cast;
+ code += obj + ".__assign(";
+ code += field.value.type.struct_def->fixed
+ ? "o + bb_pos"
+ : "__indirect(o + bb_pos)";
+ code += ", bb) : null";
+ }
+ break;
+ case BASE_TYPE_STRING:
+ code += "()";
+ member_suffix += "";
+ code += offset_prefix + getter + "(o + ";
+ code += "bb_pos) : null";
+ break;
+ case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_VECTOR: {
+ auto vectortype = field.value.type.VectorType();
+ code += "(";
+ if (vectortype.base_type == BASE_TYPE_STRUCT) {
+ code += type_name + " obj, ";
+ getter = obj + ".__assign";
+ } else if (vectortype.base_type == BASE_TYPE_UNION) {
+ code += type_name + " obj, ";
+ }
+ code += "int j)";
+ const auto body = offset_prefix + conditional_cast + getter + "(";
+ if (vectortype.base_type == BASE_TYPE_UNION) {
+ code += body + "obj, ";
+ } else {
+ code += body;
+ }
+ std::string index;
+ if (IsArray(field.value.type)) {
+ index += "bb_pos + " + NumToString(field.value.offset) + " + ";
+ } else {
+ index += "__vector(o) + ";
+ }
+ index += "j * " + NumToString(InlineSize(vectortype));
+ if (vectortype.base_type == BASE_TYPE_STRUCT) {
+ code += vectortype.struct_def->fixed
+ ? index
+ : "__indirect(" + index + ")";
+ code += ", bb";
+ } else {
+ code += index;
+ }
+ code += ")" + dest_mask;
+ if (!IsArray(field.value.type)) {
+ code += " : ";
+ code +=
+ field.value.type.element == BASE_TYPE_BOOL
+ ? "false"
+ : (IsScalar(field.value.type.element) ? default_cast + "0"
+ : "null");
+ }
+
+ break;
+ }
+ case BASE_TYPE_UNION:
+ code += "(" + type_name + " obj)" + offset_prefix + getter;
+ code += "(obj, o + bb_pos) : null";
+ break;
+ default: FLATBUFFERS_ASSERT(0);
+ }
+ }
+ code += member_suffix;
+ code += "}\n";
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ code += " public int " + MakeCamel(field.name, false);
+ code += "Length";
+ code += "()";
+ code += offset_prefix;
+ code += "__vector_len(o) : 0; ";
+ code += "";
+ code += "}\n";
+ // See if we should generate a by-key accessor.
+ if (field.value.type.element == BASE_TYPE_STRUCT &&
+ !field.value.type.struct_def->fixed) {
+ auto &sd = *field.value.type.struct_def;
+ auto &fields = sd.fields.vec;
+ for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+ auto &key_field = **kit;
+ if (key_field.key) {
+ auto qualified_name = WrapInNameSpace(sd);
+ code += " public " + qualified_name + " ";
+ code += MakeCamel(field.name, false) + "ByKey(";
+ code += GenTypeNameDest(key_field.value.type) + " key)";
+ code += offset_prefix;
+ code += qualified_name + ".__lookup_by_key(";
+ code += "null, ";
+ code += "__vector(o), key, ";
+ code += "bb) : null; ";
+ code += "}\n";
+ code += " public " + qualified_name + " ";
+ code += MakeCamel(field.name, false) + "ByKey(";
+ code += qualified_name + " obj, ";
+ code += GenTypeNameDest(key_field.value.type) + " key)";
+ code += offset_prefix;
+ code += qualified_name + ".__lookup_by_key(obj, ";
+ code += "__vector(o), key, ";
+ code += "bb) : null; ";
+ code += "}\n";
+ break;
+ }
+ }
+ }
+ }
+ // Generate the accessors for vector of structs with vector access object
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ std::string vector_type_name;
+ const auto &element_base_type = field.value.type.VectorType().base_type;
+ if (IsScalar(element_base_type)) {
+ vector_type_name = MakeCamel(type_name, true) + "Vector";
+ } else if (element_base_type == BASE_TYPE_STRING) {
+ vector_type_name = "StringVector";
+ } else if (element_base_type == BASE_TYPE_UNION) {
+ vector_type_name = "UnionVector";
+ } else {
+ vector_type_name = type_name + ".Vector";
+ }
+ auto vector_method_start = GenNullableAnnotation(field.value.type) +
+ " public " + vector_type_name + optional +
+ " " + MakeCamel(field.name, false) +
+ "Vector";
+ code += vector_method_start + "() { return ";
+ code += MakeCamel(field.name, false) + "Vector";
+ code += "(new " + vector_type_name + "()); }\n";
+ code += vector_method_start + "(" + vector_type_name + " obj)";
+ code += offset_prefix + conditional_cast + obj + ".__assign(";
+ code += "__vector(o), ";
+ if (!IsScalar(element_base_type)) {
+ auto vectortype = field.value.type.VectorType();
+ code += NumToString(InlineSize(vectortype)) + ", ";
+ }
+ code += "bb) : null" + member_suffix + "}\n";
+ }
+ // Generate a ByteBuffer accessor for strings & vectors of scalars.
+ if ((field.value.type.base_type == BASE_TYPE_VECTOR &&
+ IsScalar(field.value.type.VectorType().base_type)) ||
+ field.value.type.base_type == BASE_TYPE_STRING) {
+ code += " public ByteBuffer ";
+ code += MakeCamel(field.name, false);
+ code += "AsByteBuffer() { return ";
+ code += "__vector_as_bytebuffer(";
+ code += NumToString(field.value.offset) + ", ";
+ code += NumToString(field.value.type.base_type == BASE_TYPE_STRING
+ ? 1
+ : InlineSize(field.value.type.VectorType()));
+ code += "); }\n";
+ code += " public ByteBuffer ";
+ code += MakeCamel(field.name, false);
+ code += "InByteBuffer(ByteBuffer _bb) { return ";
+ code += "__vector_in_bytebuffer(_bb, ";
+ code += NumToString(field.value.offset) + ", ";
+ code += NumToString(field.value.type.base_type == BASE_TYPE_STRING
+ ? 1
+ : InlineSize(field.value.type.VectorType()));
+ code += "); }\n";
+ }
+ // generate object accessors if is nested_flatbuffer
+ if (field.nested_flatbuffer) {
+ auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
+ auto nested_method_name =
+ MakeCamel(field.name, false) + "As" + field.nested_flatbuffer->name;
+ auto get_nested_method_name = nested_method_name;
+ code += " public " + nested_type_name + " ";
+ code += nested_method_name + "() { return ";
+ code +=
+ get_nested_method_name + "(new " + nested_type_name + "()); }\n";
+ code += " public " + nested_type_name + " ";
+ code += get_nested_method_name + "(";
+ code += nested_type_name + " obj";
+ code += ") { int o = __offset(";
+ code += NumToString(field.value.offset) + "); ";
+ code += "return o != 0 ? " + conditional_cast + obj + ".__assign(";
+ code += "";
+ code += "__indirect(__vector(o)), ";
+ code += "bb) : null; }\n";
+ }
+ // Generate mutators for scalar fields or vectors of scalars.
+ if (parser_.opts.mutable_buffer) {
+ auto is_series = (IsSeries(field.value.type));
+ const auto &underlying_type =
+ is_series ? field.value.type.VectorType() : field.value.type;
+ // Boolean parameters have to be explicitly converted to byte
+ // representation.
+ auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL
+ ? "(byte)(" + field.name + " ? 1 : 0)"
+ : field.name;
+ auto mutator_prefix = MakeCamel("mutate", false);
+ // A vector mutator also needs the index of the vector element it should
+ // mutate.
+ auto mutator_params = (is_series ? "(int j, " : "(") +
+ GenTypeNameDest(underlying_type) + " " +
+ field.name + ") { ";
+ auto setter_index =
+ is_series
+ ? (IsArray(field.value.type)
+ ? "bb_pos + " + NumToString(field.value.offset)
+ : "__vector(o)") +
+ +" + j * " + NumToString(InlineSize(underlying_type))
+ : (struct_def.fixed
+ ? "bb_pos + " + NumToString(field.value.offset)
+ : "o + bb_pos");
+ if (IsScalar(underlying_type.base_type) && !IsUnion(field.value.type)) {
+ code += " public ";
+ code += struct_def.fixed ? "void " : "boolean ";
+ code += mutator_prefix + MakeCamel(field.name, true);
+ code += mutator_params;
+ if (struct_def.fixed) {
+ code += GenSetter(underlying_type) + "(" + setter_index + ", ";
+ code += src_cast + setter_parameter + "); }\n";
+ } else {
+ code += "int o = __offset(";
+ code += NumToString(field.value.offset) + ");";
+ code += " if (o != 0) { " + GenSetter(underlying_type);
+ code += "(" + setter_index + ", " + src_cast + setter_parameter +
+ "); return true; } else { return false; } }\n";
+ }
+ }
+ }
+ if (parser_.opts.java_primitive_has_method &&
+ IsScalar(field.value.type.base_type) && !struct_def.fixed) {
+ auto vt_offset_constant = " public static final int VT_" +
+ MakeScreamingCamel(field.name) + " = " +
+ NumToString(field.value.offset) + ";";
+
+ code += vt_offset_constant;
+ code += "\n";
+ }
+ }
+ code += "\n";
+ flatbuffers::FieldDef *key_field = nullptr;
+ if (struct_def.fixed) {
+ // create a struct constructor function
+ code += " public static " + GenOffsetType() + " ";
+ code += "create";
+ code += struct_def.name + "(FlatBufferBuilder builder";
+ GenStructArgs(struct_def, code_ptr, "");
+ code += ") {\n";
+ GenStructBody(struct_def, code_ptr, "");
+ code += " return ";
+ code += GenOffsetConstruct("builder." + std::string("offset()"));
+ code += ";\n }\n";
+ } else {
+ // Generate a method that creates a table in one go. This is only possible
+ // when the table has no struct fields, since those have to be created
+ // inline, and there's no way to do so in Java.
+ bool has_no_struct_fields = true;
+ int num_fields = 0;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (IsStruct(field.value.type)) {
+ has_no_struct_fields = false;
+ } else {
+ num_fields++;
+ }
+ }
+ // JVM specifications restrict default constructor params to be < 255.
+ // Longs and doubles take up 2 units, so we set the limit to be < 127.
+ if (has_no_struct_fields && num_fields && num_fields < 127) {
+ // Generate a table constructor of the form:
+ // public static int createName(FlatBufferBuilder builder, args...)
+ code += " public static " + GenOffsetType() + " ";
+ code += "create" + struct_def.name;
+ code += "(FlatBufferBuilder builder";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ code += ",\n ";
+ code += GenTypeBasic(DestinationType(field.value.type, false));
+ code += " ";
+ code += field.name;
+ if (!IsScalar(field.value.type.base_type)) code += "Offset";
+ }
+ code += ") {\n builder.";
+ code += "startTable(";
+ code += NumToString(struct_def.fields.vec.size()) + ");\n";
+ for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1;
+ size; size /= 2) {
+ for (auto it = struct_def.fields.vec.rbegin();
+ it != struct_def.fields.vec.rend(); ++it) {
+ auto &field = **it;
+ if (!field.deprecated &&
+ (!struct_def.sortbysize ||
+ size == SizeOf(field.value.type.base_type))) {
+ code += " " + struct_def.name + ".";
+ code += "add";
+ code += MakeCamel(field.name) + "(builder, " + field.name;
+ if (!IsScalar(field.value.type.base_type)) code += "Offset";
+ code += ");\n";
+ }
+ }
+ }
+ code += " return " + struct_def.name + ".";
+ code += "end" + struct_def.name;
+ code += "(builder);\n }\n\n";
+ }
+ // Generate a set of static methods that allow table construction,
+ // of the form:
+ // public static void addName(FlatBufferBuilder builder, short name)
+ // { builder.addShort(id, name, default); }
+ // Unlike the Create function, these always work.
+ code += " public static void start";
+ code += struct_def.name;
+ code += "(FlatBufferBuilder builder) { builder.";
+ code += "startTable(";
+ code += NumToString(struct_def.fields.vec.size()) + "); }\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (field.key) key_field = &field;
+ code += " public static void add";
+ code += MakeCamel(field.name);
+ code += "(FlatBufferBuilder builder, ";
+ code += GenTypeBasic(DestinationType(field.value.type, false));
+ auto argname = MakeCamel(field.name, false);
+ if (!IsScalar(field.value.type.base_type)) argname += "Offset";
+ code += " " + argname + ") { builder.add";
+ code += GenMethod(field.value.type) + "(";
+ code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
+ code += SourceCastBasic(field.value.type);
+ code += argname;
+ code += ", ";
+ code += SourceCastBasic(field.value.type);
+ code += GenDefaultValue(field);
+ code += "); }\n";
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ auto vector_type = field.value.type.VectorType();
+ auto alignment = InlineAlignment(vector_type);
+ auto elem_size = InlineSize(vector_type);
+ if (!IsStruct(vector_type)) {
+ // generate a method to create a vector from a java array.
+ if ((vector_type.base_type == BASE_TYPE_CHAR ||
+ vector_type.base_type == BASE_TYPE_UCHAR)) {
+ // Handle byte[] and ByteBuffers separately for Java
+ code += " public static " + GenVectorOffsetType() + " ";
+ code += "create";
+ code += MakeCamel(field.name);
+ code += "Vector(FlatBufferBuilder builder, byte[] data) ";
+ code += "{ return builder.createByteVector(data); }\n";
+
+ code += " public static " + GenVectorOffsetType() + " ";
+ code += "create";
+ code += MakeCamel(field.name);
+ code += "Vector(FlatBufferBuilder builder, ByteBuffer data) ";
+ code += "{ return builder.createByteVector(data); }\n";
+ } else {
+ code += " public static " + GenVectorOffsetType() + " ";
+ code += "create";
+ code += MakeCamel(field.name);
+ code += "Vector(FlatBufferBuilder builder, ";
+ code += GenTypeBasic(vector_type) + "[] data) ";
+ code += "{ builder.startVector(";
+ code += NumToString(elem_size);
+ code += ", data.length, ";
+ code += NumToString(alignment);
+ code += "); for (int i = data.";
+ code += "length - 1; i >= 0; i--) builder.";
+ code += "add";
+ code += GenMethod(vector_type);
+ code += "(";
+ code += SourceCastBasic(vector_type, false);
+ code += "data[i]";
+ code += "); return ";
+ code += "builder.endVector(); }\n";
+ }
+ }
+ // Generate a method to start a vector, data to be added manually
+ // after.
+ code += " public static void start";
+ code += MakeCamel(field.name);
+ code += "Vector(FlatBufferBuilder builder, int numElems) ";
+ code += "{ builder.startVector(";
+ code += NumToString(elem_size);
+ code += ", numElems, " + NumToString(alignment);
+ code += "); }\n";
+ }
+ }
+ code += " public static " + GenOffsetType() + " ";
+ code += "end" + struct_def.name;
+ code += "(FlatBufferBuilder builder) {\n int o = builder.";
+ code += "endTable();\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (!field.deprecated && field.required) {
+ code += " builder.required(o, ";
+ code += NumToString(field.value.offset);
+ code += "); // " + field.name + "\n";
+ }
+ }
+ code += " return " + GenOffsetConstruct("o") + ";\n }\n";
+ if (parser_.root_struct_def_ == &struct_def) {
+ std::string size_prefix[] = { "", "SizePrefixed" };
+ for (int i = 0; i < 2; ++i) {
+ code += " public static void ";
+ code += "finish" + size_prefix[i] + struct_def.name;
+ code += "Buffer(FlatBufferBuilder builder, " + GenOffsetType();
+ code += " offset) {";
+ code += " builder.finish" + size_prefix[i] + "(offset";
+
+ if (parser_.file_identifier_.length())
+ code += ", \"" + parser_.file_identifier_ + "\"";
+ code += "); }\n";
+ }
+ }
+ }
+ // Only generate key compare function for table,
+ // because `key_field` is not set for struct
+ if (struct_def.has_key && !struct_def.fixed) {
+ FLATBUFFERS_ASSERT(key_field);
+ code += "\n @Override\n protected int keysCompare(";
+ code += "Integer o1, Integer o2, ByteBuffer _bb) {";
+ code += GenKeyGetter(key_field);
+ code += " }\n";
+
+ code += "\n public static " + struct_def.name;
+ code += " __lookup_by_key(";
+ code += struct_def.name + " obj, ";
+ code += "int vectorLocation, ";
+ code += GenTypeNameDest(key_field->value.type);
+ code += " key, ByteBuffer bb) {\n";
+ if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+ code += " byte[] byteKey = ";
+ code += "key.getBytes(java.nio.charset.StandardCharsets.UTF_8);\n";
+ }
+ code += " int span = ";
+ code += "bb.getInt(vectorLocation - 4);\n";
+ code += " int start = 0;\n";
+ code += " while (span != 0) {\n";
+ code += " int middle = span / 2;\n";
+ code += GenLookupKeyGetter(key_field);
+ code += " if (comp > 0) {\n";
+ code += " span = middle;\n";
+ code += " } else if (comp < 0) {\n";
+ code += " middle++;\n";
+ code += " start += middle;\n";
+ code += " span -= middle;\n";
+ code += " } else {\n";
+ code += " return ";
+ code += "(obj == null ? new " + struct_def.name + "() : obj)";
+ code += ".__assign(tableOffset, bb);\n";
+ code += " }\n }\n";
+ code += " return null;\n";
+ code += " }\n";
+ }
+ GenVectorAccessObject(struct_def, code_ptr);
+ code += "}";
+ code += "\n\n";
+ }
+
+ void GenVectorAccessObject(StructDef &struct_def,
+ std::string *code_ptr) const {
+ auto &code = *code_ptr;
+ // Generate a vector of structs accessor class.
+ code += "\n";
+ code += " ";
+ if (!struct_def.attributes.Lookup("private")) code += "public ";
+ code += "static ";
+ code += "final ";
+ code += "class Vector extends ";
+ code += "BaseVector {\n";
+
+ // Generate the __assign method that sets the field in a pre-existing
+ // accessor object. This is to allow object reuse.
+ std::string method_indent = " ";
+ code += method_indent + "public Vector ";
+ code += "__assign(int _vector, int _element_size, ByteBuffer _bb) { ";
+ code += "__reset(_vector, _element_size, _bb); return this; }\n\n";
+
+ auto type_name = struct_def.name;
+ auto method_start = method_indent + "public " + type_name + " get";
+ // Generate the accessors that don't do object reuse.
+ code += method_start + "(int j) { return get";
+ code += "(new " + type_name + "(), j); }\n";
+ code += method_start + "(" + type_name + " obj, int j) { ";
+ code += " return obj.__assign(";
+ std::string index = "__element(j)";
+ code += struct_def.fixed ? index : "__indirect(" + index + ", bb)";
+ code += ", bb); }\n";
+ // See if we should generate a by-key accessor.
+ if (!struct_def.fixed) {
+ auto &fields = struct_def.fields.vec;
+ for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+ auto &key_field = **kit;
+ if (key_field.key) {
+ auto nullable_annotation =
+ parser_.opts.gen_nullable ? "@Nullable " : "";
+ code += method_indent + nullable_annotation;
+ code += "public " + type_name + " ";
+ code += "getByKey(";
+ code += GenTypeNameDest(key_field.value.type) + " key) { ";
+ code += " return __lookup_by_key(null, ";
+ code += "__vector(), key, ";
+ code += "bb); ";
+ code += "}\n";
+ code += method_indent + nullable_annotation;
+ code += "public " + type_name + " ";
+ code += "getByKey(";
+ code += type_name + " obj, ";
+ code += GenTypeNameDest(key_field.value.type) + " key) { ";
+ code += " return __lookup_by_key(obj, ";
+ code += "__vector(), key, ";
+ code += "bb); ";
+ code += "}\n";
+ break;
+ }
+ }
+ }
+ code += " }\n";
+ }
+
+ // This tracks the current namespace used to determine if a type need to be
+ // prefixed by its namespace
+ const Namespace *cur_name_space_;
+};
+} // namespace java
+
+bool GenerateJava(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ java::JavaGenerator generator(parser, path, file_name);
+ return generator.generate();
+}
+
+} // namespace flatbuffers
diff --git a/src/idl_gen_js_ts.cpp b/src/idl_gen_js_ts.cpp
index fea46208..030c5526 100644
--- a/src/idl_gen_js_ts.cpp
+++ b/src/idl_gen_js_ts.cpp
@@ -26,8 +26,6 @@
namespace flatbuffers {
-const std::string kGeneratedFileNamePostfix = "_generated";
-
struct JsTsLanguageParameters {
IDLOptions::Language language;
std::string file_extension;
@@ -61,12 +59,6 @@ const JsTsLanguageParameters &GetJsLangParams(IDLOptions::Language lang) {
}
}
-static std::string GeneratedFileName(const std::string &path,
- const std::string &file_name,
- const JsTsLanguageParameters &lang) {
- return path + file_name + kGeneratedFileNamePostfix + lang.file_extension;
-}
-
namespace jsts {
// Iterate through all definitions we haven't generate code for (enums, structs,
// and tables) and output them to a single file.
@@ -78,7 +70,8 @@ class JsTsGenerator : public BaseGenerator {
JsTsGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "", "."),
+ : BaseGenerator(parser, path, file_name, "", ".",
+ parser.opts.lang == IDLOptions::kJs ? "js" : "ts"),
lang_(GetJsLangParams(parser_.opts.lang)) {}
// Iterate through all definitions we haven't generate code for (enums,
// structs, and tables) and output them to a single file.
@@ -112,8 +105,8 @@ class JsTsGenerator : public BaseGenerator {
code += exports_code;
}
- return SaveFile(GeneratedFileName(path_, file_name_, lang_).c_str(), code,
- false);
+ return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(),
+ code, false);
}
private:
@@ -127,9 +120,7 @@ class JsTsGenerator : public BaseGenerator {
const auto &file = *it;
const auto basename =
flatbuffers::StripPath(flatbuffers::StripExtension(file));
- if (basename != file_name_) {
- code += GenPrefixedImport(file, basename);
- }
+ if (basename != file_name_) { code += GenPrefixedImport(file, basename); }
}
}
@@ -214,7 +205,7 @@ class JsTsGenerator : public BaseGenerator {
std::string &code = *code_ptr;
std::string &exports = *exports_ptr;
for (auto it = sorted_namespaces.begin(); it != sorted_namespaces.end();
- it++) {
+ ++it) {
if (lang_.language == IDLOptions::kTs) {
if (it->find('.') == std::string::npos) {
code += "import { flatbuffers } from \"./flatbuffers\"\n";
@@ -309,14 +300,12 @@ class JsTsGenerator : public BaseGenerator {
result += " " + type_name;
break;
}
- default: { result += " {" + type_name + "}"; }
- }
- if (!arg_name.empty()) {
- result += " " + arg_name;
- }
- if (include_newline) {
- result += "\n";
+ default: {
+ result += " {" + type_name + "}";
+ }
}
+ if (!arg_name.empty()) { result += " " + arg_name; }
+ if (include_newline) { result += "\n"; }
return result;
}
@@ -359,13 +348,13 @@ class JsTsGenerator : public BaseGenerator {
// Generate mapping between EnumName: EnumValue(int)
if (reverse) {
- code += " " + NumToString(ev.value);
+ code += " '" + enum_def.ToString(ev) + "'";
code += lang_.language == IDLOptions::kTs ? "= " : ": ";
code += "'" + ev.name + "'";
} else {
code += " " + ev.name;
code += lang_.language == IDLOptions::kTs ? "= " : ": ";
- code += NumToString(ev.value);
+ code += enum_def.ToString(ev);
}
code += (it + 1) != enum_def.Vals().end() ? ",\n" : "\n";
@@ -431,8 +420,7 @@ class JsTsGenerator : public BaseGenerator {
std::string GenDefaultValue(const Value &value, const std::string &context) {
if (value.type.enum_def) {
- if (auto val = value.type.enum_def->ReverseLookup(
- StringToInt(value.constant.c_str()), false)) {
+ if (auto val = value.type.enum_def->FindByValue(value.constant)) {
if (lang_.language == IDLOptions::kTs) {
return GenPrefixedTypeName(WrapInNameSpace(*value.type.enum_def),
value.type.enum_def->file) +
@@ -529,10 +517,10 @@ class JsTsGenerator : public BaseGenerator {
if (parser_.opts.keep_include_path) {
auto it = parser_.included_files_.find(full_file_name);
FLATBUFFERS_ASSERT(it != parser_.included_files_.end());
- path =
- flatbuffers::StripExtension(it->second) + kGeneratedFileNamePostfix;
+ path = flatbuffers::StripExtension(it->second) +
+ parser_.opts.filename_suffix;
} else {
- path = base_name + kGeneratedFileNamePostfix;
+ path = base_name + parser_.opts.filename_suffix;
}
// Add the include prefix and make the path always relative
@@ -605,6 +593,74 @@ class JsTsGenerator : public BaseGenerator {
}
}
+ std::string GenerateNewExpression(const std::string &object_name) {
+ return "new " + object_name +
+ (lang_.language == IDLOptions::kTs ? "()" : "");
+ }
+
+ void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
+ std::string &code, std::string &object_name,
+ bool size_prefixed) {
+ if (!struct_def.fixed) {
+ GenDocComment(code_ptr,
+ GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
+ GenTypeAnnotation(kParam, object_name + "=", "obj") +
+ GenTypeAnnotation(kReturns, object_name, "", false));
+ std::string sizePrefixed("SizePrefixed");
+ if (lang_.language == IDLOptions::kTs) {
+ code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" +
+ Verbose(struct_def, "As");
+ code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
+ "):" + object_name + " {\n";
+ } else {
+ code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") +
+ "Root" + Verbose(struct_def, "As");
+ code += " = function(bb, obj) {\n";
+ }
+ if (size_prefixed) {
+ code +=
+ " bb.setPosition(bb.position() + "
+ "flatbuffers.SIZE_PREFIX_LENGTH);\n";
+ }
+ code += " return (obj || " + GenerateNewExpression(object_name);
+ code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
+ code += "};\n\n";
+ }
+ }
+
+ void GenerateFinisher(StructDef &struct_def, std::string *code_ptr,
+ std::string &code, std::string &object_name,
+ bool size_prefixed) {
+ if (parser_.root_struct_def_ == &struct_def) {
+ std::string sizePrefixed("SizePrefixed");
+ GenDocComment(
+ code_ptr,
+ GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
+ GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset", false));
+
+ if (lang_.language == IDLOptions::kTs) {
+ code += "static finish" + (size_prefixed ? sizePrefixed : "") +
+ Verbose(struct_def) + "Buffer";
+ code += "(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
+ } else {
+ code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") +
+ Verbose(struct_def) + "Buffer";
+ code += " = function(builder, offset) {\n";
+ }
+
+ code += " builder.finish(offset";
+ if (!parser_.file_identifier_.empty()) {
+ code += ", '" + parser_.file_identifier_ + "'";
+ }
+ if (size_prefixed) {
+ if (parser_.file_identifier_.empty()) { code += ", undefined"; }
+ code += ", true";
+ }
+ code += ");\n";
+ code += "};\n\n";
+ }
+ }
+
// Generate an accessor struct with constructor for a flatbuffers struct.
void GenStruct(const Parser &parser, StructDef &struct_def,
std::string *code_ptr, std::string *exports_ptr,
@@ -627,7 +683,8 @@ class JsTsGenerator : public BaseGenerator {
code += " {\n";
if (lang_.language != IDLOptions::kTs) {
code += " /**\n";
- code += " * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", "");
+ code +=
+ " * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", "");
code += " */\n";
}
code += " bb: flatbuffers.ByteBuffer|null = null;\n";
@@ -689,43 +746,27 @@ class JsTsGenerator : public BaseGenerator {
code += " return this;\n";
code += "};\n\n";
- // Generate a special accessor for the table that when used as the root of a
+ // Generate special accessors for the table that when used as the root of a
// FlatBuffer
- if (!struct_def.fixed) {
+ GenerateRootAccessor(struct_def, code_ptr, code, object_name, false);
+ GenerateRootAccessor(struct_def, code_ptr, code, object_name, true);
+
+ // Generate the identifier check method
+ if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def &&
+ !parser_.file_identifier_.empty()) {
GenDocComment(code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
- GenTypeAnnotation(kParam, object_name + "=", "obj") +
- GenTypeAnnotation(kReturns, object_name, "", false));
+ GenTypeAnnotation(kReturns, "boolean", "", false));
if (lang_.language == IDLOptions::kTs) {
- code += "static getRoot" + Verbose(struct_def, "As");
- code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
- "):" + object_name + " {\n";
+ code +=
+ "static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean "
+ "{\n";
} else {
- code += object_name + ".getRoot" + Verbose(struct_def, "As");
- code += " = function(bb, obj) {\n";
+ code += object_name + ".bufferHasIdentifier = function(bb) {\n";
}
- code += " return (obj || new " + object_name;
- code += ").__init(bb.readInt32(bb.position()) + bb.position(), bb);\n";
- code += "};\n\n";
-
- // Generate the identifier check method
- if (parser_.root_struct_def_ == &struct_def &&
- !parser_.file_identifier_.empty()) {
- GenDocComment(
- code_ptr,
- GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
- GenTypeAnnotation(kReturns, "boolean", "", false));
- if (lang_.language == IDLOptions::kTs) {
- code +=
- "static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean "
- "{\n";
- } else {
- code += object_name + ".bufferHasIdentifier = function(bb) {\n";
- }
- code += " return bb.__has_identifier('" + parser_.file_identifier_;
- code += "');\n};\n\n";
- }
+ code += " return bb.__has_identifier('" + parser_.file_identifier_;
+ code += "');\n};\n\n";
}
// Emit field accessors
@@ -820,19 +861,21 @@ class JsTsGenerator : public BaseGenerator {
}
if (struct_def.fixed) {
- code += " return (obj || new " + type;
+ code += " return (obj || " + GenerateNewExpression(type);
code += ").__init(this.bb_pos";
code +=
MaybeAdd(field.value.offset) + ", " + GenBBAccess() + ");\n";
} else {
- code += offset_prefix + "(obj || new " + type + ").__init(";
+ code += offset_prefix + "(obj || " + GenerateNewExpression(type) +
+ ").__init(";
code += field.value.type.struct_def->fixed
? "this.bb_pos + offset"
: GenBBAccess() + ".__indirect(this.bb_pos + offset)";
code += ", " + GenBBAccess() + ") : null;\n";
}
- if (lang_.language == IDLOptions::kTs && !parser_.opts.generate_all) {
+ if (lang_.language == IDLOptions::kTs &&
+ !parser_.opts.generate_all) {
imported_files.insert(field.value.type.struct_def->file);
}
@@ -906,7 +949,8 @@ class JsTsGenerator : public BaseGenerator {
}
if (vectortype.base_type == BASE_TYPE_STRUCT) {
- code += offset_prefix + "(obj || new " + vectortypename;
+ code += offset_prefix + "(obj || " +
+ GenerateNewExpression(vectortypename);
code += ").__init(";
code += vectortype.struct_def->fixed
? index
@@ -975,7 +1019,8 @@ class JsTsGenerator : public BaseGenerator {
}
// Adds the mutable scalar value to the output
- if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer) {
+ if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer &&
+ !IsUnion(field.value.type)) {
std::string annotations = GenTypeAnnotation(
kParam, GenTypeName(field.value.type, true), "value");
GenDocComment(
@@ -1239,30 +1284,9 @@ class JsTsGenerator : public BaseGenerator {
code += " return offset;\n";
code += "};\n\n";
- // Generate the method to complete buffer construction
- if (parser_.root_struct_def_ == &struct_def) {
- GenDocComment(
- code_ptr,
- GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
- GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset",
- false));
-
- if (lang_.language == IDLOptions::kTs) {
- code += "static finish" + Verbose(struct_def) + "Buffer";
- code +=
- "(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
- } else {
- code += object_name + ".finish" + Verbose(struct_def) + "Buffer";
- code += " = function(builder, offset) {\n";
- }
-
- code += " builder.finish(offset";
- if (!parser_.file_identifier_.empty()) {
- code += ", '" + parser_.file_identifier_ + "'";
- }
- code += ");\n";
- code += "};\n\n";
- }
+ // Generate the methods to complete buffer construction
+ GenerateFinisher(struct_def, code_ptr, code, object_name, false);
+ GenerateFinisher(struct_def, code_ptr, code, object_name, true);
// Generate a convenient CreateX function
if (lang_.language == IDLOptions::kJs) {
@@ -1271,8 +1295,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
- if (field.deprecated)
- continue;
+ if (field.deprecated) continue;
paramDoc +=
GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field));
}
@@ -1292,8 +1315,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
- if (field.deprecated)
- continue;
+ if (field.deprecated) continue;
if (lang_.language == IDLOptions::kTs) {
code += ", " + GetArgName(field) + ":" + GetArgType(field);
@@ -1317,8 +1339,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
- if (field.deprecated)
- continue;
+ if (field.deprecated) continue;
code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "(";
code += "builder, " + GetArgName(field) + ");\n";
@@ -1327,14 +1348,11 @@ class JsTsGenerator : public BaseGenerator {
code += " return " + methodPrefix + ".end" + Verbose(struct_def) +
"(builder);\n";
code += "}\n";
- if (lang_.language == IDLOptions::kJs)
- code += "\n";
+ if (lang_.language == IDLOptions::kJs) code += "\n";
}
if (lang_.language == IDLOptions::kTs) {
- if (!object_namespace.empty()) {
- code += "}\n";
- }
+ if (!object_namespace.empty()) { code += "}\n"; }
code += "}\n";
}
}
@@ -1353,9 +1371,7 @@ class JsTsGenerator : public BaseGenerator {
return argname;
}
- std::string Verbose(const StructDef &struct_def,
- const char* prefix = "")
- {
+ std::string Verbose(const StructDef &struct_def, const char *prefix = "") {
return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name;
}
};
@@ -1370,11 +1386,12 @@ bool GenerateJSTS(const Parser &parser, const std::string &path,
std::string JSTSMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) {
FLATBUFFERS_ASSERT(parser.opts.lang <= IDLOptions::kMAX);
- const auto &lang = GetJsLangParams(parser.opts.lang);
std::string filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
- std::string make_rule = GeneratedFileName(path, filebase, lang) + ": ";
+ jsts::JsTsGenerator generator(parser, path, file_name);
+ std::string make_rule =
+ generator.GeneratedFileName(path, filebase, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) {
diff --git a/src/idl_gen_json_schema.cpp b/src/idl_gen_json_schema.cpp
index a0f193b5..a1d0704d 100644
--- a/src/idl_gen_json_schema.cpp
+++ b/src/idl_gen_json_schema.cpp
@@ -15,17 +15,13 @@
*/
#include <iostream>
+
#include "flatbuffers/code_generators.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
namespace flatbuffers {
-static std::string GeneratedFileName(const std::string &path,
- const std::string &file_name) {
- return path + file_name + ".schema.json";
-}
-
namespace jsons {
std::string GenNativeType(BaseType type) {
@@ -42,6 +38,7 @@ std::string GenNativeType(BaseType type) {
case BASE_TYPE_FLOAT:
case BASE_TYPE_DOUBLE: return "number";
case BASE_TYPE_STRING: return "string";
+ case BASE_TYPE_ARRAY: return "array";
default: return "";
}
}
@@ -70,6 +67,7 @@ std::string GenType(const Type &type) {
return GenTypeRef(type.enum_def);
}
switch (type.base_type) {
+ case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR: {
std::string typeline;
typeline.append("\"type\" : \"array\", \"items\" : { ");
@@ -113,12 +111,20 @@ class JsonSchemaGenerator : public BaseGenerator {
public:
JsonSchemaGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "", "") {}
+ : BaseGenerator(parser, path, file_name, "", "", "json") {}
explicit JsonSchemaGenerator(const BaseGenerator &base_generator)
: BaseGenerator(base_generator) {}
+ std::string GeneratedFileName(const std::string &path,
+ const std::string &file_name,
+ const IDLOptions &options /* unused */) const {
+ (void)options;
+ return path + file_name + ".schema.json";
+ }
+
bool generate() {
+ if (parser_.root_struct_def_ == nullptr) { return false; }
code_.Clear();
code_ += "{";
code_ += " \"$schema\": \"http://json-schema.org/draft-04/schema#\",";
@@ -149,15 +155,28 @@ class JsonSchemaGenerator : public BaseGenerator {
comment.append(*comment_line);
}
if (comment.size() > 0) {
- code_ += " \"description\" : \"" + comment + "\",";
+ std::string description;
+ if (!EscapeString(comment.c_str(), comment.length(), &description, true,
+ true)) {
+ return false;
+ }
+ code_ += " \"description\" : " + description + ",";
}
code_ += " \"properties\" : {";
const auto &properties = structure->fields.vec;
for (auto prop = properties.cbegin(); prop != properties.cend(); ++prop) {
const auto &property = *prop;
- std::string typeLine(" \"" + property->name + "\" : { " +
- GenType(property->value.type) + " }");
+ std::string arrayInfo = "";
+ if (IsArray(property->value.type)) {
+ arrayInfo = ",\n \"minItems\": " +
+ NumToString(property->value.type.fixed_length) +
+ ",\n \"maxItems\": " +
+ NumToString(property->value.type.fixed_length);
+ }
+ std::string typeLine =
+ " \"" + property->name + "\" : {\n" + " " +
+ GenType(property->value.type) + arrayInfo + "\n }";
if (property != properties.back()) { typeLine.append(","); }
code_ += typeLine;
}
@@ -191,7 +210,8 @@ class JsonSchemaGenerator : public BaseGenerator {
GenFullName(parser_.root_struct_def_) + "\"";
code_ += "}"; // close schema root
- const std::string file_path = GeneratedFileName(path_, file_name_);
+ const std::string file_path =
+ GeneratedFileName(path_, file_name_, parser_.opts);
const std::string final_code = code_.ToString();
return SaveFile(file_path.c_str(), final_code, false);
}
diff --git a/src/idl_gen_kotlin.cpp b/src/idl_gen_kotlin.cpp
new file mode 100644
index 00000000..bd72f5a4
--- /dev/null
+++ b/src/idl_gen_kotlin.cpp
@@ -0,0 +1,1442 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// independent from idl_parser, since this code is not needed for most clients
+
+#include <functional>
+#include <unordered_set>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+#if defined(FLATBUFFERS_CPP98_STL)
+# include <cctype>
+#endif // defined(FLATBUFFERS_CPP98_STL)
+
+namespace flatbuffers {
+
+namespace kotlin {
+
+typedef std::map<std::string, std::pair<std::string, std::string> > FbbParamMap;
+static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN",
+ "POSITIVE_INFINITY",
+ "NEGATIVE_INFINITY");
+
+static const CommentConfig comment_config = { "/**", " *", " */" };
+static const std::string ident_pad = " ";
+static const char *keywords[] = {
+ "package", "as", "typealias", "class", "this", "super",
+ "val", "var", "fun", "for", "null", "true",
+ "false", "is", "in", "throw", "return", "break",
+ "continue", "object", "if", "try", "else", "while",
+ "do", "when", "interface", "typeof", "Any", "Character"
+};
+
+// Escape Keywords
+static std::string Esc(const std::string &name) {
+ for (size_t i = 0; i < sizeof(keywords) / sizeof(keywords[0]); i++) {
+ if (name == keywords[i]) { return MakeCamel(name + "_", false); }
+ }
+
+ return MakeCamel(name, false);
+}
+
+class KotlinGenerator : public BaseGenerator {
+ public:
+ KotlinGenerator(const Parser &parser, const std::string &path,
+ const std::string &file_name)
+ : BaseGenerator(parser, path, file_name, "", ".", "kt"),
+ cur_name_space_(nullptr) {}
+
+ KotlinGenerator &operator=(const KotlinGenerator &);
+ bool generate() FLATBUFFERS_OVERRIDE {
+ std::string one_file_code;
+
+ cur_name_space_ = parser_.current_namespace_;
+ for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+ ++it) {
+ CodeWriter enumWriter(ident_pad);
+ auto &enum_def = **it;
+ if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
+ GenEnum(enum_def, enumWriter);
+ if (parser_.opts.one_file) {
+ one_file_code += enumWriter.ToString();
+ } else {
+ if (!SaveType(enum_def.name, *enum_def.defined_namespace,
+ enumWriter.ToString(), false))
+ return false;
+ }
+ }
+
+ for (auto it = parser_.structs_.vec.begin();
+ it != parser_.structs_.vec.end(); ++it) {
+ CodeWriter structWriter(ident_pad);
+ auto &struct_def = **it;
+ if (!parser_.opts.one_file)
+ cur_name_space_ = struct_def.defined_namespace;
+ GenStruct(struct_def, structWriter);
+ if (parser_.opts.one_file) {
+ one_file_code += structWriter.ToString();
+ } else {
+ if (!SaveType(struct_def.name, *struct_def.defined_namespace,
+ structWriter.ToString(), true))
+ return false;
+ }
+ }
+
+ if (parser_.opts.one_file) {
+ return SaveType(file_name_, *parser_.current_namespace_, one_file_code,
+ true);
+ }
+ return true;
+ }
+
+ // Save out the generated code for a single class while adding
+ // declaration boilerplate.
+ bool SaveType(const std::string &defname, const Namespace &ns,
+ const std::string &classcode, bool needs_includes) const {
+ if (!classcode.length()) return true;
+
+ std::string code =
+ "// " + std::string(FlatBuffersGeneratedWarning()) + "\n\n";
+
+ std::string namespace_name = FullNamespace(".", ns);
+ if (!namespace_name.empty()) {
+ code += "package " + namespace_name;
+ code += "\n\n";
+ }
+ if (needs_includes) {
+ code += "import java.nio.*\n";
+ code += "import kotlin.math.sign\n";
+ code += "import com.google.flatbuffers.*\n\n";
+ }
+ code += classcode;
+ auto filename = NamespaceDir(ns) + defname + ".kt";
+ return SaveFile(filename.c_str(), code, false);
+ }
+
+ const Namespace *CurrentNameSpace() const FLATBUFFERS_OVERRIDE {
+ return cur_name_space_;
+ }
+
+ static bool IsEnum(const Type &type) {
+ return type.enum_def != nullptr && IsInteger(type.base_type);
+ }
+
+ static std::string GenTypeBasic(const BaseType &type) {
+ // clang-format off
+ static const char * const kotlin_typename[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE, ...) \
+ #KTYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ };
+ // clang-format on
+ return kotlin_typename[type];
+ }
+
+ std::string GenTypePointer(const Type &type) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "String";
+ case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
+ case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
+ default: return "Table";
+ }
+ }
+
+ std::string GenTypeGet(const Type &type) const {
+ return IsScalar(type.base_type) ? GenTypeBasic(type.base_type)
+ : GenTypePointer(type);
+ }
+
+ std::string GenEnumDefaultValue(const FieldDef &field) const {
+ auto &value = field.value;
+ FLATBUFFERS_ASSERT(value.type.enum_def);
+ auto &enum_def = *value.type.enum_def;
+ auto enum_val = enum_def.FindByValue(value.constant);
+ return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
+ : value.constant;
+ }
+
+ // Generate default values to compare against a default value when
+ // `force_defaults` is `false`.
+ // Main differences are:
+ // - Floats are upcasted to doubles
+ // - Unsigned are casted to signed
+ std::string GenFBBDefaultValue(const FieldDef &field) const {
+ auto out = GenDefaultValue(field, true);
+ // All FlatBufferBuilder default floating point values are doubles
+ if (field.value.type.base_type == BASE_TYPE_FLOAT) {
+ if (out.find("Float") != std::string::npos) {
+ out.replace(0, 5, "Double");
+ }
+ }
+ // Guarantee all values are doubles
+ if (out.back() == 'f') out.pop_back();
+ return out;
+ }
+
+ // FlatBufferBuilder only store signed types, so this function
+ // returns a cast for unsigned values
+ std::string GenFBBValueCast(const FieldDef &field) const {
+ if (IsUnsigned(field.value.type.base_type)) {
+ return CastToSigned(field.value.type);
+ }
+ return "";
+ }
+
+ std::string GenDefaultValue(const FieldDef &field,
+ bool force_signed = false) const {
+ auto &value = field.value;
+ auto base_type = field.value.type.base_type;
+ if (IsFloat(base_type)) {
+ auto val = KotlinFloatGen.GenFloatConstant(field);
+ if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
+ val.pop_back();
+ }
+ return val;
+ }
+
+ if (base_type == BASE_TYPE_BOOL) {
+ return value.constant == "0" ? "false" : "true";
+ }
+
+ std::string suffix = "";
+
+ if (base_type == BASE_TYPE_LONG || !force_signed) {
+ suffix = LiteralSuffix(base_type);
+ }
+ return value.constant + suffix;
+ }
+
+ void GenEnum(EnumDef &enum_def, CodeWriter &writer) const {
+ if (enum_def.generated) return;
+
+ GenerateComment(enum_def.doc_comment, writer, &comment_config);
+
+ writer += "@Suppress(\"unused\")";
+ writer += "@ExperimentalUnsignedTypes";
+ writer += "class " + Esc(enum_def.name) + " private constructor() {";
+ writer.IncrementIdentLevel();
+
+ GenerateCompanionObject(writer, [&]() {
+ // Write all properties
+ auto vals = enum_def.Vals();
+ for (auto it = vals.begin(); it != vals.end(); ++it) {
+ auto &ev = **it;
+ auto field_type = GenTypeBasic(enum_def.underlying_type.base_type);
+ auto val = enum_def.ToString(ev);
+ auto suffix = LiteralSuffix(enum_def.underlying_type.base_type);
+ writer.SetValue("name", Esc(ev.name));
+ writer.SetValue("type", field_type);
+ writer.SetValue("val", val + suffix);
+ GenerateComment(ev.doc_comment, writer, &comment_config);
+ writer += "const val {{name}}: {{type}} = {{val}}";
+ }
+
+ // Generate a generate string table for enum values.
+ // Problem is, if values are very sparse that could generate really
+ // big tables. Ideally in that case we generate a map lookup
+ // instead, but for the moment we simply don't output a table at all.
+ auto range = enum_def.Distance();
+ // Average distance between values above which we consider a table
+ // "too sparse". Change at will.
+ static const uint64_t kMaxSparseness = 5;
+ if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
+ GeneratePropertyOneLine(writer, "names", "Array<String>", [&]() {
+ writer += "arrayOf(\\";
+ auto val = enum_def.Vals().front();
+ for (auto it = vals.begin(); it != vals.end(); ++it) {
+ auto ev = *it;
+ for (auto k = enum_def.Distance(val, ev); k > 1; --k)
+ writer += "\"\", \\";
+ val = ev;
+ writer += "\"" + (*it)->name + "\"\\";
+ if (it + 1 != vals.end()) { writer += ", \\"; }
+ }
+ writer += ")";
+ });
+ GenerateFunOneLine(writer, "name", "e: Int", "String", [&]() {
+ writer += "names[e\\";
+ if (enum_def.MinValue()->IsNonZero())
+ writer += " - " + enum_def.MinValue()->name + ".toInt()\\";
+ writer += "]";
+ });
+ }
+ });
+ writer.DecrementIdentLevel();
+ writer += "}";
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string ByteBufferGetter(const Type &type,
+ std::string bb_var_name) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "__string";
+ case BASE_TYPE_STRUCT: return "__struct";
+ case BASE_TYPE_UNION: return "__union";
+ case BASE_TYPE_VECTOR:
+ return ByteBufferGetter(type.VectorType(), bb_var_name);
+ case BASE_TYPE_INT:
+ case BASE_TYPE_UINT: return bb_var_name + ".getInt";
+ case BASE_TYPE_SHORT:
+ case BASE_TYPE_USHORT: return bb_var_name + ".getShort";
+ case BASE_TYPE_ULONG:
+ case BASE_TYPE_LONG: return bb_var_name + ".getLong";
+ case BASE_TYPE_FLOAT: return bb_var_name + ".getFloat";
+ case BASE_TYPE_DOUBLE: return bb_var_name + ".getDouble";
+ case BASE_TYPE_CHAR:
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_NONE:
+ case BASE_TYPE_UTYPE: return bb_var_name + ".get";
+ case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get";
+ default:
+ return bb_var_name + ".get" + MakeCamel(GenTypeBasic(type.base_type));
+ }
+ }
+
+ std::string ByteBufferSetter(const Type &type) const {
+ if (IsScalar(type.base_type)) {
+ switch (type.base_type) {
+ case BASE_TYPE_INT:
+ case BASE_TYPE_UINT: return "bb.putInt";
+ case BASE_TYPE_SHORT:
+ case BASE_TYPE_USHORT: return "bb.putShort";
+ case BASE_TYPE_ULONG:
+ case BASE_TYPE_LONG: return "bb.putLong";
+ case BASE_TYPE_FLOAT: return "bb.putFloat";
+ case BASE_TYPE_DOUBLE: return "bb.putDouble";
+ case BASE_TYPE_CHAR:
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_BOOL:
+ case BASE_TYPE_NONE:
+ case BASE_TYPE_UTYPE: return "bb.put";
+ default: return "bb.put" + MakeCamel(GenTypeBasic(type.base_type));
+ }
+ }
+ return "";
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string GenLookupByKey(flatbuffers::FieldDef *key_field,
+ const std::string &bb_var_name,
+ const char *num = nullptr) const {
+ auto type = key_field->value.type;
+ return ByteBufferGetter(type, bb_var_name) + "(" +
+ GenOffsetGetter(key_field, num) + ")";
+ }
+
+ // Returns the method name for use with add/put calls.
+ static std::string GenMethod(const Type &type) {
+ return IsScalar(type.base_type) ? ToSignedType(type)
+ : (IsStruct(type) ? "Struct" : "Offset");
+ }
+
+ // Recursively generate arguments for a constructor, to deal with nested
+ // structs.
+ static void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
+ const char *nameprefix) {
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (IsStruct(field.value.type)) {
+ // Generate arguments for a struct inside a struct. To ensure
+ // names don't clash, and to make it obvious these arguments are
+ // constructing a nested struct, prefix the name with the field
+ // name.
+ GenStructArgs(*field.value.type.struct_def, writer,
+ (nameprefix + (field.name + "_")).c_str());
+ } else {
+ writer += std::string(", ") + nameprefix + "\\";
+ writer += MakeCamel(field.name) + ": \\";
+ writer += GenTypeBasic(field.value.type.base_type) + "\\";
+ }
+ }
+ }
+
+ // Recusively generate struct construction statements of the form:
+ // builder.putType(name);
+ // and insert manual padding.
+ static void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
+ const char *nameprefix) {
+ writer.SetValue("align", NumToString(struct_def.minalign));
+ writer.SetValue("size", NumToString(struct_def.bytesize));
+ writer += "builder.prep({{align}}, {{size}})";
+ auto fields_vec = struct_def.fields.vec;
+ for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
+ auto &field = **it;
+
+ if (field.padding) {
+ writer.SetValue("pad", NumToString(field.padding));
+ writer += "builder.pad({{pad}})";
+ }
+ if (IsStruct(field.value.type)) {
+ GenStructBody(*field.value.type.struct_def, writer,
+ (nameprefix + (field.name + "_")).c_str());
+ } else {
+ writer.SetValue("type", GenMethod(field.value.type));
+ writer.SetValue("argname", nameprefix + MakeCamel(field.name, false));
+ writer.SetValue("cast", CastToSigned(field.value.type));
+ writer += "builder.put{{type}}({{argname}}{{cast}})";
+ }
+ }
+ }
+
+ std::string GenByteBufferLength(const char *bb_name) const {
+ std::string bb_len = bb_name;
+ bb_len += ".capacity()";
+ return bb_len;
+ }
+
+ std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
+ const char *num = nullptr) const {
+ std::string key_offset =
+ "__offset(" + NumToString(key_field->value.offset) + ", ";
+ if (num) {
+ key_offset += num;
+ key_offset += ", _bb)";
+ } else {
+ key_offset += GenByteBufferLength("bb");
+ key_offset += " - tableOffset, bb)";
+ }
+ return key_offset;
+ }
+
+ void GenStruct(StructDef &struct_def, CodeWriter &writer) const {
+ if (struct_def.generated) return;
+
+ GenerateComment(struct_def.doc_comment, writer, &comment_config);
+ auto fixed = struct_def.fixed;
+
+ writer.SetValue("struct_name", Esc(struct_def.name));
+ writer.SetValue("superclass", fixed ? "Struct" : "Table");
+
+ writer += "@Suppress(\"unused\")";
+ writer += "@ExperimentalUnsignedTypes";
+ writer += "class {{struct_name}} : {{superclass}}() {\n";
+
+ writer.IncrementIdentLevel();
+
+ {
+ // Generate the __init() method that sets the field in a pre-existing
+ // accessor object. This is to allow object reuse.
+ GenerateFun(writer, "__init", "_i: Int, _bb: ByteBuffer", "",
+ [&]() { writer += "__reset(_i, _bb)"; });
+
+ // Generate assign method
+ GenerateFun(writer, "__assign", "_i: Int, _bb: ByteBuffer",
+ Esc(struct_def.name), [&]() {
+ writer += "__init(_i, _bb)";
+ writer += "return this";
+ });
+
+ // Generate all getters
+ GenerateStructGetters(struct_def, writer);
+
+ // Generate Static Fields
+ GenerateCompanionObject(writer, [&]() {
+ if (!struct_def.fixed) {
+ FieldDef *key_field = nullptr;
+
+ // Generate verson check method.
+ // Force compile time error if not using the same version
+ // runtime.
+ GenerateFunOneLine(writer, "validateVersion", "", "", [&]() {
+ writer += "Constants.FLATBUFFERS_1_12_0()";
+ });
+
+ GenerateGetRootAsAccessors(Esc(struct_def.name), writer);
+ GenerateBufferHasIdentifier(struct_def, writer);
+ GenerateTableCreator(struct_def, writer);
+
+ GenerateStartStructMethod(struct_def, writer);
+
+ // Static Add for fields
+ auto fields = struct_def.fields.vec;
+ int field_pos = -1;
+ for (auto it = fields.begin(); it != fields.end(); ++it) {
+ auto &field = **it;
+ field_pos++;
+ if (field.deprecated) continue;
+ if (field.key) key_field = &field;
+ GenerateAddField(NumToString(field_pos), field, writer);
+
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ auto vector_type = field.value.type.VectorType();
+ if (!IsStruct(vector_type)) {
+ GenerateCreateVectorField(field, writer);
+ }
+ GenerateStartVectorField(field, writer);
+ }
+ }
+
+ GenerateEndStructMethod(struct_def, writer);
+ auto file_identifier = parser_.file_identifier_;
+ if (parser_.root_struct_def_ == &struct_def) {
+ GenerateFinishStructBuffer(struct_def, file_identifier, writer);
+ GenerateFinishSizePrefixed(struct_def, file_identifier, writer);
+ }
+
+ if (struct_def.has_key) {
+ GenerateLookupByKey(key_field, struct_def, writer);
+ }
+ } else {
+ GenerateStaticConstructor(struct_def, writer);
+ }
+ });
+ }
+
+ // class closing
+ writer.DecrementIdentLevel();
+ writer += "}";
+ }
+
+ // TODO: move key_field to reference instead of pointer
+ void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
+ CodeWriter &writer) const {
+ std::stringstream params;
+ params << "obj: " << Esc(struct_def.name) << "?"
+ << ", ";
+ params << "vectorLocation: Int, ";
+ params << "key: " << GenTypeGet(key_field->value.type) << ", ";
+ params << "bb: ByteBuffer";
+
+ auto statements = [&]() {
+ auto base_type = key_field->value.type.base_type;
+ writer.SetValue("struct_name", Esc(struct_def.name));
+ if (base_type == BASE_TYPE_STRING) {
+ writer +=
+ "val byteKey = key."
+ "toByteArray(java.nio.charset.StandardCharsets.UTF_8)";
+ }
+ writer += "var span = bb.getInt(vectorLocation - 4)";
+ writer += "var start = 0";
+ writer += "while (span != 0) {";
+ writer.IncrementIdentLevel();
+ writer += "var middle = span / 2";
+ writer +=
+ "val tableOffset = __indirect(vector"
+ "Location + 4 * (start + middle), bb)";
+ if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+ writer += "val comp = compareStrings(\\";
+ writer += GenOffsetGetter(key_field) + "\\";
+ writer += ", byteKey, bb)";
+ } else {
+ auto cast = CastToUsigned(key_field->value.type);
+ auto get_val = GenLookupByKey(key_field, "bb");
+ writer += "val value = " + get_val + cast;
+ writer += "val comp = value.compareTo(key)";
+ }
+ writer += "when {";
+ writer.IncrementIdentLevel();
+ writer += "comp > 0 -> span = middle";
+ writer += "comp < 0 -> {";
+ writer.IncrementIdentLevel();
+ writer += "middle++";
+ writer += "start += middle";
+ writer += "span -= middle";
+ writer.DecrementIdentLevel();
+ writer += "}"; // end comp < 0
+ writer += "else -> {";
+ writer.IncrementIdentLevel();
+ writer += "return (obj ?: {{struct_name}}()).__assign(tableOffset, bb)";
+ writer.DecrementIdentLevel();
+ writer += "}"; // end else
+ writer.DecrementIdentLevel();
+ writer += "}"; // end when
+ writer.DecrementIdentLevel();
+ writer += "}"; // end while
+ writer += "return null";
+ };
+ GenerateFun(writer, "__lookup_by_key", params.str(),
+ Esc(struct_def.name) + "?", statements);
+ }
+
+ void GenerateFinishSizePrefixed(StructDef &struct_def,
+ const std::string &identifier,
+ CodeWriter &writer) const {
+ auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
+ auto params = "builder: FlatBufferBuilder, offset: Int";
+ auto method_name = "finishSizePrefixed" + Esc(struct_def.name) + "Buffer";
+ GenerateFunOneLine(writer, method_name, params, "", [&]() {
+ writer += "builder.finishSizePrefixed(offset" + id + ")";
+ });
+ }
+ void GenerateFinishStructBuffer(StructDef &struct_def,
+ const std::string &identifier,
+ CodeWriter &writer) const {
+ auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
+ auto params = "builder: FlatBufferBuilder, offset: Int";
+ auto method_name = "finish" + Esc(struct_def.name) + "Buffer";
+ GenerateFunOneLine(writer, method_name, params, "",
+ [&]() { writer += "builder.finish(offset" + id + ")"; });
+ }
+
+ void GenerateEndStructMethod(StructDef &struct_def,
+ CodeWriter &writer) const {
+ // Generate end{{TableName}}(builder: FlatBufferBuilder) method
+ auto name = "end" + Esc(struct_def.name);
+ auto params = "builder: FlatBufferBuilder";
+ auto returns = "Int";
+ auto field_vec = struct_def.fields.vec;
+
+ GenerateFun(writer, name, params, returns, [&]() {
+ writer += "val o = builder.endTable()";
+ writer.IncrementIdentLevel();
+ for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated || !field.required) { continue; }
+ writer.SetValue("offset", NumToString(field.value.offset));
+ writer += "builder.required(o, {{offset}})";
+ }
+ writer.DecrementIdentLevel();
+ writer += "return o";
+ });
+ }
+
+ // Generate a method to create a vector from a Kotlin array.
+ void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer) const {
+ auto vector_type = field.value.type.VectorType();
+ auto method_name = "create" + MakeCamel(Esc(field.name)) + "Vector";
+ auto params = "builder: FlatBufferBuilder, data: " +
+ GenTypeBasic(vector_type.base_type) + "Array";
+ writer.SetValue("size", NumToString(InlineSize(vector_type)));
+ writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
+ writer.SetValue("root", GenMethod(vector_type));
+ writer.SetValue("cast", CastToSigned(vector_type));
+
+ GenerateFun(writer, method_name, params, "Int", [&]() {
+ writer += "builder.startVector({{size}}, data.size, {{align}})";
+ writer += "for (i in data.size - 1 downTo 0) {";
+ writer.IncrementIdentLevel();
+ writer += "builder.add{{root}}(data[i]{{cast}})";
+ writer.DecrementIdentLevel();
+ writer += "}";
+ writer += "return builder.endVector()";
+ });
+ }
+
+ void GenerateStartVectorField(FieldDef &field, CodeWriter &writer) const {
+ // Generate a method to start a vector, data to be added manually
+ // after.
+ auto vector_type = field.value.type.VectorType();
+ auto params = "builder: FlatBufferBuilder, numElems: Int";
+ writer.SetValue("size", NumToString(InlineSize(vector_type)));
+ writer.SetValue("align", NumToString(InlineAlignment(vector_type)));
+
+ GenerateFunOneLine(
+ writer, "start" + MakeCamel(Esc(field.name) + "Vector", true), params,
+ "", [&]() {
+ writer += "builder.startVector({{size}}, numElems, {{align}})";
+ });
+ }
+
+ void GenerateAddField(std::string field_pos, FieldDef &field,
+ CodeWriter &writer) const {
+ auto field_type = GenTypeBasic(field.value.type.base_type);
+ auto secondArg = MakeCamel(Esc(field.name), false) + ": " + field_type;
+ GenerateFunOneLine(writer, "add" + MakeCamel(Esc(field.name), true),
+ "builder: FlatBufferBuilder, " + secondArg, "", [&]() {
+ auto method = GenMethod(field.value.type);
+ writer.SetValue("field_name",
+ MakeCamel(Esc(field.name), false));
+ writer.SetValue("method_name", method);
+ writer.SetValue("pos", field_pos);
+ writer.SetValue("default", GenFBBDefaultValue(field));
+ writer.SetValue("cast", GenFBBValueCast(field));
+
+ writer += "builder.add{{method_name}}({{pos}}, \\";
+ writer += "{{field_name}}{{cast}}, {{default}})";
+ });
+ }
+
+ static std::string ToSignedType(const Type &type) {
+ switch (type.base_type) {
+ case BASE_TYPE_UINT: return GenTypeBasic(BASE_TYPE_INT);
+ case BASE_TYPE_ULONG: return GenTypeBasic(BASE_TYPE_LONG);
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_NONE:
+ case BASE_TYPE_UTYPE: return GenTypeBasic(BASE_TYPE_CHAR);
+ case BASE_TYPE_USHORT: return GenTypeBasic(BASE_TYPE_SHORT);
+ case BASE_TYPE_VECTOR: return ToSignedType(type.VectorType());
+ default: return GenTypeBasic(type.base_type);
+ }
+ }
+
+ static std::string FlexBufferBuilderCast(const std::string &method,
+ FieldDef &field, bool isFirst) {
+ auto field_type = GenTypeBasic(field.value.type.base_type);
+ std::string to_type;
+ if (method == "Boolean")
+ to_type = "Boolean";
+ else if (method == "Long")
+ to_type = "Long";
+ else if (method == "Int" || method == "Offset" || method == "Struct")
+ to_type = "Int";
+ else if (method == "Byte" || method.empty())
+ to_type = isFirst ? "Byte" : "Int";
+ else if (method == "Short")
+ to_type = isFirst ? "Short" : "Int";
+ else if (method == "Double")
+ to_type = "Double";
+ else if (method == "Float")
+ to_type = isFirst ? "Float" : "Double";
+ else if (method == "UByte")
+
+ if (field_type != to_type) return ".to" + to_type + "()";
+ return "";
+ }
+
+ // fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
+ void GenerateStartStructMethod(StructDef &struct_def,
+ CodeWriter &code) const {
+ GenerateFunOneLine(code, "start" + Esc(struct_def.name),
+ "builder: FlatBufferBuilder", "", [&]() {
+ code += "builder.startTable(" +
+ NumToString(struct_def.fields.vec.size()) +
+ ")";
+ });
+ }
+
+ void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer) const {
+ // Generate a method that creates a table in one go. This is only possible
+ // when the table has no struct fields, since those have to be created
+ // inline, and there's no way to do so in Java.
+ bool has_no_struct_fields = true;
+ int num_fields = 0;
+ auto fields_vec = struct_def.fields.vec;
+
+ for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (IsStruct(field.value.type)) {
+ has_no_struct_fields = false;
+ } else {
+ num_fields++;
+ }
+ }
+ // JVM specifications restrict default constructor params to be < 255.
+ // Longs and doubles take up 2 units, so we set the limit to be < 127.
+ if (has_no_struct_fields && num_fields && num_fields < 127) {
+ // Generate a table constructor of the form:
+ // public static int createName(FlatBufferBuilder builder, args...)
+
+ auto name = "create" + Esc(struct_def.name);
+ std::stringstream params;
+ params << "builder: FlatBufferBuilder";
+ for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ params << ", " << MakeCamel(Esc(field.name), false);
+ if (!IsScalar(field.value.type.base_type)) {
+ params << "Offset: ";
+ } else {
+ params << ": ";
+ }
+ params << GenTypeBasic(field.value.type.base_type);
+ }
+
+ GenerateFun(writer, name, params.str(), "Int", [&]() {
+ writer.SetValue("vec_size", NumToString(fields_vec.size()));
+
+ writer += "builder.startTable({{vec_size}})";
+
+ auto sortbysize = struct_def.sortbysize;
+ auto largest = sortbysize ? sizeof(largest_scalar_t) : 1;
+ for (size_t size = largest; size; size /= 2) {
+ for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
+ auto &field = **it;
+ auto base_type_size = SizeOf(field.value.type.base_type);
+ if (!field.deprecated && (!sortbysize || size == base_type_size)) {
+ writer.SetValue("camel_field_name",
+ MakeCamel(Esc(field.name), true));
+ writer.SetValue("field_name", MakeCamel(Esc(field.name), false));
+
+ writer += "add{{camel_field_name}}(builder, {{field_name}}\\";
+ if (!IsScalar(field.value.type.base_type)) {
+ writer += "Offset\\";
+ }
+ writer += ")";
+ }
+ }
+ }
+ writer += "return end{{struct_name}}(builder)";
+ });
+ }
+ }
+ void GenerateBufferHasIdentifier(StructDef &struct_def,
+ CodeWriter &writer) const {
+ auto file_identifier = parser_.file_identifier_;
+ // Check if a buffer has the identifier.
+ if (parser_.root_struct_def_ != &struct_def || !file_identifier.length())
+ return;
+ auto name = MakeCamel(Esc(struct_def.name), false);
+ GenerateFunOneLine(writer, name + "BufferHasIdentifier", "_bb: ByteBuffer",
+ "Boolean", [&]() {
+ writer += "__has_identifier(_bb, \"" +
+ file_identifier + "\")";
+ });
+ }
+
+ void GenerateStructGetters(StructDef &struct_def, CodeWriter &writer) const {
+ auto fields_vec = struct_def.fields.vec;
+ FieldDef *key_field = nullptr;
+ for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (field.key) key_field = &field;
+
+ GenerateComment(field.doc_comment, writer, &comment_config);
+
+ auto field_name = MakeCamel(Esc(field.name), false);
+ auto field_type = GenTypeGet(field.value.type);
+ auto field_default_value = GenDefaultValue(field);
+ auto return_type = GenTypeGet(field.value.type);
+ auto bbgetter = ByteBufferGetter(field.value.type, "bb");
+ auto ucast = CastToUsigned(field);
+ auto offset_val = NumToString(field.value.offset);
+ auto offset_prefix =
+ "val o = __offset(" + offset_val + "); return o != 0 ? ";
+ auto value_base_type = field.value.type.base_type;
+ // Most field accessors need to retrieve and test the field offset
+ // first, this is the offset value for that:
+ writer.SetValue("offset", NumToString(field.value.offset));
+ writer.SetValue("return_type", return_type);
+ writer.SetValue("field_type", field_type);
+ writer.SetValue("field_name", field_name);
+ writer.SetValue("field_default", field_default_value);
+ writer.SetValue("bbgetter", bbgetter);
+ writer.SetValue("ucast", ucast);
+
+ auto opt_ret_type = return_type + "?";
+ // Generate the accessors that don't do object reuse.
+ if (value_base_type == BASE_TYPE_STRUCT) {
+ // Calls the accessor that takes an accessor object with a
+ // new object.
+ // val pos
+ // get() = pos(Vec3())
+ GenerateGetterOneLine(writer, field_name, opt_ret_type, [&]() {
+ writer += "{{field_name}}({{field_type}}())";
+ });
+ } else if (value_base_type == BASE_TYPE_VECTOR &&
+ field.value.type.element == BASE_TYPE_STRUCT) {
+ // Accessors for vectors of structs also take accessor objects,
+ // this generates a variant without that argument.
+ // ex: fun weapons(j: Int) = weapons(Weapon(), j)
+ GenerateFunOneLine(writer, field_name, "j: Int", opt_ret_type, [&]() {
+ writer += "{{field_name}}({{return_type}}(), j)";
+ });
+ }
+
+ if (IsScalar(value_base_type)) {
+ if (struct_def.fixed) {
+ GenerateGetterOneLine(writer, field_name, return_type, [&]() {
+ writer += "{{bbgetter}}(bb_pos + {{offset}}){{ucast}}";
+ });
+ } else {
+ GenerateGetter(writer, field_name, return_type, [&]() {
+ writer += "val o = __offset({{offset}})";
+ writer +=
+ "return if(o != 0) {{bbgetter}}"
+ "(o + bb_pos){{ucast}} else "
+ "{{field_default}}";
+ });
+ }
+ } else {
+ switch (value_base_type) {
+ case BASE_TYPE_STRUCT:
+ if (struct_def.fixed) {
+ // create getter with object reuse
+ // ex:
+ // fun pos(obj: Vec3) : Vec3? = obj.__assign(bb_pos + 4, bb)
+ // ? adds nullability annotation
+ GenerateFunOneLine(
+ writer, field_name, "obj: " + field_type, return_type + "?",
+ [&]() { writer += "obj.__assign(bb_pos + {{offset}}, bb)"; });
+ } else {
+ // create getter with object reuse
+ // ex:
+ // fun pos(obj: Vec3) : Vec3? {
+ // val o = __offset(4)
+ // return if(o != 0) {
+ // obj.__assign(o + bb_pos, bb)
+ // else {
+ // null
+ // }
+ // }
+ // ? adds nullability annotation
+ GenerateFun(
+ writer, field_name, "obj: " + field_type, return_type + "?",
+ [&]() {
+ auto fixed = field.value.type.struct_def->fixed;
+
+ writer.SetValue("seek", Indirect("o + bb_pos", fixed));
+ OffsetWrapper(
+ writer, offset_val,
+ [&]() { writer += "obj.__assign({{seek}}, bb)"; },
+ [&]() { writer += "null"; });
+ });
+ }
+ break;
+ case BASE_TYPE_STRING:
+ // create string getter
+ // e.g.
+ // val Name : String?
+ // get() = {
+ // val o = __offset(10)
+ // return if (o != 0) __string(o + bb_pos) else null
+ // }
+ // ? adds nullability annotation
+ GenerateGetter(writer, field_name, return_type + "?", [&]() {
+ writer += "val o = __offset({{offset}})";
+ writer += "return if (o != 0) __string(o + bb_pos) else null";
+ });
+ break;
+ case BASE_TYPE_VECTOR: {
+ // e.g.
+ // fun inventory(j: Int) : UByte {
+ // val o = __offset(14)
+ // return if (o != 0) {
+ // bb.get(__vector(o) + j * 1).toUByte()
+ // } else {
+ // 0
+ // }
+ // }
+
+ auto vectortype = field.value.type.VectorType();
+ std::string params = "j: Int";
+ std::string nullable = IsScalar(vectortype.base_type) ? "" : "?";
+
+ if (vectortype.base_type == BASE_TYPE_STRUCT ||
+ vectortype.base_type == BASE_TYPE_UNION) {
+ params = "obj: " + field_type + ", j: Int";
+ }
+
+ auto ret_type = return_type + nullable;
+ GenerateFun(writer, field_name, params, ret_type, [&]() {
+ auto inline_size = NumToString(InlineSize(vectortype));
+ auto index = "__vector(o) + j * " + inline_size;
+ auto not_found = NotFoundReturn(field.value.type.element);
+ auto found = "";
+ writer.SetValue("index", index);
+ switch (vectortype.base_type) {
+ case BASE_TYPE_STRUCT: {
+ bool fixed = vectortype.struct_def->fixed;
+ writer.SetValue("index", Indirect(index, fixed));
+ found = "obj.__assign({{index}}, bb)";
+ break;
+ }
+ case BASE_TYPE_UNION:
+ found = "{{bbgetter}}(obj, {{index}} - bb_pos){{ucast}}";
+ break;
+ default: found = "{{bbgetter}}({{index}}){{ucast}}";
+ }
+ OffsetWrapper(
+ writer, offset_val, [&]() { writer += found; },
+ [&]() { writer += not_found; });
+ });
+ break;
+ }
+ case BASE_TYPE_UNION:
+ GenerateFun(writer, field_name, "obj: " + field_type,
+ return_type + "?", [&]() {
+ writer += OffsetWrapperOneLine(
+ offset_val, bbgetter + "(obj, o + bb_pos)",
+ "null");
+ });
+ break;
+ default: FLATBUFFERS_ASSERT(0);
+ }
+ }
+
+ if (value_base_type == BASE_TYPE_VECTOR) {
+ // Generate Lenght functions for vectors
+ GenerateGetter(writer, field_name + "Length", "Int", [&]() {
+ writer += OffsetWrapperOneLine(offset_val, "__vector_len(o)", "0");
+ });
+
+ // See if we should generate a by-key accessor.
+ if (field.value.type.element == BASE_TYPE_STRUCT &&
+ !field.value.type.struct_def->fixed) {
+ auto &sd = *field.value.type.struct_def;
+ auto &fields = sd.fields.vec;
+ for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+ auto &kfield = **kit;
+ if (kfield.key) {
+ auto qualified_name = WrapInNameSpace(sd);
+ auto name = MakeCamel(Esc(field.name), false) + "ByKey";
+ auto params = "key: " + GenTypeGet(kfield.value.type);
+ auto rtype = qualified_name + "?";
+ GenerateFun(writer, name, params, rtype, [&]() {
+ OffsetWrapper(
+ writer, offset_val,
+ [&]() {
+ writer += qualified_name +
+ ".__lookup_by_key(null, __vector(o), key, bb)";
+ },
+ [&]() { writer += "null"; });
+ });
+
+ auto param2 = "obj: " + qualified_name +
+ ", key: " + GenTypeGet(kfield.value.type);
+ GenerateFun(writer, name, param2, rtype, [&]() {
+ OffsetWrapper(
+ writer, offset_val,
+ [&]() {
+ writer += qualified_name +
+ ".__lookup_by_key(obj, __vector(o), key, bb)";
+ },
+ [&]() { writer += "null"; });
+ });
+
+ break;
+ }
+ }
+ }
+ }
+
+ if ((value_base_type == BASE_TYPE_VECTOR &&
+ IsScalar(field.value.type.VectorType().base_type)) ||
+ value_base_type == BASE_TYPE_STRING) {
+ auto end_idx =
+ NumToString(value_base_type == BASE_TYPE_STRING
+ ? 1
+ : InlineSize(field.value.type.VectorType()));
+ // Generate a ByteBuffer accessor for strings & vectors of scalars.
+ // e.g.
+ // val inventoryByteBuffer: ByteBuffer
+ // get = __vector_as_bytebuffer(14, 1)
+
+ GenerateGetterOneLine(
+ writer, field_name + "AsByteBuffer", "ByteBuffer", [&]() {
+ writer.SetValue("end", end_idx);
+ writer += "__vector_as_bytebuffer({{offset}}, {{end}})";
+ });
+
+ // Generate a ByteBuffer accessor for strings & vectors of scalars.
+ // e.g.
+ // fun inventoryInByteBuffer(_bb: Bytebuffer):
+ // ByteBuffer = __vector_as_bytebuffer(_bb, 14, 1)
+ GenerateFunOneLine(
+ writer, field_name + "InByteBuffer", "_bb: ByteBuffer",
+ "ByteBuffer", [&]() {
+ writer.SetValue("end", end_idx);
+ writer += "__vector_in_bytebuffer(_bb, {{offset}}, {{end}})";
+ });
+ }
+
+ // generate object accessors if is nested_flatbuffer
+ // fun testnestedflatbufferAsMonster() : Monster?
+ //{ return testnestedflatbufferAsMonster(new Monster()); }
+
+ if (field.nested_flatbuffer) {
+ auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
+ auto nested_method_name =
+ field_name + "As" + field.nested_flatbuffer->name;
+
+ GenerateGetterOneLine(
+ writer, nested_method_name, nested_type_name + "?", [&]() {
+ writer += nested_method_name + "(" + nested_type_name + "())";
+ });
+
+ GenerateFun(writer, nested_method_name, "obj: " + nested_type_name,
+ nested_type_name + "?", [&]() {
+ OffsetWrapper(
+ writer, offset_val,
+ [&]() {
+ writer +=
+ "obj.__assign(__indirect(__vector(o)), bb)";
+ },
+ [&]() { writer += "null"; });
+ });
+ }
+
+ // Generate mutators for scalar fields or vectors of scalars.
+ if (parser_.opts.mutable_buffer) {
+ auto value_type = field.value.type;
+ auto underlying_type = value_base_type == BASE_TYPE_VECTOR
+ ? value_type.VectorType()
+ : value_type;
+ auto name = "mutate" + MakeCamel(Esc(field.name), true);
+ auto size = NumToString(InlineSize(underlying_type));
+ auto params = Esc(field.name) + ": " + GenTypeGet(underlying_type);
+ // A vector mutator also needs the index of the vector element it should
+ // mutate.
+ if (value_base_type == BASE_TYPE_VECTOR) params.insert(0, "j: Int, ");
+
+ // Boolean parameters have to be explicitly converted to byte
+ // representation.
+ auto setter_parameter =
+ underlying_type.base_type == BASE_TYPE_BOOL
+ ? "(if(" + Esc(field.name) + ") 1 else 0).toByte()"
+ : Esc(field.name);
+
+ auto setter_index =
+ value_base_type == BASE_TYPE_VECTOR
+ ? "__vector(o) + j * " + size
+ : (struct_def.fixed ? "bb_pos + " + offset_val : "o + bb_pos");
+ if (IsScalar(value_base_type) ||
+ (value_base_type == BASE_TYPE_VECTOR &&
+ IsScalar(value_type.VectorType().base_type))) {
+ auto statements = [&]() {
+ writer.SetValue("bbsetter", ByteBufferSetter(underlying_type));
+ writer.SetValue("index", setter_index);
+ writer.SetValue("params", setter_parameter);
+ writer.SetValue("cast", CastToSigned(field));
+ if (struct_def.fixed) {
+ writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
+ } else {
+ OffsetWrapper(
+ writer, offset_val,
+ [&]() {
+ writer += "{{bbsetter}}({{index}}, {{params}}{{cast}})";
+ writer += "true";
+ },
+ [&]() { writer += "false"; });
+ }
+ };
+
+ if (struct_def.fixed) {
+ GenerateFunOneLine(writer, name, params, "ByteBuffer", statements);
+ } else {
+ GenerateFun(writer, name, params, "Boolean", statements);
+ }
+ }
+ }
+ }
+ if (struct_def.has_key && !struct_def.fixed) {
+ // Key Comparison method
+ GenerateOverrideFun(
+ writer, "keysCompare", "o1: Int, o2: Int, _bb: ByteBuffer", "Int",
+ [&]() {
+ if (key_field->value.type.base_type == BASE_TYPE_STRING) {
+ writer.SetValue("offset", NumToString(key_field->value.offset));
+ writer +=
+ " return compareStrings(__offset({{offset}}, o1, "
+ "_bb), __offset({{offset}}, o2, _bb), _bb)";
+
+ } else {
+ auto getter1 = GenLookupByKey(key_field, "_bb", "o1");
+ auto getter2 = GenLookupByKey(key_field, "_bb", "o2");
+ writer += "val val_1 = " + getter1;
+ writer += "val val_2 = " + getter2;
+ writer += "return (val_1 - val_2).sign";
+ }
+ });
+ }
+ }
+
+ static std::string CastToUsigned(const FieldDef &field) {
+ return CastToUsigned(field.value.type);
+ }
+
+ static std::string CastToUsigned(const Type type) {
+ switch (type.base_type) {
+ case BASE_TYPE_UINT: return ".toUInt()";
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_UTYPE: return ".toUByte()";
+ case BASE_TYPE_USHORT: return ".toUShort()";
+ case BASE_TYPE_ULONG: return ".toULong()";
+ case BASE_TYPE_VECTOR: return CastToUsigned(type.VectorType());
+ default: return "";
+ }
+ }
+
+ static std::string CastToSigned(const FieldDef &field) {
+ return CastToSigned(field.value.type);
+ }
+
+ static std::string CastToSigned(const Type type) {
+ switch (type.base_type) {
+ case BASE_TYPE_UINT: return ".toInt()";
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_UTYPE: return ".toByte()";
+ case BASE_TYPE_USHORT: return ".toShort()";
+ case BASE_TYPE_ULONG: return ".toLong()";
+ case BASE_TYPE_VECTOR: return CastToSigned(type.VectorType());
+ default: return "";
+ }
+ }
+
+ static std::string LiteralSuffix(const BaseType type) {
+ switch (type) {
+ case BASE_TYPE_UINT:
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_UTYPE:
+ case BASE_TYPE_USHORT: return "u";
+ case BASE_TYPE_ULONG: return "UL";
+ case BASE_TYPE_LONG: return "L";
+ default: return "";
+ }
+ }
+
+ void GenerateCompanionObject(CodeWriter &code,
+ const std::function<void()> &callback) const {
+ code += "companion object {";
+ code.IncrementIdentLevel();
+ callback();
+ code.DecrementIdentLevel();
+ code += "}";
+ }
+
+ // Generate a documentation comment, if available.
+ void GenerateComment(const std::vector<std::string> &dc, CodeWriter &writer,
+ const CommentConfig *config) const {
+ if (dc.begin() == dc.end()) {
+ // Don't output empty comment blocks with 0 lines of comment content.
+ return;
+ }
+
+ if (config != nullptr && config->first_line != nullptr) {
+ writer += std::string(config->first_line);
+ }
+ std::string line_prefix =
+ ((config != nullptr && config->content_line_prefix != nullptr)
+ ? config->content_line_prefix
+ : "///");
+ for (auto it = dc.begin(); it != dc.end(); ++it) {
+ writer += line_prefix + *it;
+ }
+ if (config != nullptr && config->last_line != nullptr) {
+ writer += std::string(config->last_line);
+ }
+ }
+
+ static void GenerateGetRootAsAccessors(const std::string &struct_name,
+ CodeWriter &writer) {
+ // Generate a special accessor for the table that when used as the root
+ // ex: fun getRootAsMonster(_bb: ByteBuffer): Monster {...}
+ writer.SetValue("gr_name", struct_name);
+ writer.SetValue("gr_method", "getRootAs" + struct_name);
+
+ // create convenience method that doesn't require an existing object
+ writer += "fun {{gr_method}}(_bb: ByteBuffer): {{gr_name}} = \\";
+ writer += "{{gr_method}}(_bb, {{gr_name}}())";
+
+ // create method that allows object reuse
+ // ex: fun Monster getRootAsMonster(_bb: ByteBuffer, obj: Monster) {...}
+ writer +=
+ "fun {{gr_method}}"
+ "(_bb: ByteBuffer, obj: {{gr_name}}): {{gr_name}} {";
+ writer.IncrementIdentLevel();
+ writer += "_bb.order(ByteOrder.LITTLE_ENDIAN)";
+ writer +=
+ "return (obj.__assign(_bb.getInt(_bb.position())"
+ " + _bb.position(), _bb))";
+ writer.DecrementIdentLevel();
+ writer += "}";
+ }
+
+ static void GenerateStaticConstructor(const StructDef &struct_def,
+ CodeWriter &code) {
+ // create a struct constructor function
+ auto params = StructConstructorParams(struct_def);
+ GenerateFun(code, "create" + Esc(struct_def.name), params, "Int", [&]() {
+ GenStructBody(struct_def, code, "");
+ code += "return builder.offset()";
+ });
+ }
+
+ static std::string StructConstructorParams(const StructDef &struct_def,
+ const std::string &prefix = "") {
+ // builder: FlatBufferBuilder
+ std::stringstream out;
+ auto field_vec = struct_def.fields.vec;
+ if (prefix.empty()) { out << "builder: FlatBufferBuilder"; }
+ for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
+ auto &field = **it;
+ if (IsStruct(field.value.type)) {
+ // Generate arguments for a struct inside a struct. To ensure
+ // names don't clash, and to make it obvious these arguments are
+ // constructing a nested struct, prefix the name with the field
+ // name.
+ out << StructConstructorParams(*field.value.type.struct_def,
+ prefix + (Esc(field.name) + "_"));
+ } else {
+ out << ", " << prefix << MakeCamel(Esc(field.name), false) << ": "
+ << GenTypeBasic(field.value.type.base_type);
+ }
+ }
+ return out.str();
+ }
+
+ static void GeneratePropertyOneLine(CodeWriter &writer,
+ const std::string &name,
+ const std::string &type,
+ const std::function<void()> &body) {
+ // Generates Kotlin getter for properties
+ // e.g.:
+ // val prop: Mytype = x
+ writer.SetValue("_name", name);
+ writer.SetValue("_type", type);
+ writer += "val {{_name}} : {{_type}} = \\";
+ body();
+ }
+ static void GenerateGetterOneLine(CodeWriter &writer, const std::string &name,
+ const std::string &type,
+ const std::function<void()> &body) {
+ // Generates Kotlin getter for properties
+ // e.g.:
+ // val prop: Mytype get() = x
+ writer.SetValue("_name", name);
+ writer.SetValue("_type", type);
+ writer += "val {{_name}} : {{_type}} get() = \\";
+ body();
+ }
+
+ static void GenerateGetter(CodeWriter &writer, const std::string &name,
+ const std::string &type,
+ const std::function<void()> &body) {
+ // Generates Kotlin getter for properties
+ // e.g.:
+ // val prop: Mytype
+ // get() = {
+ // return x
+ // }
+ writer.SetValue("name", name);
+ writer.SetValue("type", type);
+ writer += "val {{name}} : {{type}}";
+ writer.IncrementIdentLevel();
+ writer += "get() {";
+ writer.IncrementIdentLevel();
+ body();
+ writer.DecrementIdentLevel();
+ writer += "}";
+ writer.DecrementIdentLevel();
+ }
+
+ static void GenerateFun(CodeWriter &writer, const std::string &name,
+ const std::string &params,
+ const std::string &returnType,
+ const std::function<void()> &body) {
+ // Generates Kotlin function
+ // e.g.:
+ // fun path(j: Int): Vec3 {
+ // return path(Vec3(), j)
+ // }
+ auto noreturn = returnType.empty();
+ writer.SetValue("name", name);
+ writer.SetValue("params", params);
+ writer.SetValue("return_type", noreturn ? "" : ": " + returnType);
+ writer += "fun {{name}}({{params}}) {{return_type}} {";
+ writer.IncrementIdentLevel();
+ body();
+ writer.DecrementIdentLevel();
+ writer += "}";
+ }
+
+ static void GenerateFunOneLine(CodeWriter &writer, const std::string &name,
+ const std::string &params,
+ const std::string &returnType,
+ const std::function<void()> &body) {
+ // Generates Kotlin function
+ // e.g.:
+ // fun path(j: Int): Vec3 = return path(Vec3(), j)
+ writer.SetValue("name", name);
+ writer.SetValue("params", params);
+ writer.SetValue("return_type_p",
+ returnType.empty() ? "" : " : " + returnType);
+ writer += "fun {{name}}({{params}}){{return_type_p}} = \\";
+ body();
+ }
+
+ static void GenerateOverrideFun(CodeWriter &writer, const std::string &name,
+ const std::string &params,
+ const std::string &returnType,
+ const std::function<void()> &body) {
+ // Generates Kotlin function
+ // e.g.:
+ // override fun path(j: Int): Vec3 = return path(Vec3(), j)
+ writer += "override \\";
+ GenerateFun(writer, name, params, returnType, body);
+ }
+
+ static void GenerateOverrideFunOneLine(CodeWriter &writer,
+ const std::string &name,
+ const std::string &params,
+ const std::string &returnType,
+ const std::string &statement) {
+ // Generates Kotlin function
+ // e.g.:
+ // override fun path(j: Int): Vec3 = return path(Vec3(), j)
+ writer.SetValue("name", name);
+ writer.SetValue("params", params);
+ writer.SetValue("return_type",
+ returnType.empty() ? "" : " : " + returnType);
+ writer += "override fun {{name}}({{params}}){{return_type}} = \\";
+ writer += statement;
+ }
+
+ static std::string OffsetWrapperOneLine(const std::string &offset,
+ const std::string &found,
+ const std::string &not_found) {
+ return "val o = __offset(" + offset + "); return if (o != 0) " + found +
+ " else " + not_found;
+ }
+
+ static void OffsetWrapper(CodeWriter &code, const std::string &offset,
+ const std::function<void()> &found,
+ const std::function<void()> &not_found) {
+ code += "val o = __offset(" + offset + ")";
+ code += "return if (o != 0) {";
+ code.IncrementIdentLevel();
+ found();
+ code.DecrementIdentLevel();
+ code += "} else {";
+ code.IncrementIdentLevel();
+ not_found();
+ code.DecrementIdentLevel();
+ code += "}";
+ }
+
+ static std::string Indirect(const std::string &index, bool fixed) {
+ // We apply __indirect() and struct is not fixed.
+ if (!fixed) return "__indirect(" + index + ")";
+ return index;
+ }
+
+ static std::string NotFoundReturn(BaseType el) {
+ switch (el) {
+ case BASE_TYPE_FLOAT: return "0.0f";
+ case BASE_TYPE_DOUBLE: return "0.0";
+ case BASE_TYPE_BOOL: return "false";
+ case BASE_TYPE_LONG:
+ case BASE_TYPE_INT:
+ case BASE_TYPE_CHAR:
+ case BASE_TYPE_SHORT: return "0";
+ case BASE_TYPE_UINT:
+ case BASE_TYPE_UCHAR:
+ case BASE_TYPE_USHORT:
+ case BASE_TYPE_UTYPE: return "0u";
+ case BASE_TYPE_ULONG: return "0uL";
+ default: return "null";
+ }
+ }
+
+ // This tracks the current namespace used to determine if a type need to be
+ // prefixed by its namespace
+ const Namespace *cur_name_space_;
+};
+} // namespace kotlin
+
+bool GenerateKotlin(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ kotlin::KotlinGenerator generator(parser, path, file_name);
+ return generator.generate();
+}
+} // namespace flatbuffers
diff --git a/src/idl_gen_lobster.cpp b/src/idl_gen_lobster.cpp
index fe23d970..0c600a74 100644
--- a/src/idl_gen_lobster.cpp
+++ b/src/idl_gen_lobster.cpp
@@ -27,14 +27,17 @@ namespace lobster {
class LobsterGenerator : public BaseGenerator {
public:
- LobsterGenerator(const Parser &parser, const std::string &path,
- const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "" /* not used */, "_") {
- static const char * const keywords[] = {
- "nil", "true", "false", "return", "struct", "value", "include", "int",
- "float", "string", "any", "def", "is", "from", "program", "private",
- "coroutine", "resource", "enum", "typeof", "var", "let", "pakfile",
- "switch", "case", "default", "namespace", "not", "and", "or", "bool",
+ LobsterGenerator(const Parser &parser, const std::string &path,
+ const std::string &file_name)
+ : BaseGenerator(parser, path, file_name, "" /* not used */, "_",
+ "lobster") {
+ static const char *const keywords[] = {
+ "nil", "true", "false", "return", "struct", "class",
+ "import", "int", "float", "string", "any", "def",
+ "is", "from", "program", "private", "coroutine", "resource",
+ "enum", "typeof", "var", "let", "pakfile", "switch",
+ "case", "default", "namespace", "not", "and", "or",
+ "bool",
};
keywords_.insert(std::begin(keywords), std::end(keywords));
}
@@ -66,47 +69,53 @@ class LobsterGenerator : public BaseGenerator {
std::string LobsterType(const Type &type) {
if (IsFloat(type.base_type)) return "float";
+ if (IsScalar(type.base_type) && type.enum_def)
+ return NormalizedName(*type.enum_def);
+ if (!IsScalar(type.base_type)) return "flatbuffers_offset";
return "int";
}
// Returns the method name for use with add/put calls.
std::string GenMethod(const Type &type) {
return IsScalar(type.base_type)
- ? MakeCamel(GenTypeBasic(type))
- : (IsStruct(type) ? "Struct" : "UOffsetTRelative");
+ ? MakeCamel(GenTypeBasic(type))
+ : (IsStruct(type) ? "Struct" : "UOffsetTRelative");
}
// This uses Python names for now..
std::string GenTypeBasic(const Type &type) {
+ // clang-format off
static const char *ctypename[] = {
- // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \
#PTYPE,
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- // clang-format on
};
+ // clang-format on
return ctypename[type.base_type];
}
// Generate a struct field, conditioned on its child type(s).
- void GenStructAccessor(const StructDef &struct_def,
- const FieldDef &field, std::string *code_ptr) {
+ void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, nullptr, " ");
std::string &code = *code_ptr;
auto offsets = NumToString(field.value.offset);
auto def = " def " + NormalizedName(field);
if (IsScalar(field.value.type.base_type)) {
+ std::string acc;
if (struct_def.fixed) {
- code += def + "():\n buf_.read_" +
- GenTypeName(field.value.type) + "_le(pos_ + " + offsets +
- ")\n";
+ acc = "buf_.read_" + GenTypeName(field.value.type) + "_le(pos_ + " +
+ offsets + ")";
+
} else {
- code += def + "():\n buf_.flatbuffers_field_" +
- GenTypeName(field.value.type) + "(pos_, " + offsets + ", " +
- field.value.constant + ")\n";
+ acc = "buf_.flatbuffers_field_" + GenTypeName(field.value.type) +
+ "(pos_, " + offsets + ", " + field.value.constant + ")";
}
+ if (field.value.type.enum_def)
+ acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")";
+ code += def + "():\n return " + acc + "\n";
return;
}
switch (field.value.type.base_type) {
@@ -114,22 +123,23 @@ class LobsterGenerator : public BaseGenerator {
auto name = NamespacedName(*field.value.type.struct_def);
code += def + "():\n ";
if (struct_def.fixed) {
- code += name + "{ buf_, pos_ + " + offsets + " }\n";
+ code += "return " + name + "{ buf_, pos_ + " + offsets + " }\n";
} else {
- code += std::string("o := buf_.flatbuffers_field_") +
+ code += std::string("let o = buf_.flatbuffers_field_") +
(field.value.type.struct_def->fixed ? "struct" : "table") +
- "(pos_, " + offsets + ")\n if o: " + name +
+ "(pos_, " + offsets + ")\n return if o: " + name +
" { buf_, o } else: nil\n";
}
break;
}
case BASE_TYPE_STRING:
- code += def + "():\n buf_.flatbuffers_field_string(pos_, " +
+ code += def +
+ "():\n return buf_.flatbuffers_field_string(pos_, " +
offsets + ")\n";
break;
case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType();
- code += def + "(i:int):\n ";
+ code += def + "(i:int):\n return ";
if (vectortype.base_type == BASE_TYPE_STRUCT) {
auto start = "buf_.flatbuffers_field_vector(pos_, " + offsets +
") + i * " + NumToString(InlineSize(vectortype));
@@ -153,7 +163,7 @@ class LobsterGenerator : public BaseGenerator {
it != field.value.type.enum_def->Vals().end(); ++it) {
auto &ev = **it;
if (ev.IsNonZero()) {
- code += def + "_as_" + ev.name + "():\n " +
+ code += def + "_as_" + ev.name + "():\n return " +
NamespacedName(*ev.union_type.struct_def) +
" { buf_, buf_.flatbuffers_field_table(pos_, " + offsets +
") }\n";
@@ -165,29 +175,38 @@ class LobsterGenerator : public BaseGenerator {
}
if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code += def +
- "_length():\n buf_.flatbuffers_field_vector_len(pos_, " +
+ "_length():\n return "
+ "buf_.flatbuffers_field_vector_len(pos_, " +
offsets + ")\n";
}
}
// Generate table constructors, conditioned on its members' types.
- void GenTableBuilders(const StructDef &struct_def,
- std::string *code_ptr) {
+ void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
- code += "def " + NormalizedName(struct_def) +
- "Start(b_:flatbuffers_builder):\n b_.StartObject(" +
- NumToString(struct_def.fields.vec.size()) + ")\n";
+ code += "struct " + NormalizedName(struct_def) +
+ "Builder:\n b_:flatbuffers_builder\n";
+ code += " def start():\n b_.StartObject(" +
+ NumToString(struct_def.fields.vec.size()) +
+ ")\n return this\n";
for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
+ it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) continue;
auto offset = it - struct_def.fields.vec.begin();
- code += "def " + NormalizedName(struct_def) + "Add" +
- MakeCamel(NormalizedName(field)) + "(b_:flatbuffers_builder, " +
+ code += " def add_" + NormalizedName(field) + "(" +
NormalizedName(field) + ":" + LobsterType(field.value.type) +
- "):\n b_.Prepend" + GenMethod(field.value.type) + "Slot(" +
- NumToString(offset) + ", " + NormalizedName(field) + ", " +
- field.value.constant + ")\n";
+ "):\n b_.Prepend" + GenMethod(field.value.type) + "Slot(" +
+ NumToString(offset) + ", " + NormalizedName(field);
+ if (IsScalar(field.value.type.base_type))
+ code += ", " + field.value.constant;
+ code += ")\n return this\n";
+ }
+ code += " def end():\n return b_.EndObject()\n\n";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code += "def " + NormalizedName(struct_def) + "Start" +
MakeCamel(NormalizedName(field)) +
@@ -195,8 +214,8 @@ class LobsterGenerator : public BaseGenerator {
auto vector_type = field.value.type.VectorType();
auto alignment = InlineAlignment(vector_type);
auto elem_size = InlineSize(vector_type);
- code += NumToString(elem_size) + ", n_, " + NumToString(alignment) +
- ")\n";
+ code +=
+ NumToString(elem_size) + ", n_, " + NumToString(alignment) + ")\n";
if (vector_type.base_type != BASE_TYPE_STRUCT ||
!vector_type.struct_def->fixed) {
code += "def " + NormalizedName(struct_def) + "Create" +
@@ -204,22 +223,20 @@ class LobsterGenerator : public BaseGenerator {
"Vector(b_:flatbuffers_builder, v_:[" +
LobsterType(vector_type) + "]):\n b_.StartVector(" +
NumToString(elem_size) + ", v_.length, " +
- NumToString(alignment) +
- ")\n reverse(v_) e_: b_.Prepend" +
+ NumToString(alignment) + ")\n reverse(v_) e_: b_.Prepend" +
GenMethod(vector_type) +
- "(e_)\n b_.EndVector(v_.length)\n";
+ "(e_)\n return b_.EndVector(v_.length)\n";
}
+ code += "\n";
}
}
- code += "def " + NormalizedName(struct_def) +
- "End(b_:flatbuffers_builder):\n b_.EndObject()\n\n";
}
void GenStructPreDecl(const StructDef &struct_def, std::string *code_ptr) {
if (struct_def.generated) return;
std::string &code = *code_ptr;
CheckNameSpace(struct_def, &code);
- code += "struct " + NormalizedName(struct_def) + "\n\n";
+ code += "class " + NormalizedName(struct_def) + "\n\n";
}
// Generate struct or table methods.
@@ -228,9 +245,9 @@ class LobsterGenerator : public BaseGenerator {
std::string &code = *code_ptr;
CheckNameSpace(struct_def, &code);
GenComment(struct_def.doc_comment, code_ptr, nullptr, "");
- code += "struct " + NormalizedName(struct_def) + " : flatbuffers_handle\n";
+ code += "class " + NormalizedName(struct_def) + " : flatbuffers_handle\n";
for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
+ it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) continue;
GenStructAccessor(struct_def, field, code_ptr);
@@ -239,8 +256,8 @@ class LobsterGenerator : public BaseGenerator {
if (!struct_def.fixed) {
// Generate a special accessor for the table that has been declared as
// the root type.
- code += "def GetRootAs" + NormalizedName(struct_def) + "(buf:string): " +
- NormalizedName(struct_def) +
+ code += "def GetRootAs" + NormalizedName(struct_def) +
+ "(buf:string): return " + NormalizedName(struct_def) +
" { buf, buf.flatbuffers_indirect(0) }\n\n";
}
if (struct_def.fixed) {
@@ -258,22 +275,20 @@ class LobsterGenerator : public BaseGenerator {
std::string &code = *code_ptr;
CheckNameSpace(enum_def, &code);
GenComment(enum_def.doc_comment, code_ptr, nullptr, "");
- code += "enum + \n";
+ code += "enum " + NormalizedName(enum_def) + ":\n";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
auto &ev = **it;
GenComment(ev.doc_comment, code_ptr, nullptr, " ");
code += " " + enum_def.name + "_" + NormalizedName(ev) + " = " +
- NumToString(ev.value);
- if (it + 1 != enum_def.Vals().end()) code += ",";
- code += "\n";
+ enum_def.ToString(ev) + "\n";
}
code += "\n";
}
// Recursively generate arguments for a constructor, to deal with nested
// structs.
- void StructBuilderArgs(const StructDef &struct_def,
- const char *nameprefix, std::string *code_ptr) {
+ void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
+ std::string *code_ptr) {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
@@ -282,7 +297,8 @@ class LobsterGenerator : public BaseGenerator {
// don't clash, and to make it obvious these arguments are constructing
// a nested struct, prefix the name with the field name.
StructBuilderArgs(*field.value.type.struct_def,
- (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
+ (nameprefix + (NormalizedName(field) + "_")).c_str(),
+ code_ptr);
} else {
std::string &code = *code_ptr;
code += ", " + (nameprefix + NormalizedName(field)) + ":" +
@@ -293,8 +309,8 @@ class LobsterGenerator : public BaseGenerator {
// Recursively generate struct construction statements and instert manual
// padding.
- void StructBuilderBody(const StructDef &struct_def,
- const char *nameprefix, std::string *code_ptr) {
+ void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
+ std::string *code_ptr) {
std::string &code = *code_ptr;
code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " +
NumToString(struct_def.bytesize) + ")\n";
@@ -305,7 +321,8 @@ class LobsterGenerator : public BaseGenerator {
code += " b_.Pad(" + NumToString(field.padding) + ")\n";
if (IsStruct(field.value.type)) {
StructBuilderBody(*field.value.type.struct_def,
- (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
+ (nameprefix + (NormalizedName(field) + "_")).c_str(),
+ code_ptr);
} else {
code += " b_.Prepend" + GenMethod(field.value.type) + "(" +
nameprefix + NormalizedName(field) + ")\n";
@@ -314,11 +331,10 @@ class LobsterGenerator : public BaseGenerator {
}
// Create a struct with a builder and the struct's arguments.
- void GenStructBuilder(const StructDef &struct_def,
- std::string *code_ptr) {
+ void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
- code += "def Create" + NormalizedName(struct_def) +
- "(b_:flatbuffers_builder";
+ code +=
+ "def Create" + NormalizedName(struct_def) + "(b_:flatbuffers_builder";
StructBuilderArgs(struct_def, "", code_ptr);
code += "):\n";
StructBuilderBody(struct_def, "", code_ptr);
@@ -336,7 +352,7 @@ class LobsterGenerator : public BaseGenerator {
bool generate() {
std::string code;
code += std::string("// ") + FlatBuffersGeneratedWarning() +
- "\n\ninclude \"flatbuffers.lobster\"\n\n";
+ "\nimport flatbuffers\n\n";
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
++it) {
auto &enum_def = **it;
@@ -352,7 +368,7 @@ class LobsterGenerator : public BaseGenerator {
auto &struct_def = **it;
GenStruct(struct_def, &code);
}
- return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(),
+ return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(),
code, false);
}
@@ -364,7 +380,7 @@ class LobsterGenerator : public BaseGenerator {
} // namespace lobster
bool GenerateLobster(const Parser &parser, const std::string &path,
- const std::string &file_name) {
+ const std::string &file_name) {
lobster::LobsterGenerator generator(parser, path, file_name);
return generator.generate();
}
diff --git a/src/idl_gen_lua.cpp b/src/idl_gen_lua.cpp
index b26f9070..3d9ad9bc 100644
--- a/src/idl_gen_lua.cpp
+++ b/src/idl_gen_lua.cpp
@@ -14,715 +14,710 @@
* limitations under the License.
*/
- // independent from idl_parser, since this code is not needed for most clients
+// independent from idl_parser, since this code is not needed for most clients
#include <string>
+#include <unordered_set>
#include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-#include <unordered_set>
-
namespace flatbuffers {
namespace lua {
- // Hardcode spaces per indentation.
- const char * Indent = " ";
- const char * Comment = "-- ";
- const char * End = "end\n";
- const char * EndFunc = "end\n";
- const char * SelfData = "self.view";
- const char * SelfDataPos = "self.view.pos";
- const char * SelfDataBytes = "self.view.bytes";
-
- class LuaGenerator : public BaseGenerator {
- public:
- LuaGenerator(const Parser &parser, const std::string &path,
- const std::string &file_name)
+// Hardcode spaces per indentation.
+const CommentConfig def_comment = { nullptr, "--", nullptr };
+const char *Indent = " ";
+const char *Comment = "-- ";
+const char *End = "end\n";
+const char *EndFunc = "end\n";
+const char *SelfData = "self.view";
+const char *SelfDataPos = "self.view.pos";
+const char *SelfDataBytes = "self.view.bytes";
+
+class LuaGenerator : public BaseGenerator {
+ public:
+ LuaGenerator(const Parser &parser, const std::string &path,
+ const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */,
- "" /* not used */) {
- static const char * const keywords[] = {
- "and",
- "break",
- "do",
- "else",
- "elseif",
- "end",
- "false",
- "for",
- "function",
- "goto",
- "if",
- "in",
- "local",
- "nil",
- "not",
- "or",
- "repeat",
- "return",
- "then",
- "true",
- "until",
- "while"
- };
- keywords_.insert(std::begin(keywords), std::end(keywords));
- }
-
- // Most field accessors need to retrieve and test the field offset first,
- // this is the prefix code for that.
- std::string OffsetPrefix(const FieldDef &field) {
- return std::string(Indent) +
- "local o = " + SelfData + ":Offset(" + NumToString(field.value.offset) + ")\n" +
- Indent + "if o ~= 0 then\n";
- }
-
- // Begin a class declaration.
- void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "local " + NormalizedName(struct_def) + " = {} -- the module\n";
- code += "local " + NormalizedMetaName(struct_def) + " = {} -- the class metatable\n";
- code += "\n";
- }
-
- // Begin enum code with a class declaration.
- void BeginEnum(const std::string class_name, std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "local " + class_name + " = {\n";
- }
-
- std::string EscapeKeyword(const std::string &name) const {
- return keywords_.find(name) == keywords_.end() ? name : "_" + name;
- }
-
- std::string NormalizedName(const Definition &definition) const {
- return EscapeKeyword(definition.name);
- }
-
- std::string NormalizedName(const EnumVal &ev) const {
- return EscapeKeyword(ev.name);
- }
-
- std::string NormalizedMetaName(const Definition &definition) const {
- return EscapeKeyword(definition.name) + "_mt";
- }
-
- // A single enum member.
- void EnumMember(const EnumDef &enum_def, const EnumVal &ev, std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += std::string(Indent) + NormalizedName(ev) + " = " + NumToString(ev.value) + ",\n";
- (void)enum_def;
- }
-
- // End enum code.
- void EndEnum(std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "}\n";
- }
-
- void GenerateNewObjectPrototype(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
-
- code += "function " + NormalizedName(struct_def) + ".New()\n";
- code += std::string(Indent) + "local o = {}\n";
- code += std::string(Indent) + "setmetatable(o, {__index = " + NormalizedMetaName(struct_def) + "})\n";
- code += std::string(Indent) + "return o\n";
- code += EndFunc;
- }
-
- // Initialize a new struct or table from existing data.
- void NewRootTypeFromBuffer(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
-
- code += "function " + NormalizedName(struct_def) + ".GetRootAs" + NormalizedName(struct_def) + "(buf, offset)\n";
- code += std::string(Indent) + "local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)\n";
- code += std::string(Indent) + "local o = " + NormalizedName(struct_def) + ".New()\n";
- code += std::string(Indent) + "o:Init(buf, n + offset)\n";
- code += std::string(Indent) + "return o\n";
- code += EndFunc;
- }
-
- // Initialize an existing object with other data, to avoid an allocation.
- void InitializeExisting(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
-
- GenReceiver(struct_def, code_ptr);
- code += "Init(buf, pos)\n";
- code += std::string(Indent) + SelfData + " = flatbuffers.view.New(buf, pos)\n";
- code += EndFunc;
- }
-
- // Get the length of a vector.
- void GetVectorLen(const StructDef &struct_def, const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
-
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field)) + "Length()\n";
- code += OffsetPrefix(field);
- code += std::string(Indent) + Indent + "return " + SelfData + ":VectorLen(o)\n";
- code += std::string(Indent) + End;
+ "" /* not used */, "lua") {
+ static const char *const keywords[] = {
+ "and", "break", "do", "else", "elseif", "end", "false", "for",
+ "function", "goto", "if", "in", "local", "nil", "not", "or",
+ "repeat", "return", "then", "true", "until", "while"
+ };
+ keywords_.insert(std::begin(keywords), std::end(keywords));
+ }
+
+ // Most field accessors need to retrieve and test the field offset first,
+ // this is the prefix code for that.
+ std::string OffsetPrefix(const FieldDef &field) {
+ return std::string(Indent) + "local o = " + SelfData + ":Offset(" +
+ NumToString(field.value.offset) + ")\n" + Indent +
+ "if o ~= 0 then\n";
+ }
+
+ // Begin a class declaration.
+ void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "local " + NormalizedName(struct_def) + " = {} -- the module\n";
+ code += "local " + NormalizedMetaName(struct_def) +
+ " = {} -- the class metatable\n";
+ code += "\n";
+ }
+
+ // Begin enum code with a class declaration.
+ void BeginEnum(const std::string &class_name, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "local " + class_name + " = {\n";
+ }
+
+ std::string EscapeKeyword(const std::string &name) const {
+ return keywords_.find(name) == keywords_.end() ? name : "_" + name;
+ }
+
+ std::string NormalizedName(const Definition &definition) const {
+ return EscapeKeyword(definition.name);
+ }
+
+ std::string NormalizedName(const EnumVal &ev) const {
+ return EscapeKeyword(ev.name);
+ }
+
+ std::string NormalizedMetaName(const Definition &definition) const {
+ return EscapeKeyword(definition.name) + "_mt";
+ }
+
+ // A single enum member.
+ void EnumMember(const EnumDef &enum_def, const EnumVal &ev,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += std::string(Indent) + NormalizedName(ev) + " = " +
+ enum_def.ToString(ev) + ",\n";
+ }
+
+ // End enum code.
+ void EndEnum(std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "}\n";
+ }
+
+ void GenerateNewObjectPrototype(const StructDef &struct_def,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "function " + NormalizedName(struct_def) + ".New()\n";
+ code += std::string(Indent) + "local o = {}\n";
+ code += std::string(Indent) +
+ "setmetatable(o, {__index = " + NormalizedMetaName(struct_def) +
+ "})\n";
+ code += std::string(Indent) + "return o\n";
+ code += EndFunc;
+ }
+
+ // Initialize a new struct or table from existing data.
+ void NewRootTypeFromBuffer(const StructDef &struct_def,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "function " + NormalizedName(struct_def) + ".GetRootAs" +
+ NormalizedName(struct_def) + "(buf, offset)\n";
+ code += std::string(Indent) +
+ "local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)\n";
+ code += std::string(Indent) + "local o = " + NormalizedName(struct_def) +
+ ".New()\n";
+ code += std::string(Indent) + "o:Init(buf, n + offset)\n";
+ code += std::string(Indent) + "return o\n";
+ code += EndFunc;
+ }
+
+ // Initialize an existing object with other data, to avoid an allocation.
+ void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ GenReceiver(struct_def, code_ptr);
+ code += "Init(buf, pos)\n";
+ code +=
+ std::string(Indent) + SelfData + " = flatbuffers.view.New(buf, pos)\n";
+ code += EndFunc;
+ }
+
+ // Get the length of a vector.
+ void GetVectorLen(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field)) + "Length()\n";
+ code += OffsetPrefix(field);
+ code +=
+ std::string(Indent) + Indent + "return " + SelfData + ":VectorLen(o)\n";
+ code += std::string(Indent) + End;
+ code += std::string(Indent) + "return 0\n";
+ code += EndFunc;
+ }
+
+ // Get the value of a struct's scalar.
+ void GetScalarFieldOfStruct(const StructDef &struct_def,
+ const FieldDef &field, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ std::string getter = GenGetter(field.value.type);
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ code += "()\n";
+ code += std::string(Indent) + "return " + getter;
+ code += std::string(SelfDataPos) + " + " + NumToString(field.value.offset) +
+ ")\n";
+ code += EndFunc;
+ }
+
+ // Get the value of a table's scalar.
+ void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ std::string getter = GenGetter(field.value.type);
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ code += "()\n";
+ code += OffsetPrefix(field);
+ getter += std::string("o + ") + SelfDataPos + ")";
+ auto is_bool = field.value.type.base_type == BASE_TYPE_BOOL;
+ if (is_bool) { getter = "(" + getter + " ~= 0)"; }
+ code += std::string(Indent) + Indent + "return " + getter + "\n";
+ code += std::string(Indent) + End;
+ std::string default_value;
+ if (is_bool) {
+ default_value = field.value.constant == "0" ? "false" : "true";
+ } else {
+ default_value = field.value.constant;
+ }
+ code += std::string(Indent) + "return " + default_value + "\n";
+ code += EndFunc;
+ }
+
+ // Get a struct by initializing an existing struct.
+ // Specific to Struct.
+ void GetStructFieldOfStruct(const StructDef &struct_def,
+ const FieldDef &field, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ code += "(obj)\n";
+ code += std::string(Indent) + "obj:Init(" + SelfDataBytes + ", " +
+ SelfDataPos + " + ";
+ code += NumToString(field.value.offset) + ")\n";
+ code += std::string(Indent) + "return obj\n";
+ code += EndFunc;
+ }
+
+ // Get a struct by initializing an existing struct.
+ // Specific to Table.
+ void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ code += "()\n";
+ code += OffsetPrefix(field);
+ if (field.value.type.struct_def->fixed) {
+ code +=
+ std::string(Indent) + Indent + "local x = o + " + SelfDataPos + "\n";
+ } else {
+ code += std::string(Indent) + Indent + "local x = " + SelfData +
+ ":Indirect(o + " + SelfDataPos + ")\n";
+ }
+ code += std::string(Indent) + Indent + "local obj = require('" +
+ TypeNameWithNamespace(field) + "').New()\n";
+ code +=
+ std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
+ code += std::string(Indent) + Indent + "return obj\n";
+ code += std::string(Indent) + End;
+ code += EndFunc;
+ }
+
+ // Get the value of a string.
+ void GetStringField(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ code += "()\n";
+ code += OffsetPrefix(field);
+ code +=
+ std::string(Indent) + Indent + "return " + GenGetter(field.value.type);
+ code += std::string("o + ") + SelfDataPos + ")\n";
+ code += std::string(Indent) + End;
+ code += EndFunc;
+ }
+
+ // Get the value of a union from an object.
+ void GetUnionField(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field)) + "()\n";
+ code += OffsetPrefix(field);
+
+ // TODO(rw): this works and is not the good way to it:
+ // bool is_native_table = TypeName(field) == "*flatbuffers.Table";
+ // if (is_native_table) {
+ // code += std::string(Indent) + Indent + "from flatbuffers.table import
+ // Table\n";
+ //} else {
+ // code += std::string(Indent) + Indent +
+ // code += "from ." + TypeName(field) + " import " + TypeName(field) +
+ // "\n";
+ //}
+ code +=
+ std::string(Indent) + Indent +
+ "local obj = "
+ "flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)\n";
+ code += std::string(Indent) + Indent + GenGetter(field.value.type) +
+ "obj, o)\n";
+ code += std::string(Indent) + Indent + "return obj\n";
+ code += std::string(Indent) + End;
+ code += EndFunc;
+ }
+
+ // Get the value of a vector's struct member.
+ void GetMemberOfVectorOfStruct(const StructDef &struct_def,
+ const FieldDef &field, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ auto vectortype = field.value.type.VectorType();
+
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ code += "(j)\n";
+ code += OffsetPrefix(field);
+ code +=
+ std::string(Indent) + Indent + "local x = " + SelfData + ":Vector(o)\n";
+ code += std::string(Indent) + Indent + "x = x + ((j-1) * ";
+ code += NumToString(InlineSize(vectortype)) + ")\n";
+ if (!(vectortype.struct_def->fixed)) {
+ code +=
+ std::string(Indent) + Indent + "x = " + SelfData + ":Indirect(x)\n";
+ }
+ code += std::string(Indent) + Indent + "local obj = require('" +
+ TypeNameWithNamespace(field) + "').New()\n";
+ code +=
+ std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
+ code += std::string(Indent) + Indent + "return obj\n";
+ code += std::string(Indent) + End;
+ code += EndFunc;
+ }
+
+ // Get the value of a vector's non-struct member. Uses a named return
+ // argument to conveniently set the zero value for the result.
+ void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ auto vectortype = field.value.type.VectorType();
+
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ code += "(j)\n";
+ code += OffsetPrefix(field);
+ code +=
+ std::string(Indent) + Indent + "local a = " + SelfData + ":Vector(o)\n";
+ code += std::string(Indent) + Indent;
+ code += "return " + GenGetter(field.value.type);
+ code += "a + ((j-1) * ";
+ code += NumToString(InlineSize(vectortype)) + "))\n";
+ code += std::string(Indent) + End;
+ if (vectortype.base_type == BASE_TYPE_STRING) {
+ code += std::string(Indent) + "return ''\n";
+ } else {
code += std::string(Indent) + "return 0\n";
- code += EndFunc;
- }
-
- // Get the value of a struct's scalar.
- void GetScalarFieldOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- std::string getter = GenGetter(field.value.type);
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field));
- code += "()\n";
- code += std::string(Indent) + "return " + getter;
- code += std::string(SelfDataPos) + " + " + NumToString(field.value.offset) + ")\n";
- code += EndFunc;
}
-
- // Get the value of a table's scalar.
- void GetScalarFieldOfTable(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- std::string getter = GenGetter(field.value.type);
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field));
- code += "()\n";
- code += OffsetPrefix(field);
- getter += std::string("o + ") + SelfDataPos + ")";
- auto is_bool = field.value.type.base_type == BASE_TYPE_BOOL;
- if (is_bool) {
- getter = "(" + getter + " ~= 0)";
+ code += EndFunc;
+ }
+
+ // Begin the creator function signature.
+ void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+
+ code += "function " + NormalizedName(struct_def) + ".Create" +
+ NormalizedName(struct_def);
+ code += "(builder";
+ }
+
+ // Recursively generate arguments for a constructor, to deal with nested
+ // structs.
+ void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
+ std::string *code_ptr) {
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (IsStruct(field.value.type)) {
+ // Generate arguments for a struct inside a struct. To ensure names
+ // don't clash, and to make it obvious these arguments are constructing
+ // a nested struct, prefix the name with the field name.
+ StructBuilderArgs(*field.value.type.struct_def,
+ (nameprefix + (NormalizedName(field) + "_")).c_str(),
+ code_ptr);
+ } else {
+ std::string &code = *code_ptr;
+ code += std::string(", ") + nameprefix;
+ code += MakeCamel(NormalizedName(field), false);
}
- code += std::string(Indent) + Indent + "return " + getter + "\n";
- code += std::string(Indent) + End;
- std::string default_value;
- if (is_bool) {
- default_value = field.value.constant == "0" ? "false" : "true";
- }
- else {
- default_value = field.value.constant;
- }
- code += std::string(Indent) + "return " + default_value + "\n";
- code += EndFunc;
- }
-
- // Get a struct by initializing an existing struct.
- // Specific to Struct.
- void GetStructFieldOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field));
- code += "(obj)\n";
- code += std::string(Indent) + "obj:Init(" + SelfDataBytes + ", " + SelfDataPos + " + ";
- code += NumToString(field.value.offset) + ")\n";
- code += std::string(Indent) + "return obj\n";
- code += EndFunc;
- }
-
- // Get a struct by initializing an existing struct.
- // Specific to Table.
- void GetStructFieldOfTable(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field));
- code += "()\n";
- code += OffsetPrefix(field);
- if (field.value.type.struct_def->fixed) {
- code += std::string(Indent) + Indent + "local x = o + " + SelfDataPos + "\n";
- }
- else {
- code += std::string(Indent) + Indent + "local x = " + SelfData + ":Indirect(o + " + SelfDataPos + ")\n";
- }
- code += std::string(Indent) + Indent + "local obj = require('" + TypeNameWithNamespace(field) + "').New()\n";
- code += std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
- code += std::string(Indent) + Indent + "return obj\n";
- code += std::string(Indent) + End;
- code += EndFunc;
- }
-
- // Get the value of a string.
- void GetStringField(const StructDef &struct_def, const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field));
- code += "()\n";
- code += OffsetPrefix(field);
- code += std::string(Indent) + Indent + "return " + GenGetter(field.value.type);
- code += std::string("o + ") + SelfDataPos + ")\n";
- code += std::string(Indent) + End;
- code += EndFunc;
- }
-
- // Get the value of a union from an object.
- void GetUnionField(const StructDef &struct_def, const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field)) + "()\n";
- code += OffsetPrefix(field);
-
- // TODO(rw): this works and is not the good way to it:
- //bool is_native_table = TypeName(field) == "*flatbuffers.Table";
- //if (is_native_table) {
- // code += std::string(Indent) + Indent + "from flatbuffers.table import Table\n";
- //} else {
- // code += std::string(Indent) + Indent +
- // code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
- //}
- code += std::string(Indent) + Indent + "local obj = flatbuffers.view.New(require('flatbuffers.binaryarray').New(0), 0)\n";
- code += std::string(Indent) + Indent + GenGetter(field.value.type) + "obj, o)\n";
- code += std::string(Indent) + Indent + "return obj\n";
- code += std::string(Indent) + End;
- code += EndFunc;
- }
-
- // Get the value of a vector's struct member.
- void GetMemberOfVectorOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- auto vectortype = field.value.type.VectorType();
-
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field));
- code += "(j)\n";
- code += OffsetPrefix(field);
- code += std::string(Indent) + Indent + "local x = " + SelfData + ":Vector(o)\n";
- code += std::string(Indent) + Indent + "x = x + ((j-1) * ";
- code += NumToString(InlineSize(vectortype)) + ")\n";
- if (!(vectortype.struct_def->fixed)) {
- code += std::string(Indent) + Indent + "x = " + SelfData + ":Indirect(x)\n";
- }
- code += std::string(Indent) + Indent + "local obj = require('" + TypeNameWithNamespace(field) + "').New()\n";
- code += std::string(Indent) + Indent + "obj:Init(" + SelfDataBytes + ", x)\n";
- code += std::string(Indent) + Indent + "return obj\n";
- code += std::string(Indent) + End;
- code += EndFunc;
- }
-
- // Get the value of a vector's non-struct member. Uses a named return
- // argument to conveniently set the zero value for the result.
- void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- auto vectortype = field.value.type.VectorType();
-
- GenReceiver(struct_def, code_ptr);
- code += MakeCamel(NormalizedName(field));
- code += "(j)\n";
- code += OffsetPrefix(field);
- code += std::string(Indent) + Indent + "local a = " + SelfData + ":Vector(o)\n";
- code += std::string(Indent) + Indent;
- code += "return " + GenGetter(field.value.type);
- code += "a + ((j-1) * ";
- code += NumToString(InlineSize(vectortype)) + "))\n";
- code += std::string(Indent) + End;
- if (vectortype.base_type == BASE_TYPE_STRING) {
- code += std::string(Indent) + "return ''\n";
- }
- else {
- code += std::string(Indent) + "return 0\n";
- }
- code += EndFunc;
- }
-
- // Begin the creator function signature.
- void BeginBuilderArgs(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
-
- code += "function " + NormalizedName(struct_def) + ".Create" + NormalizedName(struct_def);
- code += "(builder";
}
-
- // Recursively generate arguments for a constructor, to deal with nested
- // structs.
- void StructBuilderArgs(const StructDef &struct_def,
- const char *nameprefix, std::string *code_ptr) {
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (IsStruct(field.value.type)) {
- // Generate arguments for a struct inside a struct. To ensure names
- // don't clash, and to make it obvious these arguments are constructing
- // a nested struct, prefix the name with the field name.
- StructBuilderArgs(*field.value.type.struct_def,
- (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
- }
- else {
- std::string &code = *code_ptr;
- code += std::string(", ") + nameprefix;
- code += MakeCamel(NormalizedName(field), false);
- }
+ }
+
+ // End the creator function signature.
+ void EndBuilderArgs(std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += ")\n";
+ }
+
+ // Recursively generate struct construction statements and instert manual
+ // padding.
+ void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += std::string(Indent) + "builder:Prep(" +
+ NumToString(struct_def.minalign) + ", ";
+ code += NumToString(struct_def.bytesize) + ")\n";
+ for (auto it = struct_def.fields.vec.rbegin();
+ it != struct_def.fields.vec.rend(); ++it) {
+ auto &field = **it;
+ if (field.padding)
+ code += std::string(Indent) + "builder:Pad(" +
+ NumToString(field.padding) + ")\n";
+ if (IsStruct(field.value.type)) {
+ StructBuilderBody(*field.value.type.struct_def,
+ (nameprefix + (NormalizedName(field) + "_")).c_str(),
+ code_ptr);
+ } else {
+ code +=
+ std::string(Indent) + "builder:Prepend" + GenMethod(field) + "(";
+ code += nameprefix + MakeCamel(NormalizedName(field), false) + ")\n";
}
}
-
- // End the creator function signature.
- void EndBuilderArgs(std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += ")\n";
- }
-
- // Recursively generate struct construction statements and instert manual
- // padding.
- void StructBuilderBody(const StructDef &struct_def,
- const char *nameprefix, std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += std::string(Indent) + "builder:Prep(" + NumToString(struct_def.minalign) + ", ";
- code += NumToString(struct_def.bytesize) + ")\n";
- for (auto it = struct_def.fields.vec.rbegin();
- it != struct_def.fields.vec.rend(); ++it) {
- auto &field = **it;
- if (field.padding)
- code += std::string(Indent) + "builder:Pad(" + NumToString(field.padding) + ")\n";
- if (IsStruct(field.value.type)) {
- StructBuilderBody(*field.value.type.struct_def,
- (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
- }
- else {
- code += std::string(Indent) + "builder:Prepend" + GenMethod(field) + "(";
- code += nameprefix + MakeCamel(NormalizedName(field), false) + ")\n";
- }
- }
- }
-
- void EndBuilderBody(std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += std::string(Indent) + "return builder:Offset()\n";
- code += EndFunc;
- }
-
- // Get the value of a table's starting offset.
- void GetStartOfTable(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "function " + NormalizedName(struct_def) + ".Start";
- code += "(builder) ";
- code += "builder:StartObject(";
- code += NumToString(struct_def.fields.vec.size());
- code += ") end\n";
- }
-
- // Set the value of a table's field.
- void BuildFieldOfTable(const StructDef &struct_def,
- const FieldDef &field, const size_t offset,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "function " + NormalizedName(struct_def) + ".Add" + MakeCamel(NormalizedName(field));
- code += "(builder, ";
- code += MakeCamel(NormalizedName(field), false);
- code += ") ";
- code += "builder:Prepend";
- code += GenMethod(field) + "Slot(";
- code += NumToString(offset) + ", ";
- // todo: i don't need to cast in Lua, but am I missing something?
+ }
+
+ void EndBuilderBody(std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += std::string(Indent) + "return builder:Offset()\n";
+ code += EndFunc;
+ }
+
+ // Get the value of a table's starting offset.
+ void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "function " + NormalizedName(struct_def) + ".Start";
+ code += "(builder) ";
+ code += "builder:StartObject(";
+ code += NumToString(struct_def.fields.vec.size());
+ code += ") end\n";
+ }
+
+ // Set the value of a table's field.
+ void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
+ const size_t offset, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "function " + NormalizedName(struct_def) + ".Add" +
+ MakeCamel(NormalizedName(field));
+ code += "(builder, ";
+ code += MakeCamel(NormalizedName(field), false);
+ code += ") ";
+ code += "builder:Prepend";
+ code += GenMethod(field) + "Slot(";
+ code += NumToString(offset) + ", ";
+ // todo: i don't need to cast in Lua, but am I missing something?
// if (!IsScalar(field.value.type.base_type) && (!struct_def.fixed)) {
// code += "flatbuffers.N.UOffsetTFlags.py_type";
// code += "(";
// code += MakeCamel(NormalizedName(field), false) + ")";
// } else {
- code += MakeCamel(NormalizedName(field), false);
- // }
- code += ", " + field.value.constant;
- code += ") end\n";
- }
-
- // Set the value of one of the members of a table's vector.
- void BuildVectorOfTable(const StructDef &struct_def,
- const FieldDef &field, std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "function " + NormalizedName(struct_def) + ".Start";
- code += MakeCamel(NormalizedName(field));
- code += "Vector(builder, numElems) return builder:StartVector(";
- auto vector_type = field.value.type.VectorType();
- auto alignment = InlineAlignment(vector_type);
- auto elem_size = InlineSize(vector_type);
- code += NumToString(elem_size);
- code += ", numElems, " + NumToString(alignment);
- code += ") end\n";
- }
-
- // Get the offset of the end of a table.
- void GetEndOffsetOnTable(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "function " + NormalizedName(struct_def) + ".End";
- code += "(builder) ";
- code += "return builder:EndObject() end\n";
- }
-
- // Generate the receiver for function signatures.
- void GenReceiver(const StructDef &struct_def, std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "function " + NormalizedMetaName(struct_def) + ":";
- }
-
- // Generate a struct field, conditioned on its child type(s).
- void GenStructAccessor(const StructDef &struct_def,
- const FieldDef &field, std::string *code_ptr) {
- GenComment(field.doc_comment, code_ptr, nullptr, Comment);
- if (IsScalar(field.value.type.base_type)) {
- if (struct_def.fixed) {
- GetScalarFieldOfStruct(struct_def, field, code_ptr);
- }
- else {
- GetScalarFieldOfTable(struct_def, field, code_ptr);
- }
+ code += MakeCamel(NormalizedName(field), false);
+ // }
+ code += ", " + field.value.constant;
+ code += ") end\n";
+ }
+
+ // Set the value of one of the members of a table's vector.
+ void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "function " + NormalizedName(struct_def) + ".Start";
+ code += MakeCamel(NormalizedName(field));
+ code += "Vector(builder, numElems) return builder:StartVector(";
+ auto vector_type = field.value.type.VectorType();
+ auto alignment = InlineAlignment(vector_type);
+ auto elem_size = InlineSize(vector_type);
+ code += NumToString(elem_size);
+ code += ", numElems, " + NumToString(alignment);
+ code += ") end\n";
+ }
+
+ // Get the offset of the end of a table.
+ void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "function " + NormalizedName(struct_def) + ".End";
+ code += "(builder) ";
+ code += "return builder:EndObject() end\n";
+ }
+
+ // Generate the receiver for function signatures.
+ void GenReceiver(const StructDef &struct_def, std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += "function " + NormalizedMetaName(struct_def) + ":";
+ }
+
+ // Generate a struct field, conditioned on its child type(s).
+ void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ GenComment(field.doc_comment, code_ptr, &def_comment);
+ if (IsScalar(field.value.type.base_type)) {
+ if (struct_def.fixed) {
+ GetScalarFieldOfStruct(struct_def, field, code_ptr);
+ } else {
+ GetScalarFieldOfTable(struct_def, field, code_ptr);
}
- else {
- switch (field.value.type.base_type) {
+ } else {
+ switch (field.value.type.base_type) {
case BASE_TYPE_STRUCT:
if (struct_def.fixed) {
GetStructFieldOfStruct(struct_def, field, code_ptr);
- }
- else {
+ } else {
GetStructFieldOfTable(struct_def, field, code_ptr);
}
break;
- case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break;
+ case BASE_TYPE_STRING:
+ GetStringField(struct_def, field, code_ptr);
+ break;
case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_STRUCT) {
GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
- }
- else {
+ } else {
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
}
break;
}
case BASE_TYPE_UNION: GetUnionField(struct_def, field, code_ptr); break;
default: FLATBUFFERS_ASSERT(0);
- }
- }
- if (field.value.type.base_type == BASE_TYPE_VECTOR) {
- GetVectorLen(struct_def, field, code_ptr);
}
}
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ GetVectorLen(struct_def, field, code_ptr);
+ }
+ }
- // Generate table constructors, conditioned on its members' types.
- void GenTableBuilders(const StructDef &struct_def,
- std::string *code_ptr) {
- GetStartOfTable(struct_def, code_ptr);
+ // Generate table constructors, conditioned on its members' types.
+ void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
+ GetStartOfTable(struct_def, code_ptr);
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
- auto offset = it - struct_def.fields.vec.begin();
- BuildFieldOfTable(struct_def, field, offset, code_ptr);
- if (field.value.type.base_type == BASE_TYPE_VECTOR) {
- BuildVectorOfTable(struct_def, field, code_ptr);
- }
+ auto offset = it - struct_def.fields.vec.begin();
+ BuildFieldOfTable(struct_def, field, offset, code_ptr);
+ if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ BuildVectorOfTable(struct_def, field, code_ptr);
}
-
- GetEndOffsetOnTable(struct_def, code_ptr);
}
- // Generate struct or table methods.
- void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
- if (struct_def.generated) return;
+ GetEndOffsetOnTable(struct_def, code_ptr);
+ }
- GenComment(struct_def.doc_comment, code_ptr, nullptr, Comment);
- BeginClass(struct_def, code_ptr);
+ // Generate struct or table methods.
+ void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
+ if (struct_def.generated) return;
- GenerateNewObjectPrototype(struct_def, code_ptr);
+ GenComment(struct_def.doc_comment, code_ptr, &def_comment);
+ BeginClass(struct_def, code_ptr);
- if (!struct_def.fixed) {
- // Generate a special accessor for the table that has been declared as
- // the root type.
- NewRootTypeFromBuffer(struct_def, code_ptr);
- }
+ GenerateNewObjectPrototype(struct_def, code_ptr);
- // Generate the Init method that sets the field in a pre-existing
- // accessor object. This is to allow object reuse.
- InitializeExisting(struct_def, code_ptr);
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- auto &field = **it;
- if (field.deprecated) continue;
+ if (!struct_def.fixed) {
+ // Generate a special accessor for the table that has been declared as
+ // the root type.
+ NewRootTypeFromBuffer(struct_def, code_ptr);
+ }
- GenStructAccessor(struct_def, field, code_ptr);
- }
+ // Generate the Init method that sets the field in a pre-existing
+ // accessor object. This is to allow object reuse.
+ InitializeExisting(struct_def, code_ptr);
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
- if (struct_def.fixed) {
- // create a struct constructor function
- GenStructBuilder(struct_def, code_ptr);
- }
- else {
- // Create a set of functions that allow table construction.
- GenTableBuilders(struct_def, code_ptr);
- }
+ GenStructAccessor(struct_def, field, code_ptr);
}
- // Generate enum declarations.
- void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
- if (enum_def.generated) return;
-
- GenComment(enum_def.doc_comment, code_ptr, nullptr, Comment);
- BeginEnum(NormalizedName(enum_def), code_ptr);
- for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
- ++it) {
- auto &ev = **it;
- GenComment(ev.doc_comment, code_ptr, nullptr, Comment);
- EnumMember(enum_def, ev, code_ptr);
- }
- EndEnum(code_ptr);
+ if (struct_def.fixed) {
+ // create a struct constructor function
+ GenStructBuilder(struct_def, code_ptr);
+ } else {
+ // Create a set of functions that allow table construction.
+ GenTableBuilders(struct_def, code_ptr);
}
+ }
- // Returns the function name that is able to read a value of the given type.
- std::string GenGetter(const Type &type) {
- switch (type.base_type) {
+ // Generate enum declarations.
+ void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
+ if (enum_def.generated) return;
+
+ GenComment(enum_def.doc_comment, code_ptr, &def_comment);
+ BeginEnum(NormalizedName(enum_def), code_ptr);
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ auto &ev = **it;
+ GenComment(ev.doc_comment, code_ptr, &def_comment, Indent);
+ EnumMember(enum_def, ev, code_ptr);
+ }
+ EndEnum(code_ptr);
+ }
+
+ // Returns the function name that is able to read a value of the given type.
+ std::string GenGetter(const Type &type) {
+ switch (type.base_type) {
case BASE_TYPE_STRING: return std::string(SelfData) + ":String(";
- case BASE_TYPE_UNION: return std::string(SelfData) + ":Union(";
+ case BASE_TYPE_UNION: return std::string(SelfData) + ":Union(";
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
default:
return std::string(SelfData) + ":Get(flatbuffers.N." +
- MakeCamel(GenTypeGet(type)) + ", ";
- }
- }
-
- // Returns the method name for use with add/put calls.
- std::string GenMethod(const FieldDef &field) {
- return IsScalar(field.value.type.base_type)
- ? MakeCamel(GenTypeBasic(field.value.type))
- : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative");
- }
-
- std::string GenTypeBasic(const Type &type) {
- static const char *ctypename[] = {
- // clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
- #PTYPE,
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
- #undef FLATBUFFERS_TD
- // clang-format on
- };
- return ctypename[type.base_type];
- }
-
- std::string GenTypePointer(const Type &type) {
- switch (type.base_type) {
+ MakeCamel(GenTypeGet(type)) + ", ";
+ }
+ }
+
+ // Returns the method name for use with add/put calls.
+ std::string GenMethod(const FieldDef &field) {
+ return IsScalar(field.value.type.base_type)
+ ? MakeCamel(GenTypeBasic(field.value.type))
+ : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative");
+ }
+
+ std::string GenTypeBasic(const Type &type) {
+ // clang-format off
+ static const char *ctypename[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \
+ #PTYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ };
+ // clang-format on
+ return ctypename[type.base_type];
+ }
+
+ std::string GenTypePointer(const Type &type) {
+ switch (type.base_type) {
case BASE_TYPE_STRING: return "string";
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
case BASE_TYPE_STRUCT: return type.struct_def->name;
case BASE_TYPE_UNION:
// fall through
default: return "*flatbuffers.Table";
- }
- }
-
- std::string GenTypeGet(const Type &type) {
- return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
- }
-
- std::string GetNamespace(const Type &type) {
- return type.struct_def->defined_namespace->GetFullyQualifiedName(type.struct_def->name);
- }
-
- std::string TypeName(const FieldDef &field) {
- return GenTypeGet(field.value.type);
- }
-
- std::string TypeNameWithNamespace(const FieldDef &field) {
- return GetNamespace(field.value.type);
- }
-
- // Create a struct with a builder and the struct's arguments.
- void GenStructBuilder(const StructDef &struct_def,
- std::string *code_ptr) {
- BeginBuilderArgs(struct_def, code_ptr);
- StructBuilderArgs(struct_def, "", code_ptr);
- EndBuilderArgs(code_ptr);
-
- StructBuilderBody(struct_def, "", code_ptr);
- EndBuilderBody(code_ptr);
- }
-
- bool generate() {
- if (!generateEnums()) return false;
- if (!generateStructs()) return false;
- return true;
- }
-
- private:
- bool generateEnums() {
- for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
- ++it) {
- auto &enum_def = **it;
- std::string enumcode;
- GenEnum(enum_def, &enumcode);
- if (!SaveType(enum_def, enumcode, false)) return false;
- }
- return true;
- }
-
- bool generateStructs() {
- for (auto it = parser_.structs_.vec.begin();
- it != parser_.structs_.vec.end(); ++it) {
- auto &struct_def = **it;
- std::string declcode;
- GenStruct(struct_def, &declcode);
- if (!SaveType(struct_def, declcode, true)) return false;
- }
- return true;
}
-
- // Begin by declaring namespace and imports.
- void BeginFile(const std::string name_space_name, const bool needs_imports,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += std::string(Comment) + FlatBuffersGeneratedWarning() + "\n\n";
- code += std::string(Comment) + "namespace: " + name_space_name + "\n\n";
- if (needs_imports) {
- code += "local flatbuffers = require('flatbuffers')\n\n";
- }
- }
-
- // Save out the generated code for a Lua Table type.
- bool SaveType(const Definition &def, const std::string &classcode,
- bool needs_imports) {
- if (!classcode.length()) return true;
-
- std::string namespace_dir = path_;
- auto &namespaces = def.defined_namespace->components;
- for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
- if (it != namespaces.begin()) namespace_dir += kPathSeparator;
- namespace_dir += *it;
- //std::string init_py_filename = namespace_dir + "/__init__.py";
- //SaveFile(init_py_filename.c_str(), "", false);
- }
-
- std::string code = "";
- BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
- code += classcode;
- code += "\n";
- code += "return " + NormalizedName(def) + " " + Comment + "return the module";
- std::string filename =
+ }
+
+ std::string GenTypeGet(const Type &type) {
+ return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
+ }
+
+ std::string GetNamespace(const Type &type) {
+ return type.struct_def->defined_namespace->GetFullyQualifiedName(
+ type.struct_def->name);
+ }
+
+ std::string TypeName(const FieldDef &field) {
+ return GenTypeGet(field.value.type);
+ }
+
+ std::string TypeNameWithNamespace(const FieldDef &field) {
+ return GetNamespace(field.value.type);
+ }
+
+ // Create a struct with a builder and the struct's arguments.
+ void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
+ BeginBuilderArgs(struct_def, code_ptr);
+ StructBuilderArgs(struct_def, "", code_ptr);
+ EndBuilderArgs(code_ptr);
+
+ StructBuilderBody(struct_def, "", code_ptr);
+ EndBuilderBody(code_ptr);
+ }
+
+ bool generate() {
+ if (!generateEnums()) return false;
+ if (!generateStructs()) return false;
+ return true;
+ }
+
+ private:
+ bool generateEnums() {
+ for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+ ++it) {
+ auto &enum_def = **it;
+ std::string enumcode;
+ GenEnum(enum_def, &enumcode);
+ if (!SaveType(enum_def, enumcode, false)) return false;
+ }
+ return true;
+ }
+
+ bool generateStructs() {
+ for (auto it = parser_.structs_.vec.begin();
+ it != parser_.structs_.vec.end(); ++it) {
+ auto &struct_def = **it;
+ std::string declcode;
+ GenStruct(struct_def, &declcode);
+ if (!SaveType(struct_def, declcode, true)) return false;
+ }
+ return true;
+ }
+
+ // Begin by declaring namespace and imports.
+ void BeginFile(const std::string &name_space_name, const bool needs_imports,
+ std::string *code_ptr) {
+ std::string &code = *code_ptr;
+ code += std::string(Comment) + FlatBuffersGeneratedWarning() + "\n\n";
+ code += std::string(Comment) + "namespace: " + name_space_name + "\n\n";
+ if (needs_imports) {
+ code += "local flatbuffers = require('flatbuffers')\n\n";
+ }
+ }
+
+ // Save out the generated code for a Lua Table type.
+ bool SaveType(const Definition &def, const std::string &classcode,
+ bool needs_imports) {
+ if (!classcode.length()) return true;
+
+ std::string namespace_dir = path_;
+ auto &namespaces = def.defined_namespace->components;
+ for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
+ if (it != namespaces.begin()) namespace_dir += kPathSeparator;
+ namespace_dir += *it;
+ // std::string init_py_filename = namespace_dir + "/__init__.py";
+ // SaveFile(init_py_filename.c_str(), "", false);
+ }
+
+ std::string code = "";
+ BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
+ code += classcode;
+ code += "\n";
+ code +=
+ "return " + NormalizedName(def) + " " + Comment + "return the module";
+ std::string filename =
NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".lua";
- return SaveFile(filename.c_str(), code, false);
- }
- private:
- std::unordered_set<std::string> keywords_;
- };
+ return SaveFile(filename.c_str(), code, false);
+ }
+
+ private:
+ std::unordered_set<std::string> keywords_;
+};
} // namespace lua
bool GenerateLua(const Parser &parser, const std::string &path,
- const std::string &file_name) {
+ const std::string &file_name) {
lua::LuaGenerator generator(parser, path, file_name);
return generator.generate();
}
diff --git a/src/idl_gen_php.cpp b/src/idl_gen_php.cpp
index a4b9a469..f346c7ce 100644
--- a/src/idl_gen_php.cpp
+++ b/src/idl_gen_php.cpp
@@ -31,7 +31,7 @@ class PhpGenerator : public BaseGenerator {
public:
PhpGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "\\", "\\") {}
+ : BaseGenerator(parser, path, file_name, "\\", "\\", "php") {}
bool generate() {
if (!GenerateEnums()) return false;
if (!GenerateStructs()) return false;
@@ -125,8 +125,7 @@ class PhpGenerator : public BaseGenerator {
code += Indent + "const ";
code += ev.name;
code += " = ";
- code += NumToString(ev.value) + ";\n";
- (void)enum_def;
+ code += enum_def.ToString(ev) + ";\n";
}
// End enum code.
@@ -233,7 +232,6 @@ class PhpGenerator : public BaseGenerator {
// Get the value of a table's scalar.
void GetScalarFieldOfTable(const FieldDef &field, std::string *code_ptr) {
std::string &code = *code_ptr;
- std::string getter = GenGetter(field.value.type);
code += Indent + "/**\n";
code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
@@ -674,7 +672,7 @@ class PhpGenerator : public BaseGenerator {
// Generate a struct field, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
- GenComment(field.doc_comment, code_ptr, nullptr);
+ GenComment(field.doc_comment, code_ptr, nullptr, Indent.c_str());
if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) {
@@ -819,7 +817,7 @@ class PhpGenerator : public BaseGenerator {
BeginEnum(enum_def.name, code_ptr);
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
auto &ev = **it;
- GenComment(ev.doc_comment, code_ptr, nullptr);
+ GenComment(ev.doc_comment, code_ptr, nullptr, Indent.c_str());
EnumMember(enum_def, ev, code_ptr);
}
@@ -828,7 +826,8 @@ class PhpGenerator : public BaseGenerator {
code += Indent + "private static $names = array(\n";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
auto &ev = **it;
- code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" + ev.name + "\",\n";
+ code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" +
+ ev.name + "\",\n";
}
code += Indent + ");\n\n";
@@ -861,22 +860,21 @@ class PhpGenerator : public BaseGenerator {
}
static std::string GenTypeBasic(const Type &type) {
- static const char *ctypename[] = {
// clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
- #NTYPE,
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
- #undef FLATBUFFERS_TD
- // clang-format on
+ static const char *ctypename[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+ CTYPE, JTYPE, GTYPE, NTYPE, ...) \
+ #NTYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
};
+ // clang-format on
return ctypename[type.base_type];
}
std::string GenDefaultValue(const Value &value) {
if (value.type.enum_def) {
- if (auto val = value.type.enum_def->ReverseLookup(
- StringToInt(value.constant.c_str()), false)) {
+ if (auto val = value.type.enum_def->FindByValue(value.constant)) {
return WrapInNameSpace(*value.type.enum_def) + "::" + val->name;
}
}
diff --git a/src/idl_gen_python.cpp b/src/idl_gen_python.cpp
index f2688e4e..dfa8a6b0 100644
--- a/src/idl_gen_python.cpp
+++ b/src/idl_gen_python.cpp
@@ -16,19 +16,22 @@
// independent from idl_parser, since this code is not needed for most clients
+#include <cctype>
+#include <set>
#include <string>
+#include <unordered_set>
+#include <vector>
#include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
-#include <unordered_set>
-
namespace flatbuffers {
namespace python {
// Hardcode spaces per indentation.
+const CommentConfig def_comment = { nullptr, "#", nullptr };
const std::string Indent = " ";
class PythonGenerator : public BaseGenerator {
@@ -36,42 +39,14 @@ class PythonGenerator : public BaseGenerator {
PythonGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */,
- "" /* not used */),
+ "" /* not used */, "py"),
float_const_gen_("float('nan')", "float('inf')", "float('-inf')") {
- static const char * const keywords[] = {
- "False",
- "None",
- "True",
- "and",
- "as",
- "assert",
- "break",
- "class",
- "continue",
- "def",
- "del",
- "elif",
- "else",
- "except",
- "finally",
- "for",
- "from",
- "global",
- "if",
- "import",
- "in",
- "is",
- "lambda",
- "nonlocal",
- "not",
- "or",
- "pass",
- "raise",
- "return",
- "try",
- "while",
- "with",
- "yield"
+ static const char *const keywords[] = {
+ "False", "None", "True", "and", "as", "assert", "break",
+ "class", "continue", "def", "del", "elif", "else", "except",
+ "finally", "for", "from", "global", "if", "import", "in",
+ "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
+ "return", "try", "while", "with", "yield"
};
keywords_.insert(std::begin(keywords), std::end(keywords));
}
@@ -80,22 +55,22 @@ class PythonGenerator : public BaseGenerator {
// this is the prefix code for that.
std::string OffsetPrefix(const FieldDef &field) {
return "\n" + Indent + Indent +
- "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
- "(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" +
- Indent + Indent + "if o != 0:\n";
+ "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
+ "(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" +
+ Indent + Indent + "if o != 0:\n";
}
// Begin a class declaration.
void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code += "class " + NormalizedName(struct_def) + "(object):\n";
code += Indent + "__slots__ = ['_tab']";
code += "\n\n";
}
// Begin enum code with a class declaration.
- void BeginEnum(const std::string class_name, std::string *code_ptr) {
- std::string &code = *code_ptr;
+ void BeginEnum(const std::string &class_name, std::string *code_ptr) {
+ auto &code = *code_ptr;
code += "class " + class_name + "(object):\n";
}
@@ -111,27 +86,43 @@ class PythonGenerator : public BaseGenerator {
return EscapeKeyword(ev.name);
}
+ // Converts the name of a definition into upper Camel format.
+ std::string MakeUpperCamel(const Definition &definition) const {
+ return MakeCamel(NormalizedName(definition), true);
+ }
+
+ // Converts the name of a definition into lower Camel format.
+ std::string MakeLowerCamel(const Definition &definition) const {
+ auto name = MakeCamel(NormalizedName(definition), false);
+ name[0] = char(tolower(name[0]));
+ return name;
+ }
+
+ // Starts a new line and then indents.
+ std::string GenIndents(int num) {
+ return "\n" + std::string(num * Indent.length(), ' ');
+ }
+
// A single enum member.
void EnumMember(const EnumDef &enum_def, const EnumVal &ev,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code += Indent;
code += NormalizedName(ev);
code += " = ";
- code += NumToString(ev.value) + "\n";
- (void)enum_def;
+ code += enum_def.ToString(ev) + "\n";
}
// End enum code.
void EndEnum(std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code += "\n";
}
// Initialize a new struct or table from existing data.
void NewRootTypeFromBuffer(const StructDef &struct_def,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code += Indent + "@classmethod\n";
code += Indent + "def GetRootAs";
@@ -148,9 +139,8 @@ class PythonGenerator : public BaseGenerator {
}
// Initialize an existing object with other data, to avoid an allocation.
- void InitializeExisting(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
+ void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
+ auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += "Init(self, buf, pos):\n";
@@ -161,7 +151,7 @@ class PythonGenerator : public BaseGenerator {
// Get the length of a vector.
void GetVectorLen(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)) + "Length(self";
@@ -170,11 +160,25 @@ class PythonGenerator : public BaseGenerator {
code += Indent + Indent + "return 0\n\n";
}
+ // Determines whether a vector is none or not.
+ void GetVectorIsNone(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field)) + "IsNone(self";
+ code += "):";
+ code += GenIndents(2) +
+ "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
+ "(self._tab.Offset(" + NumToString(field.value.offset) + "))";
+ code += GenIndents(2) + "return o == 0";
+ code += "\n\n";
+ }
+
// Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
+ const FieldDef &field, std::string *code_ptr) {
+ auto &code = *code_ptr;
std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field));
@@ -184,10 +188,9 @@ class PythonGenerator : public BaseGenerator {
}
// Get the value of a table's scalar.
- void GetScalarFieldOfTable(const StructDef &struct_def,
- const FieldDef &field,
+ void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field));
@@ -195,9 +198,7 @@ class PythonGenerator : public BaseGenerator {
code += OffsetPrefix(field);
getter += "o + self._tab.Pos)";
auto is_bool = IsBool(field.value.type.base_type);
- if (is_bool) {
- getter = "bool(" + getter + ")";
- }
+ if (is_bool) { getter = "bool(" + getter + ")"; }
code += Indent + Indent + Indent + "return " + getter + "\n";
std::string default_value;
if (is_bool) {
@@ -213,9 +214,8 @@ class PythonGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct.
// Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
+ const FieldDef &field, std::string *code_ptr) {
+ auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field));
code += "(self, obj):\n";
@@ -224,12 +224,35 @@ class PythonGenerator : public BaseGenerator {
code += "\n" + Indent + Indent + "return obj\n\n";
}
+ // Get the value of a fixed size array.
+ void GetArrayOfStruct(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ const auto vec_type = field.value.type.VectorType();
+ GenReceiver(struct_def, code_ptr);
+ code += MakeCamel(NormalizedName(field));
+ if (IsStruct(vec_type)) {
+ code += "(self, obj, i):\n";
+ code += Indent + Indent + "obj.Init(self._tab.Bytes, self._tab.Pos + ";
+ code += NumToString(field.value.offset) + " + i * ";
+ code += NumToString(InlineSize(vec_type));
+ code += ")\n" + Indent + Indent + "return obj\n\n";
+ } else {
+ auto getter = GenGetter(vec_type);
+ code += "(self): return [" + getter;
+ code += "self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(";
+ code += NumToString(field.value.offset) + " + i * ";
+ code += NumToString(InlineSize(vec_type));
+ code += ")) for i in range(";
+ code += NumToString(field.value.type.fixed_length) + ")]\n";
+ }
+ }
+
// Get a struct by initializing an existing struct.
// Specific to Table.
- void GetStructFieldOfTable(const StructDef &struct_def,
- const FieldDef &field,
+ void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field));
code += "(self):";
@@ -240,8 +263,11 @@ class PythonGenerator : public BaseGenerator {
code += Indent + Indent + Indent;
code += "x = self._tab.Indirect(o + self._tab.Pos)\n";
}
- code += Indent + Indent + Indent;
- code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+ if (parser_.opts.include_dependence_headers) {
+ code += Indent + Indent + Indent;
+ code += "from " + GenPackageReference(field.value.type) + " import " +
+ TypeName(field) + "\n";
+ }
code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n";
code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n";
code += Indent + Indent + Indent + "return obj\n";
@@ -251,7 +277,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a string.
void GetStringField(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field));
code += "(self):";
@@ -264,7 +290,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a union from an object.
void GetUnionField(const StructDef &struct_def, const FieldDef &field,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)) + "(self):";
code += OffsetPrefix(field);
@@ -272,10 +298,12 @@ class PythonGenerator : public BaseGenerator {
// TODO(rw): this works and is not the good way to it:
bool is_native_table = TypeName(field) == "*flatbuffers.Table";
if (is_native_table) {
- code += Indent + Indent + Indent + "from flatbuffers.table import Table\n";
- } else {
+ code +=
+ Indent + Indent + Indent + "from flatbuffers.table import Table\n";
+ } else if (parser_.opts.include_dependence_headers) {
code += Indent + Indent + Indent;
- code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+ code += "from " + GenPackageReference(field.value.type) + " import " +
+ TypeName(field) + "\n";
}
code += Indent + Indent + Indent + "obj = Table(bytearray(), 0)\n";
code += Indent + Indent + Indent + GenGetter(field.value.type);
@@ -283,11 +311,25 @@ class PythonGenerator : public BaseGenerator {
code += Indent + Indent + "return None\n\n";
}
+ // Generate the package reference when importing a struct or enum from its
+ // module.
+ std::string GenPackageReference(const Type &type) {
+ Namespace *namespaces;
+ if (type.struct_def) {
+ namespaces = type.struct_def->defined_namespace;
+ } else if (type.enum_def) {
+ namespaces = type.enum_def->defined_namespace;
+ } else {
+ return "." + GenTypeGet(type);
+ }
+
+ return namespaces->GetFullyQualifiedName(GenTypeGet(type));
+ }
+
// Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def,
- const FieldDef &field,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
+ const FieldDef &field, std::string *code_ptr) {
+ auto &code = *code_ptr;
auto vectortype = field.value.type.VectorType();
GenReceiver(struct_def, code_ptr);
@@ -300,8 +342,11 @@ class PythonGenerator : public BaseGenerator {
if (!(vectortype.struct_def->fixed)) {
code += Indent + Indent + Indent + "x = self._tab.Indirect(x)\n";
}
- code += Indent + Indent + Indent;
- code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
+ if (parser_.opts.include_dependence_headers) {
+ code += Indent + Indent + Indent;
+ code += "from " + GenPackageReference(field.value.type) + " import " +
+ TypeName(field) + "\n";
+ }
code += Indent + Indent + Indent + "obj = " + TypeName(field) + "()\n";
code += Indent + Indent + Indent + "obj.Init(self._tab.Bytes, x)\n";
code += Indent + Indent + Indent + "return obj\n";
@@ -313,7 +358,7 @@ class PythonGenerator : public BaseGenerator {
void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
const FieldDef &field,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
auto vectortype = field.value.type.VectorType();
GenReceiver(struct_def, code_ptr);
@@ -338,7 +383,7 @@ class PythonGenerator : public BaseGenerator {
void GetVectorOfNonStructAsNumpy(const StructDef &struct_def,
const FieldDef &field,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
auto vectortype = field.value.type.VectorType();
// Currently, we only support accessing as numpy array if
@@ -364,9 +409,8 @@ class PythonGenerator : public BaseGenerator {
}
// Begin the creator function signature.
- void BeginBuilderArgs(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
+ void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
+ auto &code = *code_ptr;
code += "\n";
code += "def Create" + NormalizedName(struct_def);
@@ -376,61 +420,99 @@ class PythonGenerator : public BaseGenerator {
// Recursively generate arguments for a constructor, to deal with nested
// structs.
void StructBuilderArgs(const StructDef &struct_def,
- const char *nameprefix, std::string *code_ptr) {
+ const std::string nameprefix,
+ const std::string namesuffix, bool has_field_name,
+ const std::string fieldname_suffix,
+ std::string *code_ptr) {
for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
+ it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
- if (IsStruct(field.value.type)) {
+ const auto &field_type = field.value.type;
+ const auto &type =
+ IsArray(field_type) ? field_type.VectorType() : field_type;
+ if (IsStruct(type)) {
// Generate arguments for a struct inside a struct. To ensure names
// don't clash, and to make it obvious these arguments are constructing
// a nested struct, prefix the name with the field name.
- StructBuilderArgs(*field.value.type.struct_def,
- (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
+ auto subprefix = nameprefix;
+ if (has_field_name) {
+ subprefix += NormalizedName(field) + fieldname_suffix;
+ }
+ StructBuilderArgs(*field.value.type.struct_def, subprefix, namesuffix,
+ has_field_name, fieldname_suffix, code_ptr);
} else {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code += std::string(", ") + nameprefix;
- code += MakeCamel(NormalizedName(field), false);
+ if (has_field_name) { code += MakeCamel(NormalizedName(field), false); }
+ code += namesuffix;
}
}
}
// End the creator function signature.
void EndBuilderArgs(std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code += "):\n";
}
// Recursively generate struct construction statements and instert manual
// padding.
- void StructBuilderBody(const StructDef &struct_def,
- const char *nameprefix, std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += " builder.Prep(" + NumToString(struct_def.minalign) + ", ";
+ void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
+ std::string *code_ptr, size_t index = 0,
+ bool in_array = false) {
+ auto &code = *code_ptr;
+ std::string indent(index * 4, ' ');
+ code +=
+ indent + " builder.Prep(" + NumToString(struct_def.minalign) + ", ";
code += NumToString(struct_def.bytesize) + ")\n";
for (auto it = struct_def.fields.vec.rbegin();
- it != struct_def.fields.vec.rend(); ++it) {
+ it != struct_def.fields.vec.rend(); ++it) {
auto &field = **it;
+ const auto &field_type = field.value.type;
+ const auto &type =
+ IsArray(field_type) ? field_type.VectorType() : field_type;
if (field.padding)
- code += " builder.Pad(" + NumToString(field.padding) + ")\n";
- if (IsStruct(field.value.type)) {
- StructBuilderBody(*field.value.type.struct_def,
- (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr);
+ code +=
+ indent + " builder.Pad(" + NumToString(field.padding) + ")\n";
+ if (IsStruct(field_type)) {
+ StructBuilderBody(*field_type.struct_def,
+ (nameprefix + (NormalizedName(field) + "_")).c_str(),
+ code_ptr, index, in_array);
} else {
- code += " builder.Prepend" + GenMethod(field) + "(";
- code += nameprefix + MakeCamel(NormalizedName(field), false) + ")\n";
+ const auto index_var = "_idx" + NumToString(index);
+ if (IsArray(field_type)) {
+ code += indent + " for " + index_var + " in range(";
+ code += NumToString(field_type.fixed_length);
+ code += " , 0, -1):\n";
+ in_array = true;
+ }
+ if (IsStruct(type)) {
+ StructBuilderBody(
+ *field_type.struct_def,
+ (nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr,
+ index + 1, in_array);
+ } else {
+ code += IsArray(field_type) ? " " : "";
+ code += indent + " builder.Prepend" + GenMethod(field) + "(";
+ code += nameprefix + MakeCamel(NormalizedName(field), false);
+ size_t array_cnt = index + (IsArray(field_type) ? 1 : 0);
+ for (size_t i = 0; in_array && i < array_cnt; i++) {
+ code += "[_idx" + NumToString(i) + "-1]";
+ }
+ code += ")\n";
+ }
}
}
}
void EndBuilderBody(std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code += " return builder.Offset()\n";
}
// Get the value of a table's starting offset.
- void GetStartOfTable(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
+ void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
+ auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start";
code += "(builder): ";
code += "builder.StartObject(";
@@ -439,11 +521,11 @@ class PythonGenerator : public BaseGenerator {
}
// Set the value of a table's field.
- void BuildFieldOfTable(const StructDef &struct_def,
- const FieldDef &field, const size_t offset,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
- code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field));
+ void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
+ const size_t offset, std::string *code_ptr) {
+ auto &code = *code_ptr;
+ code += "def " + NormalizedName(struct_def) + "Add" +
+ MakeCamel(NormalizedName(field));
code += "(builder, ";
code += MakeCamel(NormalizedName(field), false);
code += "): ";
@@ -465,9 +547,9 @@ class PythonGenerator : public BaseGenerator {
}
// Set the value of one of the members of a table's vector.
- void BuildVectorOfTable(const StructDef &struct_def,
- const FieldDef &field, std::string *code_ptr) {
- std::string &code = *code_ptr;
+ void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start";
code += MakeCamel(NormalizedName(field));
code += "Vector(builder, numElems): return builder.StartVector(";
@@ -480,9 +562,8 @@ class PythonGenerator : public BaseGenerator {
}
// Get the offset of the end of a table.
- void GetEndOffsetOnTable(const StructDef &struct_def,
- std::string *code_ptr) {
- std::string &code = *code_ptr;
+ void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
+ auto &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "End";
code += "(builder): ";
code += "return builder.EndObject()\n";
@@ -490,21 +571,23 @@ class PythonGenerator : public BaseGenerator {
// Generate the receiver for function signatures.
void GenReceiver(const StructDef &struct_def, std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code += Indent + "# " + NormalizedName(struct_def) + "\n";
code += Indent + "def ";
}
// Generate a struct field, conditioned on its child type(s).
- void GenStructAccessor(const StructDef &struct_def,
- const FieldDef &field, std::string *code_ptr) {
- GenComment(field.doc_comment, code_ptr, nullptr, "# ");
+ void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str());
if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) {
GetScalarFieldOfStruct(struct_def, field, code_ptr);
} else {
GetScalarFieldOfTable(struct_def, field, code_ptr);
}
+ } else if (IsArray(field.value.type)) {
+ GetArrayOfStruct(struct_def, field, code_ptr);
} else {
switch (field.value.type.base_type) {
case BASE_TYPE_STRUCT:
@@ -514,7 +597,9 @@ class PythonGenerator : public BaseGenerator {
GetStructFieldOfTable(struct_def, field, code_ptr);
}
break;
- case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break;
+ case BASE_TYPE_STRING:
+ GetStringField(struct_def, field, code_ptr);
+ break;
case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -529,18 +614,19 @@ class PythonGenerator : public BaseGenerator {
default: FLATBUFFERS_ASSERT(0);
}
}
- if (field.value.type.base_type == BASE_TYPE_VECTOR) {
+ if (field.value.type.base_type == BASE_TYPE_VECTOR ||
+ field.value.type.base_type == BASE_TYPE_ARRAY) {
GetVectorLen(struct_def, field, code_ptr);
+ GetVectorIsNone(struct_def, field, code_ptr);
}
}
// Generate table constructors, conditioned on its members' types.
- void GenTableBuilders(const StructDef &struct_def,
- std::string *code_ptr) {
+ void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
GetStartOfTable(struct_def, code_ptr);
for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
+ it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) continue;
@@ -554,22 +640,50 @@ class PythonGenerator : public BaseGenerator {
GetEndOffsetOnTable(struct_def, code_ptr);
}
- // Generate struct or table methods.
+ // Generate function to check for proper file identifier
+ void GenHasFileIdentifier(const StructDef &struct_def,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ std::string escapedID;
+ // In the event any of file_identifier characters are special(NULL, \, etc),
+ // problems occur. To prevent this, convert all chars to their hex-escaped
+ // equivalent.
+ for (auto it = parser_.file_identifier_.begin();
+ it != parser_.file_identifier_.end(); ++it) {
+ escapedID += "\\x" + IntToStringHex(*it, 2);
+ }
+
+ code += Indent + "@classmethod\n";
+ code += Indent + "def " + NormalizedName(struct_def);
+ code += "BufferHasIdentifier(cls, buf, offset, size_prefixed=False):";
+ code += "\n";
+ code += Indent + Indent;
+ code += "return flatbuffers.util.BufferHasIdentifier(buf, offset, b\"";
+ code += escapedID;
+ code += "\", size_prefixed=size_prefixed)\n";
+ code += "\n";
+ }
+
+ // Generates struct or table methods.
void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
if (struct_def.generated) return;
- GenComment(struct_def.doc_comment, code_ptr, nullptr, "# ");
+ GenComment(struct_def.doc_comment, code_ptr, &def_comment);
BeginClass(struct_def, code_ptr);
if (!struct_def.fixed) {
// Generate a special accessor for the table that has been declared as
// the root type.
NewRootTypeFromBuffer(struct_def, code_ptr);
+ if (parser_.file_identifier_.length()) {
+ // Generate a special function to test file_identifier
+ GenHasFileIdentifier(struct_def, code_ptr);
+ }
}
- // Generate the Init method that sets the field in a pre-existing
+ // Generates the Init method that sets the field in a pre-existing
// accessor object. This is to allow object reuse.
InitializeExisting(struct_def, code_ptr);
for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
+ it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
if (field.deprecated) continue;
@@ -577,23 +691,817 @@ class PythonGenerator : public BaseGenerator {
}
if (struct_def.fixed) {
- // create a struct constructor function
+ // creates a struct constructor function
GenStructBuilder(struct_def, code_ptr);
} else {
- // Create a set of functions that allow table construction.
+ // Creates a set of functions that allow table construction.
GenTableBuilders(struct_def, code_ptr);
}
}
+ void GenReceiverForObjectAPI(const StructDef &struct_def,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ code += GenIndents(1) + "# " + NormalizedName(struct_def) + "T";
+ code += GenIndents(1) + "def ";
+ }
+
+ void BeginClassForObjectAPI(const StructDef &struct_def,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ code += "\n";
+ code += "class " + NormalizedName(struct_def) + "T(object):";
+ code += "\n";
+ }
+
+ // Gets the accoresponding python builtin type of a BaseType for scalars and
+ // string.
+ std::string GetBasePythonTypeForScalarAndString(const BaseType &base_type) {
+ if (IsBool(base_type)) {
+ return "bool";
+ } else if (IsFloat(base_type)) {
+ return "float";
+ } else if (IsInteger(base_type)) {
+ return "int";
+ } else if (base_type == BASE_TYPE_STRING) {
+ return "str";
+ } else {
+ FLATBUFFERS_ASSERT(false && "base_type is not a scalar or string type.");
+ return "";
+ }
+ }
+
+ std::string GetDefaultValue(const FieldDef &field) {
+ BaseType base_type = field.value.type.base_type;
+ if (IsBool(base_type)) {
+ return field.value.constant == "0" ? "False" : "True";
+ } else if (IsFloat(base_type)) {
+ return float_const_gen_.GenFloatConstant(field);
+ } else if (IsInteger(base_type)) {
+ return field.value.constant;
+ } else {
+ // For string, struct, and table.
+ return "None";
+ }
+ }
+
+ void GenUnionInit(const FieldDef &field, std::string *field_types_ptr,
+ std::set<std::string> *import_list,
+ std::set<std::string> *import_typing_list) {
+ // Gets all possible types in the union.
+ import_typing_list->insert("Union");
+ auto &field_types = *field_types_ptr;
+ field_types = "Union[";
+
+ std::string separator_string = ", ";
+ auto enum_def = field.value.type.enum_def;
+ for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end();
+ ++it) {
+ auto &ev = **it;
+ // Union only supports string and table.
+ std::string field_type;
+ switch (ev.union_type.base_type) {
+ case BASE_TYPE_STRUCT:
+ field_type = GenTypeGet(ev.union_type) + "T";
+ if (parser_.opts.include_dependence_headers) {
+ auto package_reference = GenPackageReference(ev.union_type);
+ field_type = package_reference + "." + field_type;
+ import_list->insert("import " + package_reference);
+ }
+ break;
+ case BASE_TYPE_STRING: field_type += "str"; break;
+ case BASE_TYPE_NONE: field_type += "None"; break;
+ default: break;
+ }
+ field_types += field_type + separator_string;
+ }
+
+ // Removes the last separator_string.
+ field_types.erase(field_types.length() - separator_string.size());
+ field_types += "]";
+
+ // Gets the import lists for the union.
+ if (parser_.opts.include_dependence_headers) {
+ // The package reference is generated based on enum_def, instead
+ // of struct_def in field.type. That's why GenPackageReference() is
+ // not used.
+ Namespace *namespaces = field.value.type.enum_def->defined_namespace;
+ auto package_reference = namespaces->GetFullyQualifiedName(
+ MakeUpperCamel(*(field.value.type.enum_def)));
+ auto union_name = MakeUpperCamel(*(field.value.type.enum_def));
+ import_list->insert("import " + package_reference);
+ }
+ }
+
+ void GenStructInit(const FieldDef &field, std::string *field_type_ptr,
+ std::set<std::string> *import_list,
+ std::set<std::string> *import_typing_list) {
+ import_typing_list->insert("Optional");
+ auto &field_type = *field_type_ptr;
+ if (parser_.opts.include_dependence_headers) {
+ auto package_reference = GenPackageReference(field.value.type);
+ field_type = package_reference + "." + TypeName(field) + "T]";
+ import_list->insert("import " + package_reference);
+ } else {
+ field_type = TypeName(field) + "T]";
+ }
+ field_type = "Optional[" + field_type;
+ }
+
+ void GenVectorInit(const FieldDef &field, std::string *field_type_ptr,
+ std::set<std::string> *import_list,
+ std::set<std::string> *import_typing_list) {
+ import_typing_list->insert("List");
+ auto &field_type = *field_type_ptr;
+ auto base_type = field.value.type.VectorType().base_type;
+ if (base_type == BASE_TYPE_STRUCT) {
+ field_type = GenTypeGet(field.value.type.VectorType()) + "T]";
+ if (parser_.opts.include_dependence_headers) {
+ auto package_reference =
+ GenPackageReference(field.value.type.VectorType());
+ field_type = package_reference + "." +
+ GenTypeGet(field.value.type.VectorType()) + "T]";
+ import_list->insert("import " + package_reference);
+ }
+ field_type = "List[" + field_type;
+ } else {
+ field_type =
+ "List[" + GetBasePythonTypeForScalarAndString(base_type) + "]";
+ }
+ }
+
+ void GenInitialize(const StructDef &struct_def, std::string *code_ptr,
+ std::set<std::string> *import_list) {
+ std::string code;
+ std::set<std::string> import_typing_list;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+
+ // Determines field type, default value, and typing imports.
+ auto base_type = field.value.type.base_type;
+ std::string field_type;
+ switch (base_type) {
+ case BASE_TYPE_UNION: {
+ GenUnionInit(field, &field_type, import_list, &import_typing_list);
+ break;
+ }
+ case BASE_TYPE_STRUCT: {
+ GenStructInit(field, &field_type, import_list, &import_typing_list);
+ break;
+ }
+ case BASE_TYPE_VECTOR:
+ case BASE_TYPE_ARRAY: {
+ GenVectorInit(field, &field_type, import_list, &import_typing_list);
+ break;
+ }
+ default:
+ // Scalar or sting fields.
+ field_type = GetBasePythonTypeForScalarAndString(base_type);
+ break;
+ }
+
+ auto default_value = GetDefaultValue(field);
+ // Wrties the init statement.
+ auto field_instance_name = MakeLowerCamel(field);
+ code += GenIndents(2) + "self." + field_instance_name + " = " +
+ default_value + " # type: " + field_type;
+ }
+
+ // Writes __init__ method.
+ auto &code_base = *code_ptr;
+ GenReceiverForObjectAPI(struct_def, code_ptr);
+ code_base += "__init__(self):";
+ if (code.empty()) {
+ code_base += GenIndents(2) + "pass";
+ } else {
+ code_base += code;
+ }
+ code_base += "\n";
+
+ // Merges the typing imports into import_list.
+ if (!import_typing_list.empty()) {
+ // Adds the try statement.
+ std::string typing_imports = "try:";
+ typing_imports += GenIndents(1) + "from typing import ";
+ std::string separator_string = ", ";
+ for (auto it = import_typing_list.begin(); it != import_typing_list.end();
+ ++it) {
+ const std::string &im = *it;
+ typing_imports += im + separator_string;
+ }
+ // Removes the last separator_string.
+ typing_imports.erase(typing_imports.length() - separator_string.size());
+
+ // Adds the except statement.
+ typing_imports += "\n";
+ typing_imports += "except:";
+ typing_imports += GenIndents(1) + "pass";
+ import_list->insert(typing_imports);
+ }
+
+ // Removes the import of the struct itself, if applied.
+ auto package_reference =
+ struct_def.defined_namespace->GetFullyQualifiedName(
+ MakeUpperCamel(struct_def));
+ auto struct_import = "import " + package_reference;
+ import_list->erase(struct_import);
+ }
+
+ void InitializeFromBuf(const StructDef &struct_def, std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto instance_name = MakeLowerCamel(struct_def);
+ auto struct_name = NormalizedName(struct_def);
+
+ code += GenIndents(1) + "@classmethod";
+ code += GenIndents(1) + "def InitFromBuf(cls, buf, pos):";
+ code += GenIndents(2) + instance_name + " = " + struct_name + "()";
+ code += GenIndents(2) + instance_name + ".Init(buf, pos)";
+ code += GenIndents(2) + "return cls.InitFromObj(" + instance_name + ")";
+ code += "\n";
+ }
+
+ void InitializeFromObjForObject(const StructDef &struct_def,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto instance_name = MakeLowerCamel(struct_def);
+ auto struct_name = NormalizedName(struct_def);
+
+ code += GenIndents(1) + "@classmethod";
+ code += GenIndents(1) + "def InitFromObj(cls, " + instance_name + "):";
+ code += GenIndents(2) + "x = " + struct_name + "T()";
+ code += GenIndents(2) + "x._UnPack(" + instance_name + ")";
+ code += GenIndents(2) + "return x";
+ code += "\n";
+ }
+
+ void GenUnPackForStruct(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto struct_instance_name = MakeLowerCamel(struct_def);
+ auto field_instance_name = MakeLowerCamel(field);
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto field_type = TypeName(field);
+
+ if (parser_.opts.include_dependence_headers) {
+ auto package_reference = GenPackageReference(field.value.type);
+ field_type = package_reference + "." + TypeName(field);
+ }
+
+ code += GenIndents(2) + "if " + struct_instance_name + "." +
+ field_accessor_name + "(";
+ // if field is a struct, we need to create an instance for it first.
+ if (struct_def.fixed && field.value.type.base_type == BASE_TYPE_STRUCT) {
+ code += field_type + "()";
+ }
+ code += ") is not None:";
+ code += GenIndents(3) + "self." + field_instance_name + " = " + field_type +
+ "T.InitFromObj(" + struct_instance_name + "." +
+ field_accessor_name + "(";
+ // A struct's accessor requires a struct buf instance.
+ if (struct_def.fixed && field.value.type.base_type == BASE_TYPE_STRUCT) {
+ code += field_type + "()";
+ }
+ code += "))";
+ }
+
+ void GenUnPackForUnion(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_instance_name = MakeLowerCamel(struct_def);
+ auto union_name = MakeUpperCamel(*(field.value.type.enum_def));
+
+ if (parser_.opts.include_dependence_headers) {
+ Namespace *namespaces = field.value.type.enum_def->defined_namespace;
+ auto package_reference = namespaces->GetFullyQualifiedName(
+ MakeUpperCamel(*(field.value.type.enum_def)));
+ union_name = package_reference + "." + union_name;
+ }
+ code += GenIndents(2) + "self." + field_instance_name + " = " + union_name +
+ "Creator(" + "self." + field_instance_name + "Type, " +
+ struct_instance_name + "." + field_accessor_name + "())";
+ }
+
+ void GenUnPackForStructVector(const StructDef &struct_def,
+ const FieldDef &field, std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_instance_name = MakeLowerCamel(struct_def);
+
+ code += GenIndents(2) + "if not " + struct_instance_name + "." +
+ field_accessor_name + "IsNone():";
+ code += GenIndents(3) + "self." + field_instance_name + " = []";
+ code += GenIndents(3) + "for i in range(" + struct_instance_name + "." +
+ field_accessor_name + "Length()):";
+
+ auto field_type_name = TypeName(field);
+ auto one_instance = field_type_name + "_";
+ one_instance[0] = char(tolower(one_instance[0]));
+
+ if (parser_.opts.include_dependence_headers) {
+ auto package_reference = GenPackageReference(field.value.type);
+ field_type_name = package_reference + "." + TypeName(field);
+ }
+
+ code += GenIndents(4) + "if " + struct_instance_name + "." +
+ field_accessor_name + "(i) is None:";
+ code += GenIndents(5) + "self." + field_instance_name + ".append(None)";
+ code += GenIndents(4) + "else:";
+ code += GenIndents(5) + one_instance + " = " + field_type_name +
+ "T.InitFromObj(" + struct_instance_name + "." +
+ field_accessor_name + "(i))";
+ code += GenIndents(5) + "self." + field_instance_name + ".append(" +
+ one_instance + ")";
+ }
+
+ void GenUnpackforScalarVectorHelper(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_ptr, int indents) {
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_instance_name = MakeLowerCamel(struct_def);
+
+ code += GenIndents(indents) + "self." + field_instance_name + " = []";
+ code += GenIndents(indents) + "for i in range(" + struct_instance_name +
+ "." + field_accessor_name + "Length()):";
+ code += GenIndents(indents + 1) + "self." + field_instance_name +
+ ".append(" + struct_instance_name + "." + field_accessor_name +
+ "(i))";
+ }
+
+ void GenUnPackForScalarVector(const StructDef &struct_def,
+ const FieldDef &field, std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_instance_name = MakeLowerCamel(struct_def);
+
+ code += GenIndents(2) + "if not " + struct_instance_name + "." +
+ field_accessor_name + "IsNone():";
+
+ // String does not have the AsNumpy method.
+ if (!(IsScalar(field.value.type.VectorType().base_type))) {
+ GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 3);
+ return;
+ }
+
+ code += GenIndents(3) + "if np is None:";
+ GenUnpackforScalarVectorHelper(struct_def, field, code_ptr, 4);
+
+ // If numpy exists, use the AsNumpy method to optimize the unpack speed.
+ code += GenIndents(3) + "else:";
+ code += GenIndents(4) + "self." + field_instance_name + " = " +
+ struct_instance_name + "." + field_accessor_name + "AsNumpy()";
+ }
+
+ void GenUnPackForScalar(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_instance_name = MakeLowerCamel(struct_def);
+
+ code += GenIndents(2) + "self." + field_instance_name + " = " +
+ struct_instance_name + "." + field_accessor_name + "()";
+ }
+
+ // Generates the UnPack method for the object class.
+ void GenUnPack(const StructDef &struct_def, std::string *code_ptr) {
+ std::string code;
+ // Items that needs to be imported. No duplicate modules will be imported.
+ std::set<std::string> import_list;
+
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+
+ auto field_type = TypeName(field);
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT: {
+ GenUnPackForStruct(struct_def, field, &code);
+ break;
+ }
+ case BASE_TYPE_UNION: {
+ GenUnPackForUnion(struct_def, field, &code);
+ break;
+ }
+ case BASE_TYPE_VECTOR: {
+ auto vectortype = field.value.type.VectorType();
+ if (vectortype.base_type == BASE_TYPE_STRUCT) {
+ GenUnPackForStructVector(struct_def, field, &code);
+ } else {
+ GenUnPackForScalarVector(struct_def, field, &code);
+ }
+ break;
+ }
+ case BASE_TYPE_ARRAY: {
+ GenUnPackForScalarVector(struct_def, field, &code);
+ break;
+ }
+ default: GenUnPackForScalar(struct_def, field, &code);
+ }
+ }
+
+ // Writes import statements and code into the generated file.
+ auto &code_base = *code_ptr;
+ auto struct_instance_name = MakeLowerCamel(struct_def);
+ auto struct_name = MakeUpperCamel(struct_def);
+
+ GenReceiverForObjectAPI(struct_def, code_ptr);
+ code_base += "_UnPack(self, " + struct_instance_name + "):";
+ code_base += GenIndents(2) + "if " + struct_instance_name + " is None:";
+ code_base += GenIndents(3) + "return";
+
+ // Write the import statements.
+ for (std::set<std::string>::iterator it = import_list.begin();
+ it != import_list.end(); ++it) {
+ code_base += GenIndents(2) + *it;
+ }
+
+ // Write the code.
+ code_base += code;
+ code_base += "\n";
+ }
+
+ void GenPackForStruct(const StructDef &struct_def, std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto struct_name = MakeUpperCamel(struct_def);
+
+ GenReceiverForObjectAPI(struct_def, code_ptr);
+ code += "Pack(self, builder):";
+ code += GenIndents(2) + "return Create" + struct_name + "(builder";
+
+ StructBuilderArgs(struct_def,
+ /* nameprefix = */ "self.",
+ /* namesuffix = */ "",
+ /* has_field_name = */ true,
+ /* fieldname_suffix = */ ".", code_ptr);
+ code += ")\n";
+ }
+
+ void GenPackForStructVectorField(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_prefix_ptr,
+ std::string *code_ptr) {
+ auto &code_prefix = *code_prefix_ptr;
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+ auto struct_name = NormalizedName(struct_def);
+ auto field_accessor_name = MakeUpperCamel(field);
+
+ // Creates the field.
+ code_prefix +=
+ GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ if (field.value.type.struct_def->fixed) {
+ code_prefix += GenIndents(3) + struct_name + "Start" +
+ field_accessor_name + "Vector(builder, len(self." +
+ field_instance_name + "))";
+ code_prefix += GenIndents(3) + "for i in reversed(range(len(self." +
+ field_instance_name + "))):";
+ code_prefix +=
+ GenIndents(4) + "self." + field_instance_name + "[i].Pack(builder)";
+ code_prefix += GenIndents(3) + field_instance_name +
+ " = builder.EndVector(len(self." + field_instance_name +
+ "))";
+ } else {
+ // If the vector is a struct vector, we need to first build accessor for
+ // each struct element.
+ code_prefix += GenIndents(3) + field_instance_name + "list = []";
+ code_prefix += GenIndents(3);
+ code_prefix += "for i in range(len(self." + field_instance_name + ")):";
+ code_prefix += GenIndents(4) + field_instance_name + "list.append(self." +
+ field_instance_name + "[i].Pack(builder))";
+
+ code_prefix += GenIndents(3) + struct_name + "Start" +
+ field_accessor_name + "Vector(builder, len(self." +
+ field_instance_name + "))";
+ code_prefix += GenIndents(3) + "for i in reversed(range(len(self." +
+ field_instance_name + "))):";
+ code_prefix += GenIndents(4) + "builder.PrependUOffsetTRelative" + "(" +
+ field_instance_name + "list[i])";
+ code_prefix += GenIndents(3) + field_instance_name +
+ " = builder.EndVector(len(self." + field_instance_name +
+ "))";
+ }
+
+ // Adds the field into the struct.
+ code += GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+ "(builder, " + field_instance_name + ")";
+ }
+
+ void GenPackForScalarVectorFieldHelper(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_ptr, int indents) {
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_name = NormalizedName(struct_def);
+ auto vectortype = field.value.type.VectorType();
+
+ code += GenIndents(indents) + struct_name + "Start" + field_accessor_name +
+ "Vector(builder, len(self." + field_instance_name + "))";
+ code += GenIndents(indents) + "for i in reversed(range(len(self." +
+ field_instance_name + "))):";
+ code += GenIndents(indents + 1) + "builder.Prepend";
+
+ std::string type_name;
+ switch (vectortype.base_type) {
+ case BASE_TYPE_BOOL: type_name = "Bool"; break;
+ case BASE_TYPE_CHAR: type_name = "Byte"; break;
+ case BASE_TYPE_UCHAR: type_name = "Uint8"; break;
+ case BASE_TYPE_SHORT: type_name = "Int16"; break;
+ case BASE_TYPE_USHORT: type_name = "Uint16"; break;
+ case BASE_TYPE_INT: type_name = "Int32"; break;
+ case BASE_TYPE_UINT: type_name = "Uint32"; break;
+ case BASE_TYPE_LONG: type_name = "Int64"; break;
+ case BASE_TYPE_ULONG: type_name = "Uint64"; break;
+ case BASE_TYPE_FLOAT: type_name = "Float32"; break;
+ case BASE_TYPE_DOUBLE: type_name = "Float64"; break;
+ case BASE_TYPE_STRING: type_name = "UOffsetTRelative"; break;
+ default: type_name = "VOffsetT"; break;
+ }
+ code += type_name;
+ }
+
+ void GenPackForScalarVectorField(const StructDef &struct_def,
+ const FieldDef &field,
+ std::string *code_prefix_ptr,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto &code_prefix = *code_prefix_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_name = NormalizedName(struct_def);
+
+ // Adds the field into the struct.
+ code += GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+ "(builder, " + field_instance_name + ")";
+
+ // Creates the field.
+ code_prefix +=
+ GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ // If the vector is a string vector, we need to first build accessor for
+ // each string element. And this generated code, needs to be
+ // placed ahead of code_prefix.
+ auto vectortype = field.value.type.VectorType();
+ if (vectortype.base_type == BASE_TYPE_STRING) {
+ code_prefix += GenIndents(3) + MakeLowerCamel(field) + "list = []";
+ code_prefix += GenIndents(3) + "for i in range(len(self." +
+ field_instance_name + ")):";
+ code_prefix += GenIndents(4) + MakeLowerCamel(field) +
+ "list.append(builder.CreateString(self." +
+ field_instance_name + "[i]))";
+ GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 3);
+ code_prefix += "(" + MakeLowerCamel(field) + "list[i])";
+ code_prefix += GenIndents(3) + field_instance_name +
+ " = builder.EndVector(len(self." + field_instance_name +
+ "))";
+ return;
+ }
+
+ code_prefix += GenIndents(3) + "if np is not None and type(self." +
+ field_instance_name + ") is np.ndarray:";
+ code_prefix += GenIndents(4) + field_instance_name +
+ " = builder.CreateNumpyVector(self." + field_instance_name +
+ ")";
+ code_prefix += GenIndents(3) + "else:";
+ GenPackForScalarVectorFieldHelper(struct_def, field, code_prefix_ptr, 4);
+ code_prefix += "(self." + field_instance_name + "[i])";
+ code_prefix += GenIndents(4) + field_instance_name +
+ " = builder.EndVector(len(self." + field_instance_name +
+ "))";
+ }
+
+ void GenPackForStructField(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_prefix_ptr,
+ std::string *code_ptr) {
+ auto &code_prefix = *code_prefix_ptr;
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_name = NormalizedName(struct_def);
+
+ if (field.value.type.struct_def->fixed) {
+ // Pure struct fields need to be created along with their parent
+ // structs.
+ code +=
+ GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ code += GenIndents(3) + field_instance_name + " = self." +
+ field_instance_name + ".Pack(builder)";
+ } else {
+ // Tables need to be created before their parent structs are created.
+ code_prefix +=
+ GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ code_prefix += GenIndents(3) + field_instance_name + " = self." +
+ field_instance_name + ".Pack(builder)";
+ code +=
+ GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ }
+
+ code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+ "(builder, " + field_instance_name + ")";
+ }
+
+ void GenPackForUnionField(const StructDef &struct_def, const FieldDef &field,
+ std::string *code_prefix_ptr,
+ std::string *code_ptr) {
+ auto &code_prefix = *code_prefix_ptr;
+ auto &code = *code_ptr;
+ auto field_instance_name = MakeLowerCamel(field);
+
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto struct_name = NormalizedName(struct_def);
+
+ // TODO(luwa): TypeT should be moved under the None check as well.
+ code_prefix +=
+ GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ code_prefix += GenIndents(3) + field_instance_name + " = self." +
+ field_instance_name + ".Pack(builder)";
+ code += GenIndents(2) + "if self." + field_instance_name + " is not None:";
+ code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+ "(builder, " + field_instance_name + ")";
+ }
+
+ void GenPackForTable(const StructDef &struct_def, std::string *code_ptr) {
+ auto &code_base = *code_ptr;
+ std::string code, code_prefix;
+ auto struct_instance_name = MakeLowerCamel(struct_def);
+ auto struct_name = NormalizedName(struct_def);
+
+ GenReceiverForObjectAPI(struct_def, code_ptr);
+ code_base += "Pack(self, builder):";
+ code += GenIndents(2) + struct_name + "Start(builder)";
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+
+ auto field_accessor_name = MakeUpperCamel(field);
+ auto field_instance_name = MakeLowerCamel(field);
+
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT: {
+ GenPackForStructField(struct_def, field, &code_prefix, &code);
+ break;
+ }
+ case BASE_TYPE_UNION: {
+ GenPackForUnionField(struct_def, field, &code_prefix, &code);
+ break;
+ }
+ case BASE_TYPE_VECTOR: {
+ auto vectortype = field.value.type.VectorType();
+ if (vectortype.base_type == BASE_TYPE_STRUCT) {
+ GenPackForStructVectorField(struct_def, field, &code_prefix, &code);
+ } else {
+ GenPackForScalarVectorField(struct_def, field, &code_prefix, &code);
+ }
+ break;
+ }
+ case BASE_TYPE_ARRAY: {
+ GenPackForScalarVectorField(struct_def, field, &code_prefix, &code);
+ break;
+ }
+ case BASE_TYPE_STRING: {
+ code_prefix += GenIndents(2) + "if self." + field_instance_name +
+ " is not None:";
+ code_prefix += GenIndents(3) + field_instance_name +
+ " = builder.CreateString(self." + field_instance_name +
+ ")";
+ code += GenIndents(2) + "if self." + field_instance_name +
+ " is not None:";
+ code += GenIndents(3) + struct_name + "Add" + field_accessor_name +
+ "(builder, " + field_instance_name + ")";
+ break;
+ }
+ default:
+ // Generates code for scalar values. If the value equals to the
+ // default value, builder will automatically ignore it. So we don't
+ // need to check the value ahead.
+ code += GenIndents(2) + struct_name + "Add" + field_accessor_name +
+ "(builder, self." + field_instance_name + ")";
+ break;
+ }
+ }
+
+ code += GenIndents(2) + struct_instance_name + " = " + struct_name +
+ "End(builder)";
+ code += GenIndents(2) + "return " + struct_instance_name;
+
+ code_base += code_prefix + code;
+ code_base += "\n";
+ }
+
+ void GenStructForObjectAPI(const StructDef &struct_def,
+ std::string *code_ptr) {
+ if (struct_def.generated) return;
+
+ std::set<std::string> import_list;
+ std::string code;
+
+ // Creates an object class for a struct or a table
+ BeginClassForObjectAPI(struct_def, &code);
+
+ GenInitialize(struct_def, &code, &import_list);
+
+ InitializeFromBuf(struct_def, &code);
+
+ InitializeFromObjForObject(struct_def, &code);
+
+ GenUnPack(struct_def, &code);
+
+ if (struct_def.fixed) {
+ GenPackForStruct(struct_def, &code);
+ } else {
+ GenPackForTable(struct_def, &code);
+ }
+
+ // Adds the imports at top.
+ auto &code_base = *code_ptr;
+ code_base += "\n";
+ for (auto it = import_list.begin(); it != import_list.end(); it++) {
+ auto im = *it;
+ code_base += im + "\n";
+ }
+ code_base += code;
+ }
+
+ void GenUnionCreatorForStruct(const EnumDef &enum_def, const EnumVal &ev,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto union_name = NormalizedName(enum_def);
+ auto field_name = NormalizedName(ev);
+ auto field_type = GenTypeGet(ev.union_type) + "T";
+
+ code += GenIndents(1) + "if unionType == " + union_name + "()." +
+ field_name + ":";
+ if (parser_.opts.include_dependence_headers) {
+ auto package_reference = GenPackageReference(ev.union_type);
+ code += GenIndents(2) + "import " + package_reference;
+ field_type = package_reference + "." + field_type;
+ }
+ code += GenIndents(2) + "return " + field_type +
+ ".InitFromBuf(table.Bytes, table.Pos)";
+ }
+
+ void GenUnionCreatorForString(const EnumDef &enum_def, const EnumVal &ev,
+ std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto union_name = NormalizedName(enum_def);
+ auto field_name = NormalizedName(ev);
+
+ code += GenIndents(1) + "if unionType == " + union_name + "()." +
+ field_name + ":";
+ code += GenIndents(2) + "tab = Table(table.Bytes, table.Pos)";
+ code += GenIndents(2) + "union = tab.String(table.Pos)";
+ code += GenIndents(2) + "return union";
+ }
+
+ // Creates an union object based on union type.
+ void GenUnionCreator(const EnumDef &enum_def, std::string *code_ptr) {
+ auto &code = *code_ptr;
+ auto union_name = MakeUpperCamel(enum_def);
+
+ code += "\n";
+ code += "def " + union_name + "Creator(unionType, table):";
+ code += GenIndents(1) + "from flatbuffers.table import Table";
+ code += GenIndents(1) + "if not isinstance(table, Table):";
+ code += GenIndents(2) + "return None";
+
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ auto &ev = **it;
+ // Union only supports string and table.
+ switch (ev.union_type.base_type) {
+ case BASE_TYPE_STRUCT:
+ GenUnionCreatorForStruct(enum_def, ev, &code);
+ break;
+ case BASE_TYPE_STRING:
+ GenUnionCreatorForString(enum_def, ev, &code);
+ break;
+ default: break;
+ }
+ }
+ code += GenIndents(1) + "return None";
+ code += "\n";
+ }
+
// Generate enum declarations.
void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
if (enum_def.generated) return;
- GenComment(enum_def.doc_comment, code_ptr, nullptr, "# ");
+ GenComment(enum_def.doc_comment, code_ptr, &def_comment);
BeginEnum(NormalizedName(enum_def), code_ptr);
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
auto &ev = **it;
- GenComment(ev.doc_comment, code_ptr, nullptr, "# ");
+ GenComment(ev.doc_comment, code_ptr, &def_comment, Indent.c_str());
EnumMember(enum_def, ev, code_ptr);
}
EndEnum(code_ptr);
@@ -607,28 +1515,29 @@ class PythonGenerator : public BaseGenerator {
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
default:
return "self._tab.Get(flatbuffers.number_types." +
- MakeCamel(GenTypeGet(type)) + "Flags, ";
+ MakeCamel(GenTypeGet(type)) + "Flags, ";
}
}
// Returns the method name for use with add/put calls.
std::string GenMethod(const FieldDef &field) {
- return IsScalar(field.value.type.base_type)
- ? MakeCamel(GenTypeBasic(field.value.type))
- : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative");
+ return (IsScalar(field.value.type.base_type) || IsArray(field.value.type))
+ ? MakeCamel(GenTypeBasic(field.value.type))
+ : (IsStruct(field.value.type) ? "Struct" : "UOffsetTRelative");
}
std::string GenTypeBasic(const Type &type) {
- static const char *ctypename[] = {
// clang-format off
+ static const char *ctypename[] = {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \
#PTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- // clang-format on
};
- return ctypename[type.base_type];
+ // clang-format on
+ return ctypename[IsArray(type) ? type.VectorType().base_type
+ : type.base_type];
}
std::string GenTypePointer(const Type &type) {
@@ -651,10 +1560,13 @@ class PythonGenerator : public BaseGenerator {
}
// Create a struct with a builder and the struct's arguments.
- void GenStructBuilder(const StructDef &struct_def,
- std::string *code_ptr) {
+ void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
BeginBuilderArgs(struct_def, code_ptr);
- StructBuilderArgs(struct_def, "", code_ptr);
+ StructBuilderArgs(struct_def,
+ /* nameprefix = */ "",
+ /* namesuffix = */ "",
+ /* has_field_name = */ true,
+ /* fieldname_suffix = */ "_", code_ptr);
EndBuilderArgs(code_ptr);
StructBuilderBody(struct_def, "", code_ptr);
@@ -674,6 +1586,9 @@ class PythonGenerator : public BaseGenerator {
auto &enum_def = **it;
std::string enumcode;
GenEnum(enum_def, &enumcode);
+ if (parser_.opts.generate_object_based_api & enum_def.is_union) {
+ GenUnionCreator(enum_def, &enumcode);
+ }
if (!SaveType(enum_def, enumcode, false)) return false;
}
return true;
@@ -685,18 +1600,25 @@ class PythonGenerator : public BaseGenerator {
auto &struct_def = **it;
std::string declcode;
GenStruct(struct_def, &declcode);
+ if (parser_.opts.generate_object_based_api) {
+ GenStructForObjectAPI(struct_def, &declcode);
+ }
if (!SaveType(struct_def, declcode, true)) return false;
}
return true;
}
// Begin by declaring namespace and imports.
- void BeginFile(const std::string name_space_name, const bool needs_imports,
+ void BeginFile(const std::string &name_space_name, const bool needs_imports,
std::string *code_ptr) {
- std::string &code = *code_ptr;
+ auto &code = *code_ptr;
code = code + "# " + FlatBuffersGeneratedWarning() + "\n\n";
code += "# namespace: " + name_space_name + "\n\n";
- if (needs_imports) { code += "import flatbuffers\n\n"; }
+ if (needs_imports) {
+ code += "import flatbuffers\n";
+ code += "from flatbuffers.compat import import_numpy\n";
+ code += "np = import_numpy()\n\n";
+ }
}
// Save out the generated code for a Python Table type.
@@ -720,6 +1642,7 @@ class PythonGenerator : public BaseGenerator {
NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py";
return SaveFile(filename.c_str(), code, false);
}
+
private:
std::unordered_set<std::string> keywords_;
const SimpleFloatConstantGenerator float_const_gen_;
diff --git a/src/idl_gen_rust.cpp b/src/idl_gen_rust.cpp
index 23fd34a7..55b8439b 100644
--- a/src/idl_gen_rust.cpp
+++ b/src/idl_gen_rust.cpp
@@ -23,11 +23,6 @@
namespace flatbuffers {
-static std::string GeneratedFileName(const std::string &path,
- const std::string &file_name) {
- return path + file_name + "_generated.rs";
-}
-
// Convert a camelCaseIdentifier or CamelCaseIdentifier to a
// snake_case_indentifier.
std::string MakeSnakeCase(const std::string &in) {
@@ -40,9 +35,7 @@ std::string MakeSnakeCase(const std::string &in) {
} else if (!islower(in[i])) {
// Prevent duplicate underscores for Upper_Snake_Case strings
// and UPPERCASE strings.
- if (islower(in[i - 1])) {
- s += '_';
- }
+ if (islower(in[i - 1])) { s += '_'; }
s += static_cast<char>(tolower(in[i]));
} else {
s += in[i];
@@ -190,7 +183,7 @@ class RustGenerator : public BaseGenerator {
public:
RustGenerator(const Parser &parser, const std::string &path,
const std::string &file_name)
- : BaseGenerator(parser, path, file_name, "", "::"),
+ : BaseGenerator(parser, path, file_name, "", "::", "rs"),
cur_name_space_(nullptr) {
const char *keywords[] = {
// list taken from:
@@ -200,77 +193,19 @@ class RustGenerator : public BaseGenerator {
// changes to that webpage in the future.
// currently-used keywords
- "as",
- "break",
- "const",
- "continue",
- "crate",
- "else",
- "enum",
- "extern",
- "false",
- "fn",
- "for",
- "if",
- "impl",
- "in",
- "let",
- "loop",
- "match",
- "mod",
- "move",
- "mut",
- "pub",
- "ref",
- "return",
- "Self",
- "self",
- "static",
- "struct",
- "super",
- "trait",
- "true",
- "type",
- "unsafe",
- "use",
- "where",
- "while",
+ "as", "break", "const", "continue", "crate", "else", "enum", "extern",
+ "false", "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod",
+ "move", "mut", "pub", "ref", "return", "Self", "self", "static", "struct",
+ "super", "trait", "true", "type", "unsafe", "use", "where", "while",
// future possible keywords
- "abstract",
- "alignof",
- "become",
- "box",
- "do",
- "final",
- "macro",
- "offsetof",
- "override",
- "priv",
- "proc",
- "pure",
- "sizeof",
- "typeof",
- "unsized",
- "virtual",
- "yield",
+ "abstract", "alignof", "become", "box", "do", "final", "macro",
+ "offsetof", "override", "priv", "proc", "pure", "sizeof", "typeof",
+ "unsized", "virtual", "yield",
// other rust terms we should not use
- "std",
- "usize",
- "isize",
- "u8",
- "i8",
- "u16",
- "i16",
- "u32",
- "i32",
- "u64",
- "i64",
- "u128",
- "i128",
- "f32",
- "f64",
+ "std", "usize", "isize", "u8", "i8", "u16", "i16", "u32", "i32", "u64",
+ "i64", "u128", "i128", "f32", "f64",
// These are terms the code generator can implement on types.
//
@@ -281,13 +216,9 @@ class RustGenerator : public BaseGenerator {
// implementation detail, and how we implement methods could change in
// the future. as a result, we proactively block these out as reserved
// words.
- "follow",
- "push",
- "size",
- "alignment",
- "to_little_endian",
- "from_little_endian",
- nullptr };
+ "follow", "push", "size", "alignment", "to_little_endian",
+ "from_little_endian", nullptr
+ };
for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
}
@@ -310,8 +241,7 @@ class RustGenerator : public BaseGenerator {
// TODO(rw): Use a set data structure to reduce namespace evaluations from
// O(n**2) to O(n).
for (auto ns_it = parser_.namespaces_.begin();
- ns_it != parser_.namespaces_.end();
- ++ns_it) {
+ ns_it != parser_.namespaces_.end(); ++ns_it) {
const auto &ns = *ns_it;
// Generate code for all the enum declarations.
@@ -357,7 +287,7 @@ class RustGenerator : public BaseGenerator {
}
if (cur_name_space_) SetNameSpace(nullptr);
- const auto file_path = GeneratedFileName(path_, file_name_);
+ const auto file_path = GeneratedFileName(path_, file_name_, parser_.opts);
const auto final_code = code_.ToString();
return SaveFile(file_path.c_str(), final_code, false);
}
@@ -381,8 +311,12 @@ class RustGenerator : public BaseGenerator {
case ftBool:
case ftEnumKey:
case ftUnionKey:
- case ftUnionValue: { return false; }
- default: { return true; }
+ case ftUnionValue: {
+ return false;
+ }
+ default: {
+ return true;
+ }
}
}
@@ -393,13 +327,9 @@ class RustGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
- if (field.deprecated) {
- continue;
- }
+ if (field.deprecated) { continue; }
- if (TableBuilderTypeNeedsLifetime(field.value.type)) {
- return true;
- }
+ if (TableBuilderTypeNeedsLifetime(field.value.type)) { return true; }
}
return false;
@@ -410,14 +340,18 @@ class RustGenerator : public BaseGenerator {
bool StructMemberAccessNeedsCopy(const Type &type) const {
switch (GetFullType(type)) {
case ftInteger: // requires endian swap
- case ftFloat: // requires endian swap
- case ftBool: // no endian-swap, but do the copy for UX consistency
- case ftEnumKey: { return true; } // requires endian swap
- case ftStruct: { return false; } // no endian swap
+ case ftFloat: // requires endian swap
+ case ftBool: // no endian-swap, but do the copy for UX consistency
+ case ftEnumKey: {
+ return true;
+ } // requires endian swap
+ case ftStruct: {
+ return false;
+ } // no endian swap
default: {
// logic error: no other types can be struct members.
FLATBUFFERS_ASSERT(false && "invalid struct member type");
- return false; // only to satisfy compiler's return analysis
+ return false; // only to satisfy compiler's return analysis
}
}
}
@@ -449,7 +383,7 @@ class RustGenerator : public BaseGenerator {
std::stringstream stream;
stream << "::";
- for (auto d = dst->components.begin(); d != dst->components.end(); d++) {
+ for (auto d = dst->components.begin(); d != dst->components.end(); ++d) {
stream << MakeSnakeCase(*d) + "::";
}
return stream.str();
@@ -477,19 +411,17 @@ class RustGenerator : public BaseGenerator {
auto s = src->components.begin();
auto d = dst->components.begin();
- for(;;) {
+ for (;;) {
if (s == src->components.end()) { break; }
if (d == dst->components.end()) { break; }
if (*s != *d) { break; }
- s++;
- d++;
- i++;
+ ++s;
+ ++d;
+ ++i;
}
- for (; s != src->components.end(); s++) {
- stream << "super::";
- }
- for (; d != dst->components.end(); d++) {
+ for (; s != src->components.end(); ++s) { stream << "super::"; }
+ for (; d != dst->components.end(); ++d) {
stream << MakeSnakeCase(*d) + "::";
}
return stream.str();
@@ -509,19 +441,23 @@ class RustGenerator : public BaseGenerator {
case ftFloat:
case ftBool:
case ftEnumKey:
- case ftUnionKey: { break; }
- default: { FLATBUFFERS_ASSERT(false && "incorrect type given");}
+ case ftUnionKey: {
+ break;
+ }
+ default: {
+ FLATBUFFERS_ASSERT(false && "incorrect type given");
+ }
}
// clang-format off
static const char * const ctypename[] = {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
- RTYPE) \
- #RTYPE,
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ RTYPE, ...) \
+ #RTYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- // clang-format on
};
+ // clang-format on
if (type.enum_def) { return WrapInNameSpace(*type.enum_def); }
return ctypename[type.base_type];
@@ -535,15 +471,15 @@ class RustGenerator : public BaseGenerator {
FLATBUFFERS_ASSERT(false && "precondition failed in GetEnumTypeForDecl");
}
- static const char *ctypename[] = {
// clang-format off
+ static const char *ctypename[] = {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
- RTYPE) \
- #RTYPE,
- FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ RTYPE, ...) \
+ #RTYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- // clang-format on
};
+ // clang-format on
// Enums can be bools, but their Rust representation must be a u8, as used
// in the repr attribute (#[repr(bool)] is an invalid attribute).
@@ -560,13 +496,17 @@ class RustGenerator : public BaseGenerator {
case ftBool:
case ftEnumKey:
case ftUnionKey: {
- return GetTypeBasic(type); }
+ return GetTypeBasic(type);
+ }
case ftTable: {
return WrapInNameSpace(type.struct_def->defined_namespace,
- type.struct_def->name) + "<'a>"; }
+ type.struct_def->name) +
+ "<'a>";
+ }
default: {
return WrapInNameSpace(type.struct_def->defined_namespace,
- type.struct_def->name); }
+ type.struct_def->name);
+ }
}
}
@@ -586,23 +526,21 @@ class RustGenerator : public BaseGenerator {
GenComment(enum_def.doc_comment);
code_ += "#[allow(non_camel_case_types)]";
code_ += "#[repr({{BASE_TYPE}})]";
- code_ += "#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]";
+ code_ +=
+ "#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]";
code_ += "pub enum " + Name(enum_def) + " {";
- int64_t anyv = 0;
- const EnumVal *minv = nullptr, *maxv = nullptr;
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
const auto &ev = **it;
GenComment(ev.doc_comment, " ");
code_.SetValue("KEY", Name(ev));
- code_.SetValue("VALUE", NumToString(ev.value));
+ code_.SetValue("VALUE", enum_def.ToString(ev));
code_ += " {{KEY}} = {{VALUE}},";
-
- minv = !minv || minv->value > ev.value ? &ev : minv;
- maxv = !maxv || maxv->value < ev.value ? &ev : maxv;
- anyv |= ev.value;
}
+ const EnumVal *minv = enum_def.MinValue();
+ const EnumVal *maxv = enum_def.MaxValue();
+ FLATBUFFERS_ASSERT(minv && maxv);
code_ += "";
code_ += "}";
@@ -611,13 +549,13 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("ENUM_NAME", Name(enum_def));
code_.SetValue("ENUM_NAME_SNAKE", MakeSnakeCase(Name(enum_def)));
code_.SetValue("ENUM_NAME_CAPS", MakeUpper(MakeSnakeCase(Name(enum_def))));
- code_.SetValue("ENUM_MIN_BASE_VALUE", NumToString(minv->value));
- code_.SetValue("ENUM_MAX_BASE_VALUE", NumToString(maxv->value));
+ code_.SetValue("ENUM_MIN_BASE_VALUE", enum_def.ToString(*minv));
+ code_.SetValue("ENUM_MAX_BASE_VALUE", enum_def.ToString(*maxv));
// Generate enum constants, and impls for Follow, EndianScalar, and Push.
- code_ += "const ENUM_MIN_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}} = \\";
+ code_ += "pub const ENUM_MIN_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}} = \\";
code_ += "{{ENUM_MIN_BASE_VALUE}};";
- code_ += "const ENUM_MAX_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}} = \\";
+ code_ += "pub const ENUM_MAX_{{ENUM_NAME_CAPS}}: {{BASE_TYPE}} = \\";
code_ += "{{ENUM_MAX_BASE_VALUE}};";
code_ += "";
code_ += "impl<'a> flatbuffers::Follow<'a> for {{ENUM_NAME}} {";
@@ -647,8 +585,9 @@ class RustGenerator : public BaseGenerator {
code_ += " type Output = {{ENUM_NAME}};";
code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
- code_ += " flatbuffers::emplace_scalar::<{{ENUM_NAME}}>"
- "(dst, *self);";
+ code_ +=
+ " flatbuffers::emplace_scalar::<{{ENUM_NAME}}>"
+ "(dst, *self);";
code_ += " }";
code_ += "}";
code_ += "";
@@ -656,8 +595,8 @@ class RustGenerator : public BaseGenerator {
// Generate an array of all enumeration values.
auto num_fields = NumToString(enum_def.size());
code_ += "#[allow(non_camel_case_types)]";
- code_ += "const ENUM_VALUES_{{ENUM_NAME_CAPS}}:[{{ENUM_NAME}}; " +
- num_fields + "] = [";
+ code_ += "pub const ENUM_VALUES_{{ENUM_NAME_CAPS}}:[{{ENUM_NAME}}; " +
+ num_fields + "] = [";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
const auto &ev = **it;
auto value = GetEnumValUse(enum_def, ev);
@@ -671,34 +610,36 @@ class RustGenerator : public BaseGenerator {
// Problem is, if values are very sparse that could generate really big
// tables. Ideally in that case we generate a map lookup instead, but for
// the moment we simply don't output a table at all.
- auto range =
- enum_def.vals.vec.back()->value - enum_def.vals.vec.front()->value + 1;
+ auto range = enum_def.Distance();
// Average distance between values above which we consider a table
// "too sparse". Change at will.
- static const int kMaxSparseness = 5;
- if (range / static_cast<int64_t>(enum_def.vals.vec.size()) <
- kMaxSparseness) {
+ static const uint64_t kMaxSparseness = 5;
+ if (range / static_cast<uint64_t>(enum_def.size()) < kMaxSparseness) {
code_ += "#[allow(non_camel_case_types)]";
- code_ += "const ENUM_NAMES_{{ENUM_NAME_CAPS}}:[&'static str; " +
- NumToString(range) + "] = [";
+ code_ += "pub const ENUM_NAMES_{{ENUM_NAME_CAPS}}:[&'static str; " +
+ NumToString(range + 1) + "] = [";
- auto val = enum_def.Vals().front()->value;
+ auto val = enum_def.Vals().front();
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
++it) {
- const auto &ev = **it;
- while (val++ != ev.value) { code_ += " \"\","; }
- auto suffix = *it != enum_def.vals.vec.back() ? "," : "";
- code_ += " \"" + Name(ev) + "\"" + suffix;
+ auto ev = *it;
+ for (auto k = enum_def.Distance(val, ev); k > 1; --k) {
+ code_ += " \"\",";
+ }
+ val = ev;
+ auto suffix = *it != enum_def.Vals().back() ? "," : "";
+ code_ += " \"" + Name(*ev) + "\"" + suffix;
}
code_ += "];";
code_ += "";
- code_ += "pub fn enum_name_{{ENUM_NAME_SNAKE}}(e: {{ENUM_NAME}}) -> "
- "&'static str {";
+ code_ +=
+ "pub fn enum_name_{{ENUM_NAME_SNAKE}}(e: {{ENUM_NAME}}) -> "
+ "&'static str {";
code_ += " let index = e as {{BASE_TYPE}}\\";
- if (enum_def.vals.vec.front()->value) {
- auto vals = GetEnumValUse(enum_def, *enum_def.vals.vec.front());
+ if (enum_def.MinValue()->IsNonZero()) {
+ auto vals = GetEnumValUse(enum_def, *enum_def.MinValue());
code_ += " - " + vals + " as {{BASE_TYPE}}\\";
}
code_ += ";";
@@ -728,15 +669,18 @@ class RustGenerator : public BaseGenerator {
std::string GetDefaultScalarValue(const FieldDef &field) {
switch (GetFullType(field.value.type)) {
- case ftInteger: { return GetDefaultConstant(field); }
- case ftFloat: { return GetDefaultConstant(field); }
+ case ftInteger: {
+ return GetDefaultConstant(field);
+ }
+ case ftFloat: {
+ return GetDefaultConstant(field);
+ }
case ftBool: {
return field.value.constant == "0" ? "false" : "true";
}
case ftUnionKey:
case ftEnumKey: {
- auto ev = field.value.type.enum_def->ReverseLookup(
- StringToInt(field.value.constant.c_str()), false);
+ auto ev = field.value.type.enum_def->FindByValue(field.value.constant);
assert(ev);
return WrapInNameSpace(field.value.type.enum_def->defined_namespace,
GetEnumValUse(*field.value.type.enum_def, *ev));
@@ -744,7 +688,9 @@ class RustGenerator : public BaseGenerator {
// All pointer-ish types have a default value of None, because they are
// wrapped in Option.
- default: { return "None"; }
+ default: {
+ return "None";
+ }
}
}
@@ -760,8 +706,8 @@ class RustGenerator : public BaseGenerator {
// the vtable, or
// 3) return a hardcoded value because the vtable field value is set to zero.
std::string TableBuilderArgsDefnType(const FieldDef &field,
- const std::string lifetime) {
- const Type& type = field.value.type;
+ const std::string &lifetime) {
+ const Type &type = field.value.type;
switch (GetFullType(type)) {
case ftInteger:
@@ -776,7 +722,7 @@ class RustGenerator : public BaseGenerator {
}
case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return "Option<flatbuffers::WIPOffset<" + typname + "<" + lifetime + \
+ return "Option<flatbuffers::WIPOffset<" + typname + "<" + lifetime +
">>>";
}
case ftString: {
@@ -788,107 +734,109 @@ class RustGenerator : public BaseGenerator {
return typname;
}
case ftUnionValue: {
- const auto typname = WrapInNameSpace(*type.enum_def);
return "Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>";
}
case ftVectorOfInteger:
case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType());
- return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
- lifetime + ", " + typname + ">>>";
+ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", " + typname + ">>>";
}
case ftVectorOfBool: {
- return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
- lifetime + ", bool>>>";
+ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", bool>>>";
}
case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def);
- return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
- lifetime + ", " + typname + ">>>";
+ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", " + typname + ">>>";
}
case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
- lifetime + ", " + typname + ">>>";
+ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", " + typname + ">>>";
}
case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
- lifetime + ", flatbuffers::ForwardsUOffset<" + typname + \
- "<" + lifetime + ">>>>>";
+ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", flatbuffers::ForwardsUOffset<" + typname + "<" + lifetime +
+ ">>>>>";
}
case ftVectorOfString: {
- return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
- lifetime + ", flatbuffers::ForwardsUOffset<&" + lifetime + \
- " str>>>>";
+ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>>>";
}
case ftVectorOfUnionValue: {
- const auto typname = WrapInNameSpace(*type.enum_def) + \
- "UnionTableOffset";
- return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + \
- lifetime + ", flatbuffers::ForwardsUOffset<"
- "flatbuffers::Table<" + lifetime + ">>>>";
+ const auto typname =
+ WrapInNameSpace(*type.enum_def) + "UnionTableOffset";
+ return "Option<flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", flatbuffers::ForwardsUOffset<"
+ "flatbuffers::Table<" +
+ lifetime + ">>>>";
}
}
- return "INVALID_CODE_GENERATION"; // for return analysis
+ return "INVALID_CODE_GENERATION"; // for return analysis
}
std::string TableBuilderArgsDefaultValue(const FieldDef &field) {
return GetDefaultScalarValue(field);
}
std::string TableBuilderAddFuncDefaultValue(const FieldDef &field) {
+ // All branches of switch do the same action!
switch (GetFullType(field.value.type)) {
case ftUnionKey:
case ftEnumKey: {
- const std::string basetype = GetTypeBasic(field.value.type);
+ const std::string basetype =
+ GetTypeBasic(field.value.type); //<- never used
return GetDefaultScalarValue(field);
}
- default: { return GetDefaultScalarValue(field); }
+ default: {
+ return GetDefaultScalarValue(field);
+ }
}
}
std::string TableBuilderArgsAddFuncType(const FieldDef &field,
- const std::string lifetime) {
- const Type& type = field.value.type;
+ const std::string &lifetime) {
+ const Type &type = field.value.type;
switch (GetFullType(field.value.type)) {
case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
- ", " + typname + ">>";
+ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " +
+ typname + ">>";
}
case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
- ", flatbuffers::ForwardsUOffset<" + typname + \
- "<" + lifetime + ">>>>";
+ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", flatbuffers::ForwardsUOffset<" + typname + "<" + lifetime +
+ ">>>>";
}
case ftVectorOfInteger:
case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType());
- return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
- ", " + typname + ">>";
+ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " +
+ typname + ">>";
}
case ftVectorOfBool: {
- return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
", bool>>";
}
case ftVectorOfString: {
- return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
+ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>>";
}
case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def);
- return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
- ", " + typname + ">>";
+ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + ", " +
+ typname + ">>";
}
case ftVectorOfUnionValue: {
- const auto typname = WrapInNameSpace(*type.enum_def);
- return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime + \
- ", flatbuffers::ForwardsUOffset<flatbuffers::Table<" + \
- lifetime + ">>>";
+ return "flatbuffers::WIPOffset<flatbuffers::Vector<" + lifetime +
+ ", flatbuffers::ForwardsUOffset<flatbuffers::Table<" + lifetime +
+ ">>>";
}
case ftEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def);
@@ -918,16 +866,15 @@ class RustGenerator : public BaseGenerator {
return typname;
}
case ftUnionValue: {
- const auto typname = WrapInNameSpace(*type.enum_def);
return "flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>";
}
}
- return "INVALID_CODE_GENERATION"; // for return analysis
+ return "INVALID_CODE_GENERATION"; // for return analysis
}
std::string TableBuilderArgsAddFuncBody(const FieldDef &field) {
- const Type& type = field.value.type;
+ const Type &type = field.value.type;
switch (GetFullType(field.value.type)) {
case ftInteger:
@@ -951,8 +898,8 @@ class RustGenerator : public BaseGenerator {
}
case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<" + \
- typname + ">>";
+ return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<" +
+ typname + ">>";
}
case ftUnionValue:
@@ -968,12 +915,12 @@ class RustGenerator : public BaseGenerator {
return "self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>";
}
}
- return "INVALID_CODE_GENERATION"; // for return analysis
+ return "INVALID_CODE_GENERATION"; // for return analysis
}
std::string GenTableAccessorFuncReturnType(const FieldDef &field,
- const std::string lifetime) {
- const Type& type = field.value.type;
+ const std::string &lifetime) {
+ const Type &type = field.value.type;
switch (GetFullType(field.value.type)) {
case ftInteger:
@@ -986,11 +933,13 @@ class RustGenerator : public BaseGenerator {
}
case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return WrapInOptionIfNotRequired("&" + lifetime + " " + typname, field.required);
+ return WrapInOptionIfNotRequired("&" + lifetime + " " + typname,
+ field.required);
}
case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return WrapInOptionIfNotRequired(typname + "<" + lifetime + ">", field.required);
+ return WrapInOptionIfNotRequired(typname + "<" + lifetime + ">",
+ field.required);
}
case ftEnumKey:
case ftUnionKey: {
@@ -999,55 +948,68 @@ class RustGenerator : public BaseGenerator {
}
case ftUnionValue: {
- return WrapInOptionIfNotRequired("flatbuffers::Table<" + lifetime + ">", field.required);
+ return WrapInOptionIfNotRequired("flatbuffers::Table<" + lifetime + ">",
+ field.required);
}
case ftString: {
- return WrapInOptionIfNotRequired("&" + lifetime + " str", field.required);
+ return WrapInOptionIfNotRequired("&" + lifetime + " str",
+ field.required);
}
case ftVectorOfInteger:
case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType());
if (IsOneByte(type.VectorType().base_type)) {
- return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]", field.required);
+ return WrapInOptionIfNotRequired(
+ "&" + lifetime + " [" + typname + "]", field.required);
}
- return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", " + typname + ">", field.required);
+ return WrapInOptionIfNotRequired(
+ "flatbuffers::Vector<" + lifetime + ", " + typname + ">",
+ field.required);
}
case ftVectorOfBool: {
- return WrapInOptionIfNotRequired("&" + lifetime + " [bool]", field.required);
+ return WrapInOptionIfNotRequired("&" + lifetime + " [bool]",
+ field.required);
}
case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def);
- return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", " + typname + ">", field.required);
+ return WrapInOptionIfNotRequired(
+ "flatbuffers::Vector<" + lifetime + ", " + typname + ">",
+ field.required);
}
case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]", field.required);
+ return WrapInOptionIfNotRequired("&" + lifetime + " [" + typname + "]",
+ field.required);
}
case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", flatbuffers::ForwardsUOffset<" + \
- typname + "<" + lifetime + ">>>", field.required);
+ return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime +
+ ", flatbuffers::ForwardsUOffset<" +
+ typname + "<" + lifetime + ">>>",
+ field.required);
}
case ftVectorOfString: {
- return WrapInOptionIfNotRequired("flatbuffers::Vector<" + lifetime + ", flatbuffers::ForwardsUOffset<&" + \
- lifetime + " str>>", field.required);
+ return WrapInOptionIfNotRequired(
+ "flatbuffers::Vector<" + lifetime +
+ ", flatbuffers::ForwardsUOffset<&" + lifetime + " str>>",
+ field.required);
}
case ftVectorOfUnionValue: {
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
// TODO(rw): when we do support these, we should consider using the
// Into trait to convert tables to typesafe union values.
- return "INVALID_CODE_GENERATION"; // for return analysis
+ return "INVALID_CODE_GENERATION"; // for return analysis
}
}
- return "INVALID_CODE_GENERATION"; // for return analysis
+ return "INVALID_CODE_GENERATION"; // for return analysis
}
std::string GenTableAccessorFuncBody(const FieldDef &field,
- const std::string lifetime,
- const std::string offset_prefix) {
- const std::string offset_name = offset_prefix + "::" + \
- GetFieldOffsetName(field);
- const Type& type = field.value.type;
+ const std::string &lifetime,
+ const std::string &offset_prefix) {
+ const std::string offset_name =
+ offset_prefix + "::" + GetFieldOffsetName(field);
+ const Type &type = field.value.type;
switch (GetFullType(field.value.type)) {
case ftInteger:
@@ -1055,42 +1017,51 @@ class RustGenerator : public BaseGenerator {
case ftBool: {
const auto typname = GetTypeBasic(type);
const auto default_value = GetDefaultScalarValue(field);
- return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" + \
+ return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
default_value + ")).unwrap()";
}
case ftStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return AddUnwrapIfRequired("self._tab.get::<" + typname + ">(" + offset_name + ", None)", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<" + typname + ">(" + offset_name + ", None)",
+ field.required);
}
case ftTable: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<" + \
- typname + "<" + lifetime + ">>>(" + offset_name + ", None)", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<flatbuffers::ForwardsUOffset<" + typname + "<" +
+ lifetime + ">>>(" + offset_name + ", None)",
+ field.required);
}
case ftUnionValue: {
- return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
- "flatbuffers::Table<" + lifetime + ">>>(" + offset_name + \
- ", None)", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<flatbuffers::ForwardsUOffset<"
+ "flatbuffers::Table<" +
+ lifetime + ">>>(" + offset_name + ", None)",
+ field.required);
}
case ftUnionKey:
case ftEnumKey: {
- const auto underlying_typname = GetTypeBasic(type);
+ const auto underlying_typname = GetTypeBasic(type); //<- never used
const auto typname = WrapInNameSpace(*type.enum_def);
const auto default_value = GetDefaultScalarValue(field);
- return "self._tab.get::<" + typname + ">(" + offset_name + \
- ", Some(" + default_value + ")).unwrap()";
+ return "self._tab.get::<" + typname + ">(" + offset_name + ", Some(" +
+ default_value + ")).unwrap()";
}
case ftString: {
- return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(" + \
- offset_name + ", None)", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<flatbuffers::ForwardsUOffset<&str>>(" +
+ offset_name + ", None)",
+ field.required);
}
case ftVectorOfInteger:
case ftVectorOfFloat: {
const auto typname = GetTypeBasic(type.VectorType());
- std::string s = "self._tab.get::<flatbuffers::ForwardsUOffset<"
- "flatbuffers::Vector<" + lifetime + ", " + typname + \
- ">>>(" + offset_name + ", None)";
+ std::string s =
+ "self._tab.get::<flatbuffers::ForwardsUOffset<"
+ "flatbuffers::Vector<" +
+ lifetime + ", " + typname + ">>>(" + offset_name + ", None)";
// single-byte values are safe to slice
if (IsOneByte(type.VectorType().base_type)) {
s += ".map(|v| v.safe_slice())";
@@ -1098,53 +1069,74 @@ class RustGenerator : public BaseGenerator {
return AddUnwrapIfRequired(s, field.required);
}
case ftVectorOfBool: {
- return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
- "flatbuffers::Vector<" + lifetime + ", bool>>>(" + \
- offset_name + ", None).map(|v| v.safe_slice())", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<flatbuffers::ForwardsUOffset<"
+ "flatbuffers::Vector<" +
+ lifetime + ", bool>>>(" + offset_name +
+ ", None).map(|v| v.safe_slice())",
+ field.required);
}
case ftVectorOfEnumKey: {
const auto typname = WrapInNameSpace(*type.enum_def);
- return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
- "flatbuffers::Vector<" + lifetime + ", " + typname + ">>>(" + \
- offset_name + ", None)", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<flatbuffers::ForwardsUOffset<"
+ "flatbuffers::Vector<" +
+ lifetime + ", " + typname + ">>>(" + offset_name + ", None)",
+ field.required);
}
case ftVectorOfStruct: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
- "flatbuffers::Vector<" + typname + ">>>(" + \
- offset_name + ", None).map(|v| v.safe_slice() )", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<flatbuffers::ForwardsUOffset<"
+ "flatbuffers::Vector<" +
+ typname + ">>>(" + offset_name +
+ ", None).map(|v| v.safe_slice() )",
+ field.required);
}
case ftVectorOfTable: {
const auto typname = WrapInNameSpace(*type.struct_def);
- return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
- "flatbuffers::Vector<flatbuffers::ForwardsUOffset<" + typname + \
- "<" + lifetime + ">>>>>(" + offset_name + ", None)", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<flatbuffers::ForwardsUOffset<"
+ "flatbuffers::Vector<flatbuffers::ForwardsUOffset<" +
+ typname + "<" + lifetime + ">>>>>(" + offset_name + ", None)",
+ field.required);
}
case ftVectorOfString: {
- return AddUnwrapIfRequired("self._tab.get::<flatbuffers::ForwardsUOffset<"
- "flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" + \
- lifetime + " str>>>>(" + offset_name + ", None)", field.required);
+ return AddUnwrapIfRequired(
+ "self._tab.get::<flatbuffers::ForwardsUOffset<"
+ "flatbuffers::Vector<flatbuffers::ForwardsUOffset<&" +
+ lifetime + " str>>>>(" + offset_name + ", None)",
+ field.required);
}
case ftVectorOfUnionValue: {
FLATBUFFERS_ASSERT(false && "vectors of unions are not yet supported");
- return "INVALID_CODE_GENERATION"; // for return analysis
+ return "INVALID_CODE_GENERATION"; // for return analysis
}
}
- return "INVALID_CODE_GENERATION"; // for return analysis
+ return "INVALID_CODE_GENERATION"; // for return analysis
}
- bool TableFieldReturnsOption(const Type& type) {
+ bool TableFieldReturnsOption(const Type &type) {
switch (GetFullType(type)) {
case ftInteger:
case ftFloat:
case ftBool:
case ftEnumKey:
- case ftUnionKey:
- return false;
+ case ftUnionKey: return false;
default: return true;
}
}
+ // Generates a fully-qualified name getter for use with --gen-name-strings
+ void GenFullyQualifiedNameGetter(const StructDef &struct_def,
+ const std::string &name) {
+ code_ += " pub const fn get_fully_qualified_name() -> &'static str {";
+ code_ += " \"" +
+ struct_def.defined_namespace->GetFullyQualifiedName(name) + "\"";
+ code_ += " }";
+ code_ += "";
+ }
+
// Generate an accessor struct, builder struct, and create function for a
// table.
void GenTable(const StructDef &struct_def) {
@@ -1175,9 +1167,15 @@ class RustGenerator : public BaseGenerator {
code_ += "}";
code_ += "";
code_ += "impl<'a> {{STRUCT_NAME}}<'a> {";
+
+ if (parser_.opts.generate_name_strings) {
+ GenFullyQualifiedNameGetter(struct_def, struct_def.name);
+ }
+
code_ += " #[inline]";
- code_ += " pub fn init_from_table(table: flatbuffers::Table<'a>) -> "
- "Self {";
+ code_ +=
+ " pub fn init_from_table(table: flatbuffers::Table<'a>) -> "
+ "Self {";
code_ += " {{STRUCT_NAME}} {";
code_ += " _tab: table,";
code_ += " }";
@@ -1185,16 +1183,17 @@ class RustGenerator : public BaseGenerator {
// Generate a convenient create* function that uses the above builder
// to create a table in one function call.
- code_.SetValue("MAYBE_US",
- struct_def.fields.vec.size() == 0 ? "_" : "");
+ code_.SetValue("MAYBE_US", struct_def.fields.vec.size() == 0 ? "_" : "");
code_.SetValue("MAYBE_LT",
- TableBuilderArgsNeedsLifetime(struct_def) ? "<'args>" : "");
+ TableBuilderArgsNeedsLifetime(struct_def) ? "<'args>" : "");
code_ += " #[allow(unused_mut)]";
code_ += " pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(";
- code_ += " _fbb: "
- "&'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,";
- code_ += " {{MAYBE_US}}args: &'args {{STRUCT_NAME}}Args{{MAYBE_LT}})"
- " -> flatbuffers::WIPOffset<{{STRUCT_NAME}}<'bldr>> {";
+ code_ +=
+ " _fbb: "
+ "&'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,";
+ code_ +=
+ " {{MAYBE_US}}args: &'args {{STRUCT_NAME}}Args{{MAYBE_LT}})"
+ " -> flatbuffers::WIPOffset<{{STRUCT_NAME}}<'bldr>> {";
code_ += " let mut builder = {{STRUCT_NAME}}Builder::new(_fbb);";
for (size_t size = struct_def.sortbysize ? sizeof(largest_scalar_t) : 1;
@@ -1207,8 +1206,9 @@ class RustGenerator : public BaseGenerator {
size == SizeOf(field.value.type.base_type))) {
code_.SetValue("FIELD_NAME", Name(field));
if (TableFieldReturnsOption(field.value.type)) {
- code_ += " if let Some(x) = args.{{FIELD_NAME}} "
- "{ builder.add_{{FIELD_NAME}}(x); }";
+ code_ +=
+ " if let Some(x) = args.{{FIELD_NAME}} "
+ "{ builder.add_{{FIELD_NAME}}(x); }";
} else {
code_ += " builder.add_{{FIELD_NAME}}(args.{{FIELD_NAME}});";
}
@@ -1231,8 +1231,9 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field));
code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
- code_ += " pub const {{OFFSET_NAME}}: flatbuffers::VOffsetT = "
- "{{OFFSET_VALUE}};";
+ code_ +=
+ " pub const {{OFFSET_NAME}}: flatbuffers::VOffsetT = "
+ "{{OFFSET_VALUE}};";
}
code_ += "";
}
@@ -1270,9 +1271,7 @@ class RustGenerator : public BaseGenerator {
code_ += " }";
// Generate a comparison function for this field if it is a key.
- if (field.key) {
- GenKeyFieldMethods(field);
- }
+ if (field.key) { GenKeyFieldMethods(field); }
// Generate a nested flatbuffer field, if applicable.
auto nested = field.attributes.Lookup("nested_flatbuffer");
@@ -1289,14 +1288,16 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("OFFSET_NAME",
offset_prefix + "::" + GetFieldOffsetName(field));
- code_ += " pub fn {{FIELD_NAME}}_nested_flatbuffer(&'a self) -> "
- " Option<{{STRUCT_NAME}}<'a>> {";
+ code_ +=
+ " pub fn {{FIELD_NAME}}_nested_flatbuffer(&'a self) -> "
+ " Option<{{STRUCT_NAME}}<'a>> {";
code_ += " match self.{{FIELD_NAME}}() {";
code_ += " None => { None }";
code_ += " Some(data) => {";
code_ += " use self::flatbuffers::Follow;";
- code_ += " Some(<flatbuffers::ForwardsUOffset"
- "<{{STRUCT_NAME}}<'a>>>::follow(data, 0))";
+ code_ +=
+ " Some(<flatbuffers::ForwardsUOffset"
+ "<{{STRUCT_NAME}}<'a>>>::follow(data, 0))";
code_ += " },";
code_ += " }";
code_ += " }";
@@ -1314,27 +1315,44 @@ class RustGenerator : public BaseGenerator {
auto u = field.value.type.enum_def;
code_.SetValue("FIELD_NAME", Name(field));
+ code_.SetValue("FIELD_TYPE_FIELD_NAME", field.name);
for (auto u_it = u->Vals().begin(); u_it != u->Vals().end(); ++u_it) {
auto &ev = **u_it;
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
- auto table_init_type = WrapInNameSpace(
- ev.union_type.struct_def->defined_namespace,
- ev.union_type.struct_def->name);
+ auto table_init_type =
+ WrapInNameSpace(ev.union_type.struct_def->defined_namespace,
+ ev.union_type.struct_def->name);
- code_.SetValue("U_ELEMENT_ENUM_TYPE",
- WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev)));
+ code_.SetValue(
+ "U_ELEMENT_ENUM_TYPE",
+ WrapInNameSpace(u->defined_namespace, GetEnumValUse(*u, ev)));
code_.SetValue("U_ELEMENT_TABLE_TYPE", table_init_type);
code_.SetValue("U_ELEMENT_NAME", MakeSnakeCase(Name(ev)));
code_ += " #[inline]";
code_ += " #[allow(non_snake_case)]";
- code_ += " pub fn {{FIELD_NAME}}_as_{{U_ELEMENT_NAME}}(&self) -> "
- "Option<{{U_ELEMENT_TABLE_TYPE}}<'a>> {";
- code_ += " if self.{{FIELD_NAME}}_type() == {{U_ELEMENT_ENUM_TYPE}} {";
- code_ += " self.{{FIELD_NAME}}().map(|u| "
- "{{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))";
+ code_ +=
+ " pub fn {{FIELD_NAME}}_as_{{U_ELEMENT_NAME}}(&self) -> "
+ "Option<{{U_ELEMENT_TABLE_TYPE}}<'a>> {";
+ // If the user defined schemas name a field that clashes with a
+ // language reserved word, flatc will try to escape the field name by
+ // appending an underscore. This works well for most cases, except
+ // one. When generating union accessors (and referring to them
+ // internally within the code generated here), an extra underscore
+ // will be appended to the name, causing build failures.
+ //
+ // This only happens when unions have members that overlap with
+ // language reserved words.
+ //
+ // To avoid this problem the type field name is used unescaped here:
+ code_ +=
+ " if self.{{FIELD_TYPE_FIELD_NAME}}_type() == "
+ "{{U_ELEMENT_ENUM_TYPE}} {";
+ code_ +=
+ " self.{{FIELD_NAME}}().map(|u| "
+ "{{U_ELEMENT_TABLE_TYPE}}::init_from_table(u))";
code_ += " } else {";
code_ += " None";
code_ += " }";
@@ -1348,7 +1366,7 @@ class RustGenerator : public BaseGenerator {
// Generate an args struct:
code_.SetValue("MAYBE_LT",
- TableBuilderArgsNeedsLifetime(struct_def) ? "<'a>" : "");
+ TableBuilderArgsNeedsLifetime(struct_def) ? "<'a>" : "");
code_ += "pub struct {{STRUCT_NAME}}Args{{MAYBE_LT}} {";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
@@ -1367,7 +1385,7 @@ class RustGenerator : public BaseGenerator {
code_ += " fn default() -> Self {";
code_ += " {{STRUCT_NAME}}Args {";
for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
+ it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
if (!field.deprecated) {
code_.SetValue("PARAM_VALUE", TableBuilderArgsDefaultValue(field));
@@ -1383,8 +1401,9 @@ class RustGenerator : public BaseGenerator {
// Generate a builder struct:
code_ += "pub struct {{STRUCT_NAME}}Builder<'a: 'b, 'b> {";
code_ += " fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,";
- code_ += " start_: flatbuffers::WIPOffset<"
- "flatbuffers::TableUnfinishedWIPOffset>,";
+ code_ +=
+ " start_: flatbuffers::WIPOffset<"
+ "flatbuffers::TableUnfinishedWIPOffset>,";
code_ += "}";
// Generate builder functions:
@@ -1396,8 +1415,6 @@ class RustGenerator : public BaseGenerator {
const bool is_scalar = IsScalar(field.value.type.base_type);
std::string offset = GetFieldOffsetName(field);
- std::string name = Name(field);
- std::string value = GetDefaultScalarValue(field);
// Generate functions to add data, which take one of two forms.
//
@@ -1415,13 +1432,15 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("FIELD_TYPE", TableBuilderArgsAddFuncType(field, "'b "));
code_.SetValue("FUNC_BODY", TableBuilderArgsAddFuncBody(field));
code_ += " #[inline]";
- code_ += " pub fn add_{{FIELD_NAME}}(&mut self, {{FIELD_NAME}}: "
- "{{FIELD_TYPE}}) {";
+ code_ +=
+ " pub fn add_{{FIELD_NAME}}(&mut self, {{FIELD_NAME}}: "
+ "{{FIELD_TYPE}}) {";
if (is_scalar) {
code_.SetValue("FIELD_DEFAULT_VALUE",
TableBuilderAddFuncDefaultValue(field));
- code_ += " {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}}, "
- "{{FIELD_DEFAULT_VALUE}});";
+ code_ +=
+ " {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}}, "
+ "{{FIELD_DEFAULT_VALUE}});";
} else {
code_ += " {{FUNC_BODY}}({{FIELD_OFFSET}}, {{FIELD_NAME}});";
}
@@ -1444,8 +1463,9 @@ class RustGenerator : public BaseGenerator {
// finish() function.
code_ += " #[inline]";
- code_ += " pub fn finish(self) -> "
- "flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>> {";
+ code_ +=
+ " pub fn finish(self) -> "
+ "flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>> {";
code_ += " let o = self.fbb_.end_table(self.start_);";
for (auto it = struct_def.fields.vec.begin();
@@ -1454,8 +1474,9 @@ class RustGenerator : public BaseGenerator {
if (!field.deprecated && field.required) {
code_.SetValue("FIELD_NAME", MakeSnakeCase(Name(field)));
code_.SetValue("OFFSET_NAME", GetFieldOffsetName(field));
- code_ += " self.fbb_.required(o, {{STRUCT_NAME}}::{{OFFSET_NAME}},"
- "\"{{FIELD_NAME}}\");";
+ code_ +=
+ " self.fbb_.required(o, {{STRUCT_NAME}}::{{OFFSET_NAME}},"
+ "\"{{FIELD_NAME}}\");";
}
}
code_ += " flatbuffers::WIPOffset::new(o.value())";
@@ -1472,14 +1493,16 @@ class RustGenerator : public BaseGenerator {
code_.SetValue("KEY_TYPE", GenTableAccessorFuncReturnType(field, ""));
code_ += " #[inline]";
- code_ += " pub fn key_compare_less_than(&self, o: &{{STRUCT_NAME}}) -> "
- " bool {";
+ code_ +=
+ " pub fn key_compare_less_than(&self, o: &{{STRUCT_NAME}}) -> "
+ " bool {";
code_ += " self.{{FIELD_NAME}}() < o.{{FIELD_NAME}}()";
code_ += " }";
code_ += "";
code_ += " #[inline]";
- code_ += " pub fn key_compare_with_value(&self, val: {{KEY_TYPE}}) -> "
- " ::std::cmp::Ordering {";
+ code_ +=
+ " pub fn key_compare_with_value(&self, val: {{KEY_TYPE}}) -> "
+ " ::std::cmp::Ordering {";
code_ += " let key = self.{{FIELD_NAME}}();";
code_ += " key.cmp(&val)";
code_ += " }";
@@ -1505,10 +1528,12 @@ class RustGenerator : public BaseGenerator {
code_ += "";
code_ += "#[inline]";
- code_ += "pub fn get_size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}"
- "<'a>(buf: &'a [u8]) -> {{STRUCT_NAME}}<'a> {";
- code_ += " flatbuffers::get_size_prefixed_root::<{{STRUCT_NAME}}<'a>>"
- "(buf)";
+ code_ +=
+ "pub fn get_size_prefixed_root_as_{{STRUCT_NAME_SNAKECASE}}"
+ "<'a>(buf: &'a [u8]) -> {{STRUCT_NAME}}<'a> {";
+ code_ +=
+ " flatbuffers::get_size_prefixed_root::<{{STRUCT_NAME}}<'a>>"
+ "(buf)";
code_ += "}";
code_ += "";
@@ -1556,13 +1581,15 @@ class RustGenerator : public BaseGenerator {
code_ += "}";
code_ += "";
code_ += "#[inline]";
- code_ += "pub fn finish_size_prefixed_{{STRUCT_NAME_SNAKECASE}}_buffer"
- "<'a, 'b>("
- "fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, "
- "root: flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>>) {";
+ code_ +=
+ "pub fn finish_size_prefixed_{{STRUCT_NAME_SNAKECASE}}_buffer"
+ "<'a, 'b>("
+ "fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, "
+ "root: flatbuffers::WIPOffset<{{STRUCT_NAME}}<'a>>) {";
if (parser_.file_identifier_.length()) {
- code_ += " fbb.finish_size_prefixed(root, "
- "Some({{STRUCT_NAME_CAPS}}_IDENTIFIER));";
+ code_ +=
+ " fbb.finish_size_prefixed(root, "
+ "Some({{STRUCT_NAME_CAPS}}_IDENTIFIER));";
} else {
code_ += " fbb.finish_size_prefixed(root, None);";
}
@@ -1583,8 +1610,8 @@ class RustGenerator : public BaseGenerator {
}
static void PaddingDefinition(int bits, std::string *code_ptr, int *id) {
- *code_ptr += " padding" + NumToString((*id)++) + "__: u" + \
- NumToString(bits) + ",";
+ *code_ptr +=
+ " padding" + NumToString((*id)++) + "__: u" + NumToString(bits) + ",";
}
static void PaddingInitializer(int bits, std::string *code_ptr, int *id) {
@@ -1650,8 +1677,9 @@ class RustGenerator : public BaseGenerator {
code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
code_ += " let src = unsafe {";
- code_ += " ::std::slice::from_raw_parts("
- "self as *const {{STRUCT_NAME}} as *const u8, Self::size())";
+ code_ +=
+ " ::std::slice::from_raw_parts("
+ "self as *const {{STRUCT_NAME}} as *const u8, Self::size())";
code_ += " };";
code_ += " dst.copy_from_slice(src);";
code_ += " }";
@@ -1662,8 +1690,9 @@ class RustGenerator : public BaseGenerator {
code_ += " #[inline]";
code_ += " fn push(&self, dst: &mut [u8], _rest: &[u8]) {";
code_ += " let src = unsafe {";
- code_ += " ::std::slice::from_raw_parts("
- "*self as *const {{STRUCT_NAME}} as *const u8, Self::size())";
+ code_ +=
+ " ::std::slice::from_raw_parts("
+ "*self as *const {{STRUCT_NAME}} as *const u8, Self::size())";
code_ += " };";
code_ += " dst.copy_from_slice(src);";
code_ += " }";
@@ -1680,14 +1709,12 @@ class RustGenerator : public BaseGenerator {
it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it;
const auto member_name = Name(field) + "_";
- const auto reference = StructMemberAccessNeedsCopy(field.value.type)
- ? "" : "&'a ";
+ const auto reference =
+ StructMemberAccessNeedsCopy(field.value.type) ? "" : "&'a ";
const auto arg_name = "_" + Name(field);
const auto arg_type = reference + GetTypeGet(field.value.type);
- if (it != struct_def.fields.vec.begin()) {
- arg_list += ", ";
- }
+ if (it != struct_def.fields.vec.begin()) { arg_list += ", "; }
arg_list += arg_name + ": ";
arg_list += arg_type;
init_list += " " + member_name;
@@ -1716,6 +1743,10 @@ class RustGenerator : public BaseGenerator {
code_ += " }";
code_ += " }";
+ if (parser_.opts.generate_name_strings) {
+ GenFullyQualifiedNameGetter(struct_def, struct_def.name);
+ }
+
// Generate accessor methods for the struct.
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
@@ -1723,8 +1754,9 @@ class RustGenerator : public BaseGenerator {
auto field_type = TableBuilderArgsAddFuncType(field, "'a");
auto member = "self." + Name(field) + "_";
- auto value = StructMemberAccessNeedsCopy(field.value.type) ?
- member + ".from_little_endian()" : member;
+ auto value = StructMemberAccessNeedsCopy(field.value.type)
+ ? member + ".from_little_endian()"
+ : member;
code_.SetValue("FIELD_NAME", Name(field));
code_.SetValue("FIELD_TYPE", field_type);
@@ -1737,22 +1769,28 @@ class RustGenerator : public BaseGenerator {
code_ += " }";
// Generate a comparison function for this field if it is a key.
- if (field.key) {
- GenKeyFieldMethods(field);
- }
+ if (field.key) { GenKeyFieldMethods(field); }
}
code_ += "}";
code_ += "";
}
void GenNamespaceImports(const int white_spaces) {
- std::string indent = std::string(white_spaces, ' ');
- code_ += "";
- code_ += indent + "use std::mem;";
- code_ += indent + "use std::cmp::Ordering;";
- code_ += "";
- code_ += indent + "extern crate flatbuffers;";
- code_ += indent + "use self::flatbuffers::EndianScalar;";
+ std::string indent = std::string(white_spaces, ' ');
+ code_ += "";
+ for (auto it = parser_.included_files_.begin();
+ it != parser_.included_files_.end(); ++it) {
+ if (it->second.empty()) continue;
+ auto noext = flatbuffers::StripExtension(it->second);
+ auto basename = flatbuffers::StripPath(noext);
+
+ code_ += indent + "use crate::" + basename + "_generated::*;";
+ }
+ code_ += indent + "use std::mem;";
+ code_ += indent + "use std::cmp::Ordering;";
+ code_ += "";
+ code_ += indent + "extern crate flatbuffers;";
+ code_ += indent + "use self::flatbuffers::EndianScalar;";
}
// Set up the correct namespace. This opens a namespace if the current
@@ -1811,7 +1849,9 @@ std::string RustMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) {
std::string filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
- std::string make_rule = GeneratedFileName(path, filebase) + ": ";
+ rust::RustGenerator generator(parser, path, file_name);
+ std::string make_rule =
+ generator.GeneratedFileName(path, filebase, parser.opts) + ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) {
@@ -1829,3 +1869,10 @@ std::string RustMakeRule(const Parser &parser, const std::string &path,
// TODO(rw): Generated code should generate endian-safe Debug impls.
// TODO(rw): Generated code could use a Rust-only enum type to access unions,
// instead of making the user use _type() to manually switch.
+// TODO(maxburke): There should be test schemas added that use language
+// keywords as fields of structs, tables, unions, enums, to make sure
+// that internal code generated references escaped names correctly.
+// TODO(maxburke): We should see if there is a more flexible way of resolving
+// module paths for use declarations. Right now if schemas refer to
+// other flatbuffer files, the include paths in emitted Rust bindings
+// are crate-relative which may undesirable.
diff --git a/src/idl_gen_swift.cpp b/src/idl_gen_swift.cpp
new file mode 100644
index 00000000..055d9ddc
--- /dev/null
+++ b/src/idl_gen_swift.cpp
@@ -0,0 +1,902 @@
+/*
+ * Copyright 2020 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unordered_set>
+
+#include "flatbuffers/code_generators.h"
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/util.h"
+
+namespace flatbuffers {
+
+namespace swift {
+
+inline std::string GenIndirect(const std::string &reading) {
+ return "{{ACCESS}}.indirect(" + reading + ")";
+}
+
+inline std::string GenArrayMainBody(const std::string &optional) {
+ return "\tpublic func {{VALUENAME}}(at index: Int32) -> {{VALUETYPE}}" +
+ optional + " { ";
+}
+
+inline char LowerCase(char c) {
+ return static_cast<char>(::tolower(static_cast<unsigned char>(c)));
+}
+
+class SwiftGenerator : public BaseGenerator {
+ private:
+ const Namespace *cur_name_space_;
+ CodeWriter code_;
+ std::unordered_set<std::string> keywords_;
+ std::set<std::string> namespaces_;
+ int namespace_depth;
+
+ public:
+ SwiftGenerator(const Parser &parser, const std::string &path,
+ const std::string &file_name)
+ : BaseGenerator(parser, path, file_name, "", ".", "swift"),
+ cur_name_space_(nullptr) {
+ namespace_depth = 0;
+ static const char *const keywords[] = {
+ "associatedtype",
+ "class",
+ "deinit",
+ "enum",
+ "extension",
+ "fileprivate",
+ "func",
+ "import",
+ "init",
+ "inout",
+ "internal",
+ "let",
+ "open",
+ "operator",
+ "private",
+ "protocol",
+ "public",
+ "rethrows",
+ "static",
+ "struct",
+ "subscript",
+ "typealias",
+ "var",
+ "break",
+ "case",
+ "continue",
+ "default",
+ "defer",
+ "do",
+ "else",
+ "fallthrough",
+ "for",
+ "guard",
+ "if",
+ "in",
+ "repeat",
+ "return",
+ "switch",
+ "where",
+ "while",
+ "Any",
+ "catch",
+ "false",
+ "is",
+ "nil",
+ "super",
+ "self",
+ "Self",
+ "throw",
+ "throws",
+ "true",
+ "try",
+ "associativity",
+ "convenience",
+ "dynamic",
+ "didSet",
+ "final",
+ "get",
+ "infix",
+ "indirect",
+ "lazy",
+ "left",
+ "mutating",
+ "none",
+ "nonmutating",
+ "optional",
+ "override",
+ "postfix",
+ "precedence",
+ "prefix",
+ "Protocol",
+ "required",
+ "right",
+ "set",
+ "Type",
+ "unowned",
+ "weak",
+ "willSet",
+ nullptr,
+ };
+ for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
+ }
+
+ bool generate() {
+ code_.Clear();
+ code_.SetValue("ACCESS", "_accessor");
+ code_ += "// " + std::string(FlatBuffersGeneratedWarning()) + "\n";
+ code_ += "import FlatBuffers\n";
+ // Generate code for all the enum declarations.
+
+ for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
+ ++it) {
+ const auto &enum_def = **it;
+ if (!enum_def.generated) {
+ SetNameSpace(enum_def.defined_namespace);
+ GenEnum(enum_def);
+ }
+ }
+
+ for (auto it = parser_.structs_.vec.begin();
+ it != parser_.structs_.vec.end(); ++it) {
+ const auto &struct_def = **it;
+ if (struct_def.fixed && !struct_def.generated) {
+ SetNameSpace(struct_def.defined_namespace);
+ GenStructReader(struct_def);
+ }
+ }
+
+ for (auto it = parser_.structs_.vec.begin();
+ it != parser_.structs_.vec.end(); ++it) {
+ const auto &struct_def = **it;
+ if (struct_def.fixed && !struct_def.generated) {
+ SetNameSpace(struct_def.defined_namespace);
+ GenStructWriter(struct_def);
+ }
+ }
+
+ for (auto it = parser_.structs_.vec.begin();
+ it != parser_.structs_.vec.end(); ++it) {
+ const auto &struct_def = **it;
+ if (!struct_def.fixed && !struct_def.generated) {
+ SetNameSpace(struct_def.defined_namespace);
+ GenTable(struct_def);
+ }
+ }
+
+ if (cur_name_space_) SetNameSpace(nullptr);
+
+ const auto filename = GeneratedFileName(path_, file_name_, parser_.opts);
+ const auto final_code = code_.ToString();
+ return SaveFile(filename.c_str(), final_code, false);
+ }
+
+ void mark(const std::string &str) {
+ code_.SetValue("MARKVALUE", str);
+ code_ += "\n// MARK: - {{MARKVALUE}}\n";
+ }
+
+ // Generates the create function for swift
+ void GenStructWriter(const StructDef &struct_def) {
+ code_.SetValue("STRUCTNAME", Name(struct_def));
+ std::string static_type = this->namespace_depth == 0 ? "" : "static ";
+ code_ += "public " + static_type + "func create{{STRUCTNAME}}(\\";
+ std::string func_header = "";
+ GenerateStructArgs(struct_def, &func_header, "");
+ code_ += func_header.substr(0, func_header.size() - 2) + "\\";
+ code_ += ") -> UnsafeMutableRawPointer {";
+ code_ +=
+ "\tlet memory = UnsafeMutableRawPointer.allocate(byteCount: "
+ "{{STRUCTNAME}}.size, alignment: {{STRUCTNAME}}.alignment)";
+ code_ +=
+ "\tmemory.initializeMemory(as: UInt8.self, repeating: 0, count: "
+ "{{STRUCTNAME}}.size)";
+ GenerateStructBody(struct_def, "");
+ code_ += "\treturn memory";
+ code_ += "}\n";
+ }
+
+ void GenerateStructBody(const StructDef &struct_def,
+ const std::string &nameprefix, int offset = 0) {
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ auto name = nameprefix + Name(field);
+ const auto &field_type = field.value.type;
+ auto type = GenTypeBasic(field_type, false);
+ if (IsStruct(field.value.type)) {
+ GenerateStructBody(*field_type.struct_def, (nameprefix + field.name),
+ static_cast<int>(field.value.offset));
+ } else {
+ auto off = NumToString(offset + field.value.offset);
+ code_ += "\tmemory.storeBytes(of: " + name +
+ (field_type.enum_def ? ".rawValue" : "") +
+ ", toByteOffset: " + off + ", as: " + type + ".self)";
+ }
+ }
+ }
+
+ void GenerateStructArgs(const StructDef &struct_def, std::string *code_ptr,
+ const std::string &nameprefix) {
+ auto &code = *code_ptr;
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ const auto &field_type = field.value.type;
+ if (IsStruct(field.value.type)) {
+ GenerateStructArgs(*field_type.struct_def, code_ptr,
+ (nameprefix + field.name));
+ } else {
+ auto name = Name(field);
+ auto type = GenType(field.value.type);
+ code += nameprefix + name + ": " + type;
+ code += ", ";
+ }
+ }
+ }
+
+ void GenObjectHeader(const StructDef &struct_def) {
+ GenComment(struct_def.doc_comment);
+ code_.SetValue("STRUCTNAME", Name(struct_def));
+ code_.SetValue("PROTOCOL",
+ struct_def.fixed ? "Readable" : "FlatBufferObject");
+ code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table");
+ code_ += "public struct {{STRUCTNAME}}: {{PROTOCOL}} {\n";
+ code_ += ValidateFunc();
+ code_ += "\tpublic var __buffer: ByteBuffer! { return {{ACCESS}}.bb }";
+ code_ += "\n\tprivate var {{ACCESS}}: {{OBJECTTYPE}}";
+ if (struct_def.fixed) {
+ code_.SetValue("BYTESIZE", NumToString(struct_def.bytesize));
+ code_.SetValue("MINALIGN", NumToString(struct_def.minalign));
+ code_ += "\tpublic static var size = {{BYTESIZE}}";
+ code_ += "\tpublic static var alignment = {{MINALIGN}}\t";
+ } else {
+ if (parser_.file_identifier_.length()) {
+ code_.SetValue("FILENAME", parser_.file_identifier_);
+ code_ +=
+ "\tpublic static func finish(_ fbb: FlatBufferBuilder, end: "
+ "Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, "
+ "fileId: "
+ "\"{{FILENAME}}\", addPrefix: prefix) }";
+ }
+ code_ +=
+ "\tpublic static func getRootAs{{STRUCTNAME}}(bb: ByteBuffer) -> "
+ "{{STRUCTNAME}} { return {{STRUCTNAME}}(Table(bb: bb, position: "
+ "Int32(bb.read(def: UOffset.self, position: bb.reader)) + "
+ "Int32(bb.reader))) }\n";
+ code_ += "\tprivate init(_ t: Table) { {{ACCESS}} = t }";
+ }
+ code_ +=
+ "\tpublic init(_ bb: ByteBuffer, o: Int32) { {{ACCESS}} = "
+ "{{OBJECTTYPE}}(bb: "
+ "bb, position: o) }";
+ code_ += "";
+ }
+
+ // Generates the reader for swift
+ void GenTable(const StructDef &struct_def) {
+ GenObjectHeader(struct_def);
+ GenTableReader(struct_def);
+ GenTableWriter(struct_def);
+ code_ += "}\n";
+ }
+
+ void GenTableReader(const StructDef &struct_def) {
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ GenTableReaderFields(field);
+ }
+ }
+
+ void GenTableWriter(const StructDef &struct_def) {
+ flatbuffers::FieldDef *key_field = nullptr;
+ std::vector<std::string> require_fields;
+ std::string create_func_body;
+ std::string create_func_header;
+ auto should_generate_create = struct_def.fields.vec.size() != 0;
+
+ code_.SetValue("NUMBEROFFIELDS", NumToString(struct_def.fields.vec.size()));
+ code_ +=
+ "\tpublic static func start{{STRUCTNAME}}(_ fbb: FlatBufferBuilder) -> "
+ "UOffset { fbb.startTable(with: {{NUMBEROFFIELDS}}) }";
+
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ if (field.key) key_field = &field;
+ if (field.required)
+ require_fields.push_back(NumToString(field.value.offset));
+
+ GenTableWriterFields(
+ field, &create_func_body, &create_func_header,
+ static_cast<int>(it - struct_def.fields.vec.begin()));
+ }
+ code_ +=
+ "\tpublic static func end{{STRUCTNAME}}(_ fbb: FlatBufferBuilder, "
+ "start: "
+ "UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: "
+ "fbb.endTable(at: start))\\";
+ if (require_fields.capacity() != 0) {
+ std::string fields = "";
+ for (auto it = require_fields.begin(); it != require_fields.end(); ++it)
+ fields += *it + ", ";
+ code_.SetValue("FIELDS", fields.substr(0, fields.size() - 2));
+ code_ += "; fbb.require(table: end, fields: [{{FIELDS}}])\\";
+ }
+ code_ += "; return end }";
+
+ code_ +=
+ "\tpublic static func create{{STRUCTNAME}}(_ fbb: FlatBufferBuilder\\";
+ if (should_generate_create)
+ code_ += ",\n" +
+ create_func_header.substr(0, create_func_header.size() - 2) +
+ "\\";
+ code_ += ") -> Offset<UOffset> {";
+ code_ += "\t\tlet __start = {{STRUCTNAME}}.start{{STRUCTNAME}}(fbb)";
+ if (should_generate_create)
+ code_ += create_func_body.substr(0, create_func_body.size() - 1);
+ code_ += "\t\treturn {{STRUCTNAME}}.end{{STRUCTNAME}}(fbb, start: __start)";
+ code_ += "\t}";
+
+ std::string spacing = "\t\t";
+
+ if (key_field != nullptr && !struct_def.fixed && struct_def.has_key) {
+ code_.SetValue("VALUENAME", struct_def.name);
+ code_.SetValue("VOFFSET", NumToString(key_field->value.offset));
+
+ code_ +=
+ "\tpublic static func "
+ "sortVectorOf{{VALUENAME}}(offsets:[Offset<UOffset>], "
+ "_ fbb: FlatBufferBuilder) -> Offset<UOffset> {";
+ code_ += spacing + "var off = offsets";
+ code_ +=
+ spacing +
+ "off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: "
+ "{{VOFFSET}}, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: "
+ "{{VOFFSET}}, fbb: fbb.buffer), fbb: fbb.buffer) < 0 } ";
+ code_ += spacing + "return fbb.createVector(ofOffsets: off)";
+ code_ += "\t}";
+ GenLookup(*key_field);
+ }
+ }
+
+ void GenTableWriterFields(const FieldDef &field, std::string *create_body,
+ std::string *create_header, const int position) {
+ std::string builder_string = ", _ fbb: FlatBufferBuilder) { fbb.add(";
+ auto &create_func_body = *create_body;
+ auto &create_func_header = *create_header;
+ auto name = Name(field);
+ auto type = GenType(field.value.type);
+ code_.SetValue("VALUENAME", name);
+ code_.SetValue("VALUETYPE", type);
+ code_.SetValue("OFFSET", NumToString(position));
+ code_.SetValue("CONSTANT", field.value.constant);
+ std::string check_if_vector =
+ (field.value.type.base_type == BASE_TYPE_VECTOR ||
+ field.value.type.base_type == BASE_TYPE_ARRAY)
+ ? "VectorOf("
+ : "(";
+ std::string body = "add" + check_if_vector + name + ": ";
+ code_ += "\tpublic static func " + body + "\\";
+
+ create_func_body += "\t\t{{STRUCTNAME}}." + body + name + ", fbb)\n";
+
+ if (IsScalar(field.value.type.base_type) &&
+ !IsBool(field.value.type.base_type)) {
+ auto default_value = IsEnum(field.value.type) ? GenEnumDefaultValue(field)
+ : field.value.constant;
+ auto is_enum = IsEnum(field.value.type) ? ".rawValue" : "";
+ code_ += "{{VALUETYPE}}" + builder_string + "element: {{VALUENAME}}" +
+ is_enum + ", def: {{CONSTANT}}, at: {{OFFSET}}) }";
+ create_func_header +=
+ "\t\t" + name + ": " + type + " = " + default_value + ",\n";
+ return;
+ }
+
+ if (IsBool(field.value.type.base_type)) {
+ std::string default_value =
+ "0" == field.value.constant ? "false" : "true";
+ code_.SetValue("VALUETYPE", "Bool");
+ code_.SetValue("CONSTANT", default_value);
+ code_ += "{{VALUETYPE}}" + builder_string +
+ "condition: {{VALUENAME}}, def: {{CONSTANT}}, at: {{OFFSET}}) }";
+ create_func_header +=
+ "\t\t" + name + ": " + type + " = " + default_value + ",\n";
+ return;
+ }
+
+ auto offset_type = field.value.type.base_type == BASE_TYPE_STRING
+ ? "Offset<String>"
+ : "Offset<UOffset>";
+ auto camel_case_name =
+ (field.value.type.base_type == BASE_TYPE_VECTOR ||
+ field.value.type.base_type == BASE_TYPE_ARRAY
+ ? "vectorOf"
+ : "offsetOf") +
+ MakeCamel(name, true);
+ create_func_header += "\t\t" + camel_case_name + " " + name + ": " +
+ offset_type + " = Offset(),\n";
+ auto reader_type =
+ IsStruct(field.value.type) && field.value.type.struct_def->fixed
+ ? "structOffset: {{OFFSET}}) }"
+ : "offset: {{VALUENAME}}, at: {{OFFSET}}) }";
+ code_ += offset_type + builder_string + reader_type;
+ }
+
+ void GenTableReaderFields(const FieldDef &field) {
+ auto offset = NumToString(field.value.offset);
+ auto name = Name(field);
+ auto type = GenType(field.value.type);
+ code_.SetValue("VALUENAME", name);
+ code_.SetValue("VALUETYPE", type);
+ code_.SetValue("OFFSET", offset);
+ code_.SetValue("CONSTANT", field.value.constant);
+ std::string const_string = "return o == 0 ? {{CONSTANT}} : ";
+ GenComment(field.doc_comment, "\t");
+ if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type) &&
+ !IsBool(field.value.type.base_type)) {
+ code_ += GenReaderMainBody() + GenOffset() + const_string +
+ GenReader("VALUETYPE", "o") + " }";
+ if (parser_.opts.mutable_buffer) code_ += GenMutate("o", GenOffset());
+ return;
+ }
+
+ if (IsBool(field.value.type.base_type)) {
+ code_.SetValue("VALUETYPE", "Bool");
+ code_ += GenReaderMainBody() + "\\";
+ code_.SetValue("VALUETYPE", "Byte");
+ code_ += GenOffset() +
+ "return o == 0 ? false : 0 != " + GenReader("VALUETYPE", "o") +
+ " }";
+ if (parser_.opts.mutable_buffer) code_ += GenMutate("o", GenOffset());
+ return;
+ }
+
+ if (IsEnum(field.value.type)) {
+ auto default_value = GenEnumDefaultValue(field);
+ code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false));
+ code_ += GenReaderMainBody() + "\\";
+ code_ += GenOffset() + "return o == 0 ? " + default_value + " : " +
+ GenEnumConstructor("o") + "?? " + default_value + " }";
+ if (parser_.opts.mutable_buffer && !IsUnion(field.value.type))
+ code_ += GenMutate("o", GenOffset(), true);
+ return;
+ }
+
+ if (IsStruct(field.value.type) && field.value.type.struct_def->fixed) {
+ code_.SetValue("VALUETYPE", GenType(field.value.type));
+ code_.SetValue("CONSTANT", "nil");
+ code_ += GenReaderMainBody("?") + GenOffset() + const_string +
+ GenConstructor("o + {{ACCESS}}.postion");
+ return;
+ }
+ switch (field.value.type.base_type) {
+ case BASE_TYPE_STRUCT:
+ code_.SetValue("VALUETYPE", GenType(field.value.type));
+ code_.SetValue("CONSTANT", "nil");
+ code_ += GenReaderMainBody("?") + GenOffset() + const_string +
+ GenConstructor(GenIndirect("o + {{ACCESS}}.postion"));
+ break;
+
+ case BASE_TYPE_STRING:
+ code_.SetValue("VALUETYPE", GenType(field.value.type));
+ code_.SetValue("CONSTANT", "nil");
+ code_ += GenReaderMainBody("?") + GenOffset() + const_string +
+ "{{ACCESS}}.string(at: o) }";
+ code_ +=
+ "\tpublic var {{VALUENAME}}SegmentArray: [UInt8]? { return "
+ "{{ACCESS}}.getVector(at: {{OFFSET}}) }";
+ break;
+
+ case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
+ case BASE_TYPE_VECTOR:
+ GenTableReaderVectorFields(field, const_string);
+ break;
+ case BASE_TYPE_UNION:
+ code_.SetValue("CONSTANT", "nil");
+ code_ +=
+ "\tpublic func {{VALUENAME}}<T: FlatBufferObject>(type: "
+ "T.Type) -> T? { " +
+ GenOffset() + const_string + "{{ACCESS}}.union(o) }";
+ break;
+ default: FLATBUFFERS_ASSERT(0);
+ }
+ }
+
+ void GenTableReaderVectorFields(const FieldDef &field,
+ const std::string &const_string) {
+ auto vectortype = field.value.type.VectorType();
+ code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));
+ code_ += "\tpublic var {{VALUENAME}}Count: Int32 { " + GenOffset() +
+ const_string + "{{ACCESS}}.vector(count: o) }";
+ code_.SetValue("CONSTANT", IsScalar(vectortype.base_type) == true
+ ? field.value.constant
+ : "nil");
+ auto nullable = IsScalar(vectortype.base_type) == true ? "" : "?";
+ nullable = IsEnum(vectortype) == true ? "?" : nullable;
+ if (vectortype.base_type != BASE_TYPE_UNION) {
+ code_ += GenArrayMainBody(nullable) + GenOffset() + "\\";
+ } else {
+ code_ +=
+ "\tpublic func {{VALUENAME}}<T: FlatBufferObject>(at index: "
+ "Int32, type: T.Type) -> T? { " +
+ GenOffset() + "\\";
+ }
+
+ if (IsBool(vectortype.base_type)) {
+ code_.SetValue("CONSTANT", field.value.offset == 0 ? "false" : "true");
+ code_.SetValue("VALUETYPE", "Byte");
+ }
+ if (!IsEnum(vectortype))
+ code_ +=
+ const_string + (IsBool(vectortype.base_type) ? "0 != " : "") + "\\";
+
+ if (IsScalar(vectortype.base_type) && !IsEnum(vectortype) &&
+ !IsBool(field.value.type.base_type)) {
+ code_ +=
+ "{{ACCESS}}.directRead(of: {{VALUETYPE}}.self, offset: "
+ "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
+ code_ +=
+ "\tpublic var {{VALUENAME}}: [{{VALUETYPE}}] { return "
+ "{{ACCESS}}.getVector(at: {{OFFSET}}) ?? [] }";
+ if (parser_.opts.mutable_buffer) code_ += GenMutateArray();
+ return;
+ }
+ if (vectortype.base_type == BASE_TYPE_STRUCT &&
+ field.value.type.struct_def->fixed) {
+ code_ += GenConstructor("{{ACCESS}}.vector(at: o) + index * {{SIZE}}");
+ return;
+ }
+
+ if (vectortype.base_type == BASE_TYPE_STRING) {
+ code_ +=
+ "{{ACCESS}}.directString(at: {{ACCESS}}.vector(at: o) + "
+ "index * {{SIZE}}) }";
+ return;
+ }
+
+ if (IsEnum(vectortype)) {
+ code_.SetValue("BASEVALUE", GenTypeBasic(vectortype, false));
+ code_ += "return o == 0 ? {{VALUETYPE}}" + GenEnumDefaultValue(field) +
+ " : {{VALUETYPE}}(rawValue: {{ACCESS}}.directRead(of: "
+ "{{BASEVALUE}}.self, offset: {{ACCESS}}.vector(at: o) + "
+ "index * {{SIZE}})) }";
+ return;
+ }
+ if (vectortype.base_type == BASE_TYPE_UNION) {
+ code_ +=
+ "{{ACCESS}}.directUnion({{ACCESS}}.vector(at: o) + "
+ "index * {{SIZE}}) }";
+ return;
+ }
+
+ if (vectortype.base_type == BASE_TYPE_STRUCT &&
+ !field.value.type.struct_def->fixed) {
+ code_ += GenConstructor(
+ "{{ACCESS}}.indirect({{ACCESS}}.vector(at: o) + index * "
+ "{{SIZE}})");
+ auto &sd = *field.value.type.struct_def;
+ auto &fields = sd.fields.vec;
+ for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
+ auto &key_field = **kit;
+ if (key_field.key) {
+ GenByKeyFunctions(key_field);
+ break;
+ }
+ }
+ }
+ }
+
+ void GenByKeyFunctions(const FieldDef &key_field) {
+ code_.SetValue("TYPE", GenType(key_field.value.type));
+ code_ +=
+ "\tpublic func {{VALUENAME}}By(key: {{TYPE}}) -> {{VALUETYPE}}? { \\";
+ code_ += GenOffset() +
+ "return o == 0 ? nil : {{VALUETYPE}}.lookupByKey(vector: "
+ "{{ACCESS}}.vector(at: o), key: key, fbb: {{ACCESS}}.bb) }";
+ }
+
+ // Generates the reader for swift
+ void GenStructReader(const StructDef &struct_def) {
+ GenObjectHeader(struct_def);
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ auto &field = **it;
+ if (field.deprecated) continue;
+ auto offset = NumToString(field.value.offset);
+ auto name = Name(field);
+ auto type = GenType(field.value.type);
+ code_.SetValue("VALUENAME", name);
+ code_.SetValue("VALUETYPE", type);
+ code_.SetValue("OFFSET", offset);
+ GenComment(field.doc_comment, "\t");
+ if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type)) {
+ code_ +=
+ GenReaderMainBody() + "return " + GenReader("VALUETYPE") + " }";
+ if (parser_.opts.mutable_buffer) code_ += GenMutate("{{OFFSET}}", "");
+ } else if (IsEnum(field.value.type)) {
+ code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false));
+ code_ += GenReaderMainBody() + "return " +
+ GenEnumConstructor("{{OFFSET}}") + "?? " +
+ GenEnumDefaultValue(field) + " }";
+ } else if (IsStruct(field.value.type)) {
+ code_.SetValue("VALUETYPE", GenType(field.value.type));
+ code_ += GenReaderMainBody() + "return " +
+ GenConstructor("{{ACCESS}}.postion + {{OFFSET}}");
+ }
+ }
+
+ code_ += "}\n";
+ }
+
+ void GenEnum(const EnumDef &enum_def) {
+ if (enum_def.generated) return;
+ code_.SetValue("ENUM_NAME", Name(enum_def));
+ code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false));
+ GenComment(enum_def.doc_comment);
+ code_ += "public enum {{ENUM_NAME}}: {{BASE_TYPE}}, Enum { ";
+ code_ += "\tpublic typealias T = {{BASE_TYPE}}";
+ code_ +=
+ "\tpublic static var byteSize: Int { return "
+ "MemoryLayout<{{BASE_TYPE}}>.size "
+ "}";
+ code_ += "\tpublic var value: {{BASE_TYPE}} { return self.rawValue }";
+
+ for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
+ const auto &ev = **it;
+ auto name = Name(ev);
+ std::transform(name.begin(), name.end(), name.begin(), LowerCase);
+ code_.SetValue("KEY", name);
+ code_.SetValue("VALUE", enum_def.ToString(ev));
+ GenComment(ev.doc_comment, "\t");
+ code_ += "\tcase {{KEY}} = {{VALUE}}";
+ }
+ code_ += "\n";
+ AddMinOrMaxEnumValue(enum_def.MaxValue()->name, "max");
+ AddMinOrMaxEnumValue(enum_def.MinValue()->name, "min");
+ code_ += "}\n";
+ }
+
+ void AddMinOrMaxEnumValue(const std::string &str, const std::string &type) {
+ auto current_value = str;
+ std::transform(current_value.begin(), current_value.end(),
+ current_value.begin(), LowerCase);
+ code_.SetValue(type, current_value);
+ code_ += "\tpublic static var " + type + ": {{ENUM_NAME}} { return .{{" +
+ type + "}} }";
+ }
+
+ void GenLookup(const FieldDef &key_field) {
+ code_.SetValue("OFFSET", NumToString(key_field.value.offset));
+ auto offset_reader =
+ "Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: {{OFFSET}}, "
+ "fbb: fbb)";
+ std::string spacing = "\t\t";
+ std::string double_spacing = spacing + "\t";
+
+ code_.SetValue("TYPE", GenType(key_field.value.type));
+ code_ +=
+ "\tfileprivate static func lookupByKey(vector: Int32, key: {{TYPE}}, "
+ "fbb: "
+ "ByteBuffer) -> {{VALUENAME}}? {";
+
+ if (key_field.value.type.base_type == BASE_TYPE_STRING)
+ code_ += spacing + "let key = key.utf8.map { $0 }";
+ code_ += spacing +
+ "var span = fbb.read(def: Int32.self, position: Int(vector - 4))";
+ code_ += spacing + "var start: Int32 = 0";
+ code_ += spacing + "while span != 0 {";
+ code_ += double_spacing + "var middle = span / 2";
+ code_ +=
+ double_spacing +
+ "let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)";
+ if (key_field.value.type.base_type == BASE_TYPE_STRING) {
+ code_ += double_spacing + "let comp = Table.compare(" + offset_reader +
+ ", key, fbb: fbb)";
+ } else {
+ code_ += double_spacing +
+ "let comp = fbb.read(def: {{TYPE}}.self, position: Int(" +
+ offset_reader + "))";
+ }
+
+ code_ += double_spacing + "if comp > 0 {";
+ code_ += double_spacing + "\tspan = middle";
+ code_ += double_spacing + "} else if comp < 0 {";
+ code_ += double_spacing + "\tmiddle += 1";
+ code_ += double_spacing + "\tstart += middle";
+ code_ += double_spacing + "\tspan -= middle";
+ code_ += double_spacing + "} else {";
+ code_ += double_spacing + "\treturn {{VALUENAME}}(fbb, o: tableOffset)";
+ code_ += double_spacing + "}";
+ code_ += spacing + "}";
+ code_ += spacing + "return nil";
+ code_ += "\t}";
+ }
+
+ void GenComment(const std::vector<std::string> &dc, const char *prefix = "") {
+ std::string text;
+ ::flatbuffers::GenComment(dc, &text, nullptr, prefix);
+ code_ += text + "\\";
+ }
+
+ std::string GenOffset() { return "let o = {{ACCESS}}.offset({{OFFSET}}); "; }
+
+ std::string GenReaderMainBody(const std::string &optional = "") {
+ return "\tpublic var {{VALUENAME}}: {{VALUETYPE}}" + optional + " { ";
+ }
+
+ std::string GenReader(const std::string &type,
+ const std::string &at = "{{OFFSET}}") {
+ return "{{ACCESS}}.readBuffer(of: {{" + type + "}}.self, at: " + at + ")";
+ }
+
+ std::string GenConstructor(const std::string &offset) {
+ return "{{VALUETYPE}}({{ACCESS}}.bb, o: " + offset + ") }";
+ }
+
+ std::string GenMutate(const std::string &offset,
+ const std::string &get_offset, bool isRaw = false) {
+ return "\tpublic func mutate({{VALUENAME}}: {{VALUETYPE}}) -> Bool {" +
+ get_offset + " return {{ACCESS}}.mutate({{VALUENAME}}" +
+ (isRaw ? ".rawValue" : "") + ", index: " + offset + ") }";
+ }
+
+ std::string GenMutateArray() {
+ return "\tpublic func mutate({{VALUENAME}}: {{VALUETYPE}}, at index: "
+ "Int32) -> Bool { " +
+ GenOffset() +
+ "return {{ACCESS}}.directMutate({{VALUENAME}}, index: "
+ "{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
+ }
+
+ std::string GenEnumDefaultValue(const FieldDef &field) {
+ auto &value = field.value;
+ FLATBUFFERS_ASSERT(value.type.enum_def);
+ auto &enum_def = *value.type.enum_def;
+ auto enum_val = enum_def.FindByValue(value.constant);
+ std::string name;
+ if (enum_val) {
+ name = enum_val->name;
+ } else {
+ const auto &ev = **enum_def.Vals().begin();
+ name = ev.name;
+ }
+ std::transform(name.begin(), name.end(), name.begin(), LowerCase);
+ return "." + name;
+ }
+
+ std::string GenEnumConstructor(const std::string &at) {
+ return "{{VALUETYPE}}(rawValue: " + GenReader("BASEVALUE", at) + ") ";
+ }
+
+ std::string ValidateFunc() {
+ return "\tstatic func validateVersion() { FlatBuffersVersion_1_12_0() }";
+ }
+
+ std::string GenType(const Type &type) const {
+ return IsScalar(type.base_type)
+ ? GenTypeBasic(type)
+ : (IsArray(type) ? GenType(type.VectorType())
+ : GenTypePointer(type));
+ }
+
+ std::string GenTypePointer(const Type &type) const {
+ switch (type.base_type) {
+ case BASE_TYPE_STRING: return "String";
+ case BASE_TYPE_VECTOR: return GenType(type.VectorType());
+ case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
+ case BASE_TYPE_UNION:
+ default: return "FlatBufferObject";
+ }
+ }
+
+ std::string GenTypeBasic(const Type &type) const {
+ return GenTypeBasic(type, true);
+ }
+
+ std::string GenTypeBasic(const Type &type, bool can_override) const {
+ // clang-format off
+ static const char * const swift_type[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
+ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE, STYPE) \
+ #STYPE,
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ };
+ // clang-format on
+ if (can_override) {
+ if (type.enum_def)
+ return WrapInNameSpace(type.enum_def->defined_namespace,
+ Name(*type.enum_def));
+ if (type.base_type == BASE_TYPE_BOOL) return "Bool";
+ }
+ return swift_type[static_cast<int>(type.base_type)];
+ }
+
+ std::string EscapeKeyword(const std::string &name) const {
+ return keywords_.find(name) == keywords_.end() ? name : name + "_";
+ }
+
+ std::string Name(const EnumVal &ev) const { return EscapeKeyword(ev.name); }
+
+ std::string Name(const Definition &def) const {
+ return EscapeKeyword(MakeCamel(def.name, false));
+ }
+
+ // MARK: - Copied from the cpp implementation, needs revisiting
+ void SetNameSpace(const Namespace *ns) {
+ if (cur_name_space_ == ns) { return; }
+ // Compute the size of the longest common namespace prefix.
+ // If cur_name_space is A::B::C::D and ns is A::B::E::F::G,
+ // the common prefix is A::B:: and we have old_size = 4, new_size = 5
+ // and common_prefix_size = 2
+ size_t old_size = cur_name_space_ ? cur_name_space_->components.size() : 0;
+ size_t new_size = ns ? ns->components.size() : 0;
+
+ size_t common_prefix_size = 0;
+ while (common_prefix_size < old_size && common_prefix_size < new_size &&
+ ns->components[common_prefix_size] ==
+ cur_name_space_->components[common_prefix_size]) {
+ common_prefix_size++;
+ }
+
+ // Close cur_name_space in reverse order to reach the common prefix.
+ // In the previous example, D then C are closed.
+ for (size_t j = old_size; j > common_prefix_size; --j) {
+ if (namespace_depth != 0) {
+ code_ += "}";
+ namespace_depth -= 1;
+ }
+ mark(cur_name_space_->components[j - 1]);
+ }
+ if (old_size != common_prefix_size) { code_ += ""; }
+
+ // open namespace parts to reach the ns namespace
+ // in the previous example, E, then F, then G are opened
+ bool is_extension = false;
+ for (auto j = common_prefix_size; j < new_size; ++j) {
+ std::string name = ns->components[j];
+ if (namespaces_.find(name) == namespaces_.end()) {
+ code_ += "public enum " + name + " {";
+ namespace_depth += 1;
+ namespaces_.insert(name);
+ } else {
+ code_ += "}";
+ is_extension = true;
+ }
+ }
+ if (is_extension) {
+ code_.SetValue("EXTENSION", FullNamespace(".", *ns));
+ code_ += "extension {{EXTENSION}} {";
+ }
+ if (new_size != common_prefix_size) { code_ += ""; }
+ cur_name_space_ = ns;
+ }
+};
+} // namespace swift
+bool GenerateSwift(const Parser &parser, const std::string &path,
+ const std::string &file_name) {
+ swift::SwiftGenerator generator(parser, path, file_name);
+ return generator.generate();
+}
+} // namespace flatbuffers
diff --git a/src/idl_gen_text.cpp b/src/idl_gen_text.cpp
index 4c61ff99..e4d21824 100644
--- a/src/idl_gen_text.cpp
+++ b/src/idl_gen_text.cpp
@@ -23,242 +23,337 @@
namespace flatbuffers {
-static bool GenStruct(const StructDef &struct_def, const Table *table,
- int indent, const IDLOptions &opts, std::string *_text);
+struct PrintScalarTag {};
+struct PrintPointerTag {};
+template<typename T> struct PrintTag { typedef PrintScalarTag type; };
+template<> struct PrintTag<const void *> { typedef PrintPointerTag type; };
-// If indentation is less than 0, that indicates we don't want any newlines
-// either.
-const char *NewLine(const IDLOptions &opts) {
- return opts.indent_step >= 0 ? "\n" : "";
-}
+struct JsonPrinter {
+ // If indentation is less than 0, that indicates we don't want any newlines
+ // either.
+ void AddNewLine() {
+ if (opts.indent_step >= 0) text += '\n';
+ }
-int Indent(const IDLOptions &opts) { return std::max(opts.indent_step, 0); }
+ void AddIndent(int ident) { text.append(ident, ' '); }
-// Output an identifier with or without quotes depending on strictness.
-void OutputIdentifier(const std::string &name, const IDLOptions &opts,
- std::string *_text) {
- std::string &text = *_text;
- if (opts.strict_json) text += "\"";
- text += name;
- if (opts.strict_json) text += "\"";
-}
+ int Indent() const { return std::max(opts.indent_step, 0); }
-// Print (and its template specialization below for pointers) generate text
-// for a single FlatBuffer value into JSON format.
-// The general case for scalars:
-template<typename T>
-bool Print(T val, Type type, int /*indent*/, Type * /*union_type*/,
- const IDLOptions &opts, std::string *_text) {
- std::string &text = *_text;
- if (type.enum_def && opts.output_enum_identifiers) {
- auto enum_val = type.enum_def->ReverseLookup(static_cast<int64_t>(val));
- if (enum_val) {
- text += "\"";
- text += enum_val->name;
- text += "\"";
- return true;
- }
+ // Output an identifier with or without quotes depending on strictness.
+ void OutputIdentifier(const std::string &name) {
+ if (opts.strict_json) text += '\"';
+ text += name;
+ if (opts.strict_json) text += '\"';
}
- if (type.base_type == BASE_TYPE_BOOL) {
- text += val != 0 ? "true" : "false";
- } else {
+ // Print (and its template specialization below for pointers) generate text
+ // for a single FlatBuffer value into JSON format.
+ // The general case for scalars:
+ template<typename T>
+ bool PrintScalar(T val, const Type &type, int /*indent*/) {
+ if (IsBool(type.base_type)) {
+ text += val != 0 ? "true" : "false";
+ return true; // done
+ }
+
+ if (opts.output_enum_identifiers && type.enum_def) {
+ const auto &enum_def = *type.enum_def;
+ if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
+ text += '\"';
+ text += ev->name;
+ text += '\"';
+ return true; // done
+ } else if (val && enum_def.attributes.Lookup("bit_flags")) {
+ const auto entry_len = text.length();
+ const auto u64 = static_cast<uint64_t>(val);
+ uint64_t mask = 0;
+ text += '\"';
+ for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
+ it != e; ++it) {
+ auto f = (*it)->GetAsUInt64();
+ if (f & u64) {
+ mask |= f;
+ text += (*it)->name;
+ text += ' ';
+ }
+ }
+ // Don't slice if (u64 != mask)
+ if (mask && (u64 == mask)) {
+ text[text.length() - 1] = '\"';
+ return true; // done
+ }
+ text.resize(entry_len); // restore
+ }
+ // print as numeric value
+ }
+
text += NumToString(val);
+ return true;
}
- return true;
-}
+ void AddComma() {
+ if (!opts.protobuf_ascii_alike) text += ',';
+ }
-// Print a vector a sequence of JSON values, comma separated, wrapped in "[]".
-template<typename T>
-bool PrintVector(const Vector<T> &v, Type type, int indent,
- const IDLOptions &opts, std::string *_text) {
- std::string &text = *_text;
- text += "[";
- text += NewLine(opts);
- for (uoffset_t i = 0; i < v.size(); i++) {
- if (i) {
- if (!opts.protobuf_ascii_alike) text += ",";
- text += NewLine(opts);
+ // Print a vector or an array of JSON values, comma seperated, wrapped in
+ // "[]".
+ template<typename Container>
+ bool PrintContainer(PrintScalarTag, const Container &c, size_t size,
+ const Type &type, int indent, const uint8_t *) {
+ const auto elem_indent = indent + Indent();
+ text += '[';
+ AddNewLine();
+ for (uoffset_t i = 0; i < size; i++) {
+ if (i) {
+ AddComma();
+ AddNewLine();
+ }
+ AddIndent(elem_indent);
+ if (!PrintScalar(c[i], type, elem_indent)) { return false; }
}
- text.append(indent + Indent(opts), ' ');
- if (IsStruct(type)) {
- if (!Print(v.GetStructFromOffset(i * type.struct_def->bytesize), type,
- indent + Indent(opts), nullptr, opts, _text)) {
- return false;
+ AddNewLine();
+ AddIndent(indent);
+ text += ']';
+ return true;
+ }
+
+ // Print a vector or an array of JSON values, comma seperated, wrapped in
+ // "[]".
+ template<typename Container>
+ bool PrintContainer(PrintPointerTag, const Container &c, size_t size,
+ const Type &type, int indent, const uint8_t *prev_val) {
+ const auto is_struct = IsStruct(type);
+ const auto elem_indent = indent + Indent();
+ text += '[';
+ AddNewLine();
+ for (uoffset_t i = 0; i < size; i++) {
+ if (i) {
+ AddComma();
+ AddNewLine();
}
- } else {
- if (!Print(v[i], type, indent + Indent(opts), nullptr, opts, _text)) {
+ AddIndent(elem_indent);
+ auto ptr = is_struct ? reinterpret_cast<const void *>(
+ c.Data() + type.struct_def->bytesize * i)
+ : c[i];
+ if (!PrintOffset(ptr, type, elem_indent, prev_val,
+ static_cast<soffset_t>(i))) {
return false;
}
}
+ AddNewLine();
+ AddIndent(indent);
+ text += ']';
+ return true;
}
- text += NewLine(opts);
- text.append(indent, ' ');
- text += "]";
- return true;
-}
-// Specialization of Print above for pointer types.
-template<>
-bool Print<const void *>(const void *val, Type type, int indent,
- Type *union_type, const IDLOptions &opts,
- std::string *_text) {
- switch (type.base_type) {
- case BASE_TYPE_UNION:
- // If this assert hits, you have an corrupt buffer, a union type field
- // was not present or was out of range.
- FLATBUFFERS_ASSERT(union_type);
- return Print<const void *>(val, *union_type, indent, nullptr, opts,
- _text);
- case BASE_TYPE_STRUCT:
- if (!GenStruct(*type.struct_def, reinterpret_cast<const Table *>(val),
- indent, opts, _text)) {
- return false;
+ template<typename T>
+ bool PrintVector(const void *val, const Type &type, int indent,
+ const uint8_t *prev_val) {
+ typedef Vector<T> Container;
+ typedef typename PrintTag<typename Container::return_type>::type tag;
+ auto &vec = *reinterpret_cast<const Container *>(val);
+ return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
+ prev_val);
+ }
+
+ // Print an array a sequence of JSON values, comma separated, wrapped in "[]".
+ template<typename T>
+ bool PrintArray(const void *val, size_t size, const Type &type, int indent) {
+ typedef Array<T, 0xFFFF> Container;
+ typedef typename PrintTag<typename Container::return_type>::type tag;
+ auto &arr = *reinterpret_cast<const Container *>(val);
+ return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr);
+ }
+
+ bool PrintOffset(const void *val, const Type &type, int indent,
+ const uint8_t *prev_val, soffset_t vector_index) {
+ switch (type.base_type) {
+ case BASE_TYPE_UNION: {
+ // If this assert hits, you have an corrupt buffer, a union type field
+ // was not present or was out of range.
+ FLATBUFFERS_ASSERT(prev_val);
+ auto union_type_byte = *prev_val; // Always a uint8_t.
+ if (vector_index >= 0) {
+ auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(
+ prev_val + ReadScalar<uoffset_t>(prev_val));
+ union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index));
+ }
+ auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true);
+ if (enum_val) {
+ return PrintOffset(val, enum_val->union_type, indent, nullptr, -1);
+ } else {
+ return false;
+ }
}
- break;
- case BASE_TYPE_STRING: {
- auto s = reinterpret_cast<const String *>(val);
- if (!EscapeString(s->c_str(), s->size(), _text, opts.allow_non_utf8,
- opts.natural_utf8)) {
- return false;
+ case BASE_TYPE_STRUCT:
+ return GenStruct(*type.struct_def, reinterpret_cast<const Table *>(val),
+ indent);
+ case BASE_TYPE_STRING: {
+ auto s = reinterpret_cast<const String *>(val);
+ return EscapeString(s->c_str(), s->size(), &text, opts.allow_non_utf8,
+ opts.natural_utf8);
}
- break;
- }
- case BASE_TYPE_VECTOR:
- type = type.VectorType();
- // Call PrintVector above specifically for each element type:
- switch (type.base_type) {
+ case BASE_TYPE_VECTOR: {
+ const auto vec_type = type.VectorType();
+ // Call PrintVector above specifically for each element type:
// clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ switch (vec_type.base_type) {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
case BASE_TYPE_ ## ENUM: \
if (!PrintVector<CTYPE>( \
- *reinterpret_cast<const Vector<CTYPE> *>(val), \
- type, indent, opts, _text)) { \
+ val, vec_type, indent, prev_val)) { \
return false; \
} \
break;
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
+ }
+ // clang-format on
+ return true;
+ }
+ case BASE_TYPE_ARRAY: {
+ const auto vec_type = type.VectorType();
+ // Call PrintArray above specifically for each element type:
+ // clang-format off
+ switch (vec_type.base_type) {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ case BASE_TYPE_ ## ENUM: \
+ if (!PrintArray<CTYPE>( \
+ val, type.fixed_length, vec_type, indent)) { \
+ return false; \
+ } \
+ break;
+ FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
+ // Arrays of scalars or structs are only possible.
+ FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0);
+ }
// clang-format on
+ return true;
}
- break;
- default: FLATBUFFERS_ASSERT(0);
+ default: FLATBUFFERS_ASSERT(0); return false;
+ }
}
- return true;
-}
-
-template<typename T> static T GetFieldDefault(const FieldDef &fd) {
- T val;
- auto check = StringToNumber(fd.value.constant.c_str(), &val);
- (void)check;
- FLATBUFFERS_ASSERT(check);
- return val;
-}
-// Generate text for a scalar field.
-template<typename T>
-static bool GenField(const FieldDef &fd, const Table *table, bool fixed,
- const IDLOptions &opts, int indent, std::string *_text) {
- return Print(
- fixed ? reinterpret_cast<const Struct *>(table)->GetField<T>(
- fd.value.offset)
- : table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
- fd.value.type, indent, nullptr, opts, _text);
-}
+ template<typename T> static T GetFieldDefault(const FieldDef &fd) {
+ T val;
+ auto check = StringToNumber(fd.value.constant.c_str(), &val);
+ (void)check;
+ FLATBUFFERS_ASSERT(check);
+ return val;
+ }
-static bool GenStruct(const StructDef &struct_def, const Table *table,
- int indent, const IDLOptions &opts, std::string *_text);
+ // Generate text for a scalar field.
+ template<typename T>
+ bool GenField(const FieldDef &fd, const Table *table, bool fixed,
+ int indent) {
+ return PrintScalar(
+ fixed ? reinterpret_cast<const Struct *>(table)->GetField<T>(
+ fd.value.offset)
+ : table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
+ fd.value.type, indent);
+ }
-// Generate text for non-scalar field.
-static bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
- int indent, Type *union_type, const IDLOptions &opts,
- std::string *_text) {
- const void *val = nullptr;
- if (fixed) {
- // The only non-scalar fields in structs are structs.
- FLATBUFFERS_ASSERT(IsStruct(fd.value.type));
- val = reinterpret_cast<const Struct *>(table)->GetStruct<const void *>(
- fd.value.offset);
- } else if (fd.flexbuffer) {
- auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
- auto root = flexbuffers::GetRoot(vec->data(), vec->size());
- root.ToString(true, opts.strict_json, *_text);
- return true;
- } else if (fd.nested_flatbuffer) {
- auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
- auto root = GetRoot<Table>(vec->data());
- return GenStruct(*fd.nested_flatbuffer, root, indent, opts, _text);
- } else {
- val = IsStruct(fd.value.type)
- ? table->GetStruct<const void *>(fd.value.offset)
- : table->GetPointer<const void *>(fd.value.offset);
+ // Generate text for non-scalar field.
+ bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
+ int indent, const uint8_t *prev_val) {
+ const void *val = nullptr;
+ if (fixed) {
+ // The only non-scalar fields in structs are structs or arrays.
+ FLATBUFFERS_ASSERT(IsStruct(fd.value.type) || IsArray(fd.value.type));
+ val = reinterpret_cast<const Struct *>(table)->GetStruct<const void *>(
+ fd.value.offset);
+ } else if (fd.flexbuffer) {
+ auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
+ auto root = flexbuffers::GetRoot(vec->data(), vec->size());
+ root.ToString(true, opts.strict_json, text);
+ return true;
+ } else if (fd.nested_flatbuffer) {
+ auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
+ auto root = GetRoot<Table>(vec->data());
+ return GenStruct(*fd.nested_flatbuffer, root, indent);
+ } else {
+ val = IsStruct(fd.value.type)
+ ? table->GetStruct<const void *>(fd.value.offset)
+ : table->GetPointer<const void *>(fd.value.offset);
+ }
+ return PrintOffset(val, fd.value.type, indent, prev_val, -1);
}
- return Print(val, fd.value.type, indent, union_type, opts, _text);
-}
-// Generate text for a struct or table, values separated by commas, indented,
-// and bracketed by "{}"
-static bool GenStruct(const StructDef &struct_def, const Table *table,
- int indent, const IDLOptions &opts, std::string *_text) {
- std::string &text = *_text;
- text += "{";
- int fieldout = 0;
- Type *union_type = nullptr;
- for (auto it = struct_def.fields.vec.begin();
- it != struct_def.fields.vec.end(); ++it) {
- FieldDef &fd = **it;
- auto is_present = struct_def.fixed || table->CheckField(fd.value.offset);
- auto output_anyway = opts.output_default_scalars_in_json &&
- IsScalar(fd.value.type.base_type) && !fd.deprecated;
- if (is_present || output_anyway) {
- if (fieldout++) {
- if (!opts.protobuf_ascii_alike) text += ",";
- }
- text += NewLine(opts);
- text.append(indent + Indent(opts), ' ');
- OutputIdentifier(fd.name, opts, _text);
- if (!opts.protobuf_ascii_alike ||
- (fd.value.type.base_type != BASE_TYPE_STRUCT &&
- fd.value.type.base_type != BASE_TYPE_VECTOR))
- text += ":";
- text += " ";
- switch (fd.value.type.base_type) {
- // clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
- case BASE_TYPE_ ## ENUM: \
- if (!GenField<CTYPE>(fd, table, struct_def.fixed, \
- opts, indent + Indent(opts), _text)) { \
- return false; \
- } \
- break;
- FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
+ // Generate text for a struct or table, values separated by commas, indented,
+ // and bracketed by "{}"
+ bool GenStruct(const StructDef &struct_def, const Table *table, int indent) {
+ text += '{';
+ int fieldout = 0;
+ const uint8_t *prev_val = nullptr;
+ const auto elem_indent = indent + Indent();
+ for (auto it = struct_def.fields.vec.begin();
+ it != struct_def.fields.vec.end(); ++it) {
+ FieldDef &fd = **it;
+ auto is_present = struct_def.fixed || table->CheckField(fd.value.offset);
+ auto output_anyway = opts.output_default_scalars_in_json &&
+ IsScalar(fd.value.type.base_type) && !fd.deprecated;
+ if (is_present || output_anyway) {
+ if (fieldout++) { AddComma(); }
+ AddNewLine();
+ AddIndent(elem_indent);
+ OutputIdentifier(fd.name);
+ if (!opts.protobuf_ascii_alike ||
+ (fd.value.type.base_type != BASE_TYPE_STRUCT &&
+ fd.value.type.base_type != BASE_TYPE_VECTOR))
+ text += ':';
+ text += ' ';
+ // clang-format off
+ switch (fd.value.type.base_type) {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ case BASE_TYPE_ ## ENUM: \
+ if (!GenField<CTYPE>(fd, table, struct_def.fixed, elem_indent)) { \
+ return false; \
+ } \
+ break;
+ FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
// Generate drop-thru case statements for all pointer types:
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ #define FLATBUFFERS_TD(ENUM, ...) \
case BASE_TYPE_ ## ENUM:
- FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
+ FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
+ FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- if (!GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
- union_type, opts, _text)) {
- return false;
- }
+ if (!GenFieldOffset(fd, table, struct_def.fixed, elem_indent, prev_val)) {
+ return false;
+ }
break;
- // clang-format on
- }
- if (fd.value.type.base_type == BASE_TYPE_UTYPE) {
- auto enum_val = fd.value.type.enum_def->ReverseLookup(
- table->GetField<uint8_t>(fd.value.offset, 0));
- union_type = enum_val ? &enum_val->union_type : nullptr;
+ }
+ // clang-format on
+ // Track prev val for use with union types.
+ if (struct_def.fixed) {
+ prev_val = reinterpret_cast<const uint8_t *>(table) + fd.value.offset;
+ } else {
+ prev_val = table->GetAddressOf(fd.value.offset);
+ }
}
}
+ AddNewLine();
+ AddIndent(indent);
+ text += '}';
+ return true;
}
- text += NewLine(opts);
- text.append(indent, ' ');
- text += "}";
+
+ JsonPrinter(const Parser &parser, std::string &dest)
+ : opts(parser.opts), text(dest) {
+ text.reserve(1024); // Reduce amount of inevitable reallocs.
+ }
+
+ const IDLOptions &opts;
+ std::string &text;
+};
+
+static bool GenerateTextImpl(const Parser &parser, const Table *table,
+ const StructDef &struct_def, std::string *_text) {
+ JsonPrinter printer(parser, *_text);
+ if (!printer.GenStruct(struct_def, table, 0)) { return false; }
+ printer.AddNewLine();
return true;
}
@@ -266,41 +361,33 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
bool GenerateTextFromTable(const Parser &parser, const void *table,
const std::string &table_name, std::string *_text) {
auto struct_def = parser.LookupStruct(table_name);
- if (struct_def == nullptr) {
- return false;
- }
- auto text = *_text;
- text.reserve(1024); // Reduce amount of inevitable reallocs.
+ if (struct_def == nullptr) { return false; }
auto root = static_cast<const Table *>(table);
- if (!GenStruct(*struct_def, root, 0, parser.opts, _text)) {
- return false;
- }
- text += NewLine(parser.opts);
- return true;
+ return GenerateTextImpl(parser, root, *struct_def, _text);
}
// Generate a text representation of a flatbuffer in JSON format.
bool GenerateText(const Parser &parser, const void *flatbuffer,
std::string *_text) {
- std::string &text = *_text;
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
- text.reserve(1024); // Reduce amount of inevitable reallocs.
- auto root = parser.opts.size_prefixed ?
- GetSizePrefixedRoot<Table>(flatbuffer) : GetRoot<Table>(flatbuffer);
- if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) {
- return false;
- }
- text += NewLine(parser.opts);
- return true;
+ auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
+ : GetRoot<Table>(flatbuffer);
+ return GenerateTextImpl(parser, root, *parser.root_struct_def_, _text);
}
-std::string TextFileName(const std::string &path,
- const std::string &file_name) {
+static std::string TextFileName(const std::string &path,
+ const std::string &file_name) {
return path + file_name + ".json";
}
bool GenerateTextFile(const Parser &parser, const std::string &path,
const std::string &file_name) {
+ if (parser.opts.use_flexbuffers) {
+ std::string json;
+ parser.flex_root_.ToString(true, parser.opts.strict_json, json);
+ return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(),
+ json.c_str(), json.size(), true);
+ }
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true;
std::string text;
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) {
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index e26aa550..28ff3ec0 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -15,38 +15,44 @@
*/
#include <algorithm>
+#include <cmath>
#include <list>
#include <string>
-
-#include <math.h>
+#include <utility>
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
namespace flatbuffers {
+// Reflects the version at the compiling time of binary(lib/dll/so).
+const char *FLATBUFFERS_VERSION() {
+ // clang-format off
+ return
+ FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
+ FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
+ FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
+ // clang-format on
+}
+
const double kPi = 3.14159265358979323846;
-const char *const kTypeNames[] = {
// clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+const char *const kTypeNames[] = {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \
IDLTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- // clang-format on
nullptr
};
const char kTypeSizes[] = {
-// clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
- sizeof(CTYPE),
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ sizeof(CTYPE),
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- // clang-format on
};
+// clang-format on
// The enums in the reflection schema should match the ones we use internally.
// Compare the last element to check if these go out of sync.
@@ -91,8 +97,20 @@ std::string MakeCamel(const std::string &in, bool first) {
return s;
}
-void DeserializeDoc( std::vector<std::string> &doc,
- const Vector<Offset<String>> *documentation) {
+// Convert an underscore_based_identifier in to screaming snake case.
+std::string MakeScreamingCamel(const std::string &in) {
+ std::string s;
+ for (size_t i = 0; i < in.length(); i++) {
+ if (in[i] != '_')
+ s += static_cast<char>(toupper(in[i]));
+ else
+ s += in[i];
+ }
+ return s;
+}
+
+void DeserializeDoc(std::vector<std::string> &doc,
+ const Vector<Offset<String>> *documentation) {
if (documentation == nullptr) return;
for (uoffset_t index = 0; index < documentation->size(); index++)
doc.push_back(documentation->Get(index)->str());
@@ -200,8 +218,7 @@ static std::string TokenToString(int t) {
#define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) STRING,
FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN)
#undef FLATBUFFERS_TOKEN
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \
IDLTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
@@ -376,7 +393,8 @@ CheckedError Parser::Next() {
"illegal Unicode sequence (unpaired high surrogate)");
}
// reset if non-printable
- attr_is_trivial_ascii_string_ &= check_ascii_range(*cursor_, ' ', '~');
+ attr_is_trivial_ascii_string_ &=
+ check_ascii_range(*cursor_, ' ', '~');
attribute_ += *cursor_++;
}
@@ -414,7 +432,7 @@ CheckedError Parser::Next() {
cursor_ += 2;
break;
}
- FLATBUFFERS_FALLTHROUGH(); // else fall thru
+ FLATBUFFERS_FALLTHROUGH(); // else fall thru
default:
const auto has_sign = (c == '+') || (c == '-');
// '-'/'+' and following identifier - can be a predefined constant like:
@@ -428,14 +446,15 @@ CheckedError Parser::Next() {
return NoError();
}
- auto dot_lvl = (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen
- if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum?
+ auto dot_lvl =
+ (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen
+ if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum?
// Parser accepts hexadecimal-floating-literal (see C++ 5.13.4).
if (is_digit(c) || has_sign || !dot_lvl) {
const auto start = cursor_ - 1;
auto start_digits = !is_digit(c) ? cursor_ : cursor_ - 1;
- if (!is_digit(c) && is_digit(*cursor_)){
- start_digits = cursor_; // see digit in cursor_ position
+ if (!is_digit(c) && is_digit(*cursor_)) {
+ start_digits = cursor_; // see digit in cursor_ position
c = *cursor_++;
}
// hex-float can't begind with '.'
@@ -478,7 +497,8 @@ CheckedError Parser::Next() {
}
std::string ch;
ch = c;
- if (false == check_ascii_range(c, ' ', '~')) ch = "code: " + NumToString(c);
+ if (false == check_ascii_range(c, ' ', '~'))
+ ch = "code: " + NumToString(c);
return Error("illegal character: " + ch);
}
}
@@ -590,12 +610,29 @@ CheckedError Parser::ParseType(Type &type) {
NEXT();
Type subtype;
ECHECK(Recurse([&]() { return ParseType(subtype); }));
- if (subtype.base_type == BASE_TYPE_VECTOR) {
+ if (IsSeries(subtype)) {
// We could support this, but it will complicate things, and it's
// easier to work around with a struct around the inner vector.
- return Error("nested vector types not supported (wrap in table first).");
+ return Error("nested vector types not supported (wrap in table first)");
+ }
+ if (token_ == ':') {
+ NEXT();
+ if (token_ != kTokenIntegerConstant) {
+ return Error("length of fixed-length array must be an integer value");
+ }
+ uint16_t fixed_length = 0;
+ bool check = StringToNumber(attribute_.c_str(), &fixed_length);
+ if (!check || fixed_length < 1) {
+ return Error(
+ "length of fixed-length array must be positive and fit to "
+ "uint16_t type");
+ }
+ type = Type(BASE_TYPE_ARRAY, subtype.struct_def, subtype.enum_def,
+ fixed_length);
+ NEXT();
+ } else {
+ type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def);
}
- type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def);
type.element = subtype.base_type;
EXPECT(']');
} else {
@@ -631,7 +668,7 @@ CheckedError Parser::AddField(StructDef &struct_def, const std::string &name,
CheckedError Parser::ParseField(StructDef &struct_def) {
std::string name = attribute_;
- if (LookupStruct(name))
+ if (LookupCreateStruct(name, false, false))
return Error("field name can not be the same as table/struct name");
std::vector<std::string> dc = doc_comment_;
@@ -640,9 +677,19 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
Type type;
ECHECK(ParseType(type));
- if (struct_def.fixed && !IsScalar(type.base_type) && !IsStruct(type))
+ if (struct_def.fixed && !IsScalar(type.base_type) && !IsStruct(type) &&
+ !IsArray(type))
return Error("structs_ may contain only scalar or struct fields");
+ if (!struct_def.fixed && IsArray(type))
+ return Error("fixed-length array in table must be wrapped in struct");
+
+ if (IsArray(type) && !SupportsAdvancedArrayFeatures()) {
+ return Error(
+ "Arrays are not yet supported in all "
+ "the specified programming languages.");
+ }
+
FieldDef *typefield = nullptr;
if (type.base_type == BASE_TYPE_UNION) {
// For union fields, add a second auto-generated field to hold the type,
@@ -674,15 +721,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (!IsScalar(type.base_type) ||
(struct_def.fixed && field->value.constant != "0"))
return Error(
- "default values currently only supported for scalars in tables");
- }
- if (type.enum_def &&
- !type.enum_def->is_union &&
- !type.enum_def->attributes.Lookup("bit_flags") &&
- !type.enum_def->ReverseLookup(StringToInt(
- field->value.constant.c_str()))) {
- return Error("default value of " + field->value.constant + " for field " +
- name + " is not part of enum " + type.enum_def->name);
+ "default values currently only supported for scalars in tables");
}
// Append .0 if the value has not it (skip hex and scientific floats).
// This suffix needed for generated C++ code.
@@ -690,7 +729,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
auto &text = field->value.constant;
FLATBUFFERS_ASSERT(false == text.empty());
auto s = text.c_str();
- while(*s == ' ') s++;
+ while (*s == ' ') s++;
if (*s == '-' || *s == '+') s++;
// 1) A float constants (nan, inf, pi, etc) is a kind of identifier.
// 2) A float number needn't ".0" at the end if it has exponent.
@@ -699,21 +738,35 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
field->value.constant += ".0";
}
}
-
- if (type.enum_def && IsScalar(type.base_type) && !struct_def.fixed &&
- !type.enum_def->attributes.Lookup("bit_flags") &&
- !type.enum_def->ReverseLookup(StringToInt(
- field->value.constant.c_str())))
- Warning("enum " + type.enum_def->name +
- " does not have a declaration for this field\'s default of " +
- field->value.constant);
+ if (type.enum_def) {
+ // The type.base_type can only be scalar, union, array or vector.
+ // Table, struct or string can't have enum_def.
+ // Default value of union and vector in NONE, NULL translated to "0".
+ FLATBUFFERS_ASSERT(IsInteger(type.base_type) ||
+ (type.base_type == BASE_TYPE_UNION) ||
+ (type.base_type == BASE_TYPE_VECTOR) ||
+ (type.base_type == BASE_TYPE_ARRAY));
+ if (type.base_type == BASE_TYPE_VECTOR) {
+ // Vector can't use initialization list.
+ FLATBUFFERS_ASSERT(field->value.constant == "0");
+ } else {
+ // All unions should have the NONE ("0") enum value.
+ auto in_enum = type.enum_def->attributes.Lookup("bit_flags") ||
+ type.enum_def->FindByValue(field->value.constant);
+ if (false == in_enum)
+ return Error("default value of " + field->value.constant +
+ " for field " + name + " is not part of enum " +
+ type.enum_def->name);
+ }
+ }
field->doc_comment = dc;
ECHECK(ParseMetaData(&field->attributes));
field->deprecated = field->attributes.Lookup("deprecated") != nullptr;
auto hash_name = field->attributes.Lookup("hash");
if (hash_name) {
- switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element : type.base_type) {
+ switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element
+ : type.base_type) {
case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: {
if (FindHashFunction16(hash_name->constant.c_str()) == nullptr)
@@ -737,7 +790,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
}
default:
return Error(
- "only short, ushort, int, uint, long and ulong data types support hashing.");
+ "only short, ushort, int, uint, long and ulong data types support "
+ "hashing.");
}
}
auto cpp_type = field->attributes.Lookup("cpp_type");
@@ -756,8 +810,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (field->deprecated && struct_def.fixed)
return Error("can't deprecate fields in a struct");
field->required = field->attributes.Lookup("required") != nullptr;
- if (field->required &&
- (struct_def.fixed || IsScalar(type.base_type)))
+ if (field->required && (struct_def.fixed || IsScalar(type.base_type)))
return Error("only non-scalar fields in tables may be 'required'");
field->key = field->attributes.Lookup("key") != nullptr;
if (field->key) {
@@ -794,19 +847,13 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
"nested_flatbuffer attribute may only apply to a vector of ubyte");
// This will cause an error if the root type of the nested flatbuffer
// wasn't defined elsewhere.
- LookupCreateStruct(nested->constant);
-
- // Keep a pointer to StructDef in FieldDef to simplify re-use later
- auto nested_qualified_name =
- current_namespace_->GetFullyQualifiedName(nested->constant);
- field->nested_flatbuffer = LookupStruct(nested_qualified_name);
+ field->nested_flatbuffer = LookupCreateStruct(nested->constant);
}
if (field->attributes.Lookup("flexbuffer")) {
field->flexbuffer = true;
uses_flexbuffers_ = true;
- if (type.base_type != BASE_TYPE_VECTOR ||
- type.element != BASE_TYPE_UCHAR)
+ if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR)
return Error("flexbuffer attribute may only apply to a vector of ubyte");
}
@@ -846,8 +893,7 @@ CheckedError Parser::ParseComma() {
CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
size_t parent_fieldn,
const StructDef *parent_struct_def,
- uoffset_t count,
- bool inside_vector) {
+ uoffset_t count, bool inside_vector) {
switch (val.type.base_type) {
case BASE_TYPE_UNION: {
FLATBUFFERS_ASSERT(field);
@@ -865,8 +911,8 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
uoffset_t offset;
ECHECK(atot(elem->first.constant.c_str(), *this, &offset));
vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>(
- builder_.GetCurrentBufferPointer() +
- builder_.GetSize() - offset);
+ builder_.GetCurrentBufferPointer() + builder_.GetSize() -
+ offset);
break;
}
} else {
@@ -908,8 +954,7 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
}
}
if (constant.empty() && !vector_of_union_types) {
- return Error("missing type field for this union value: " +
- field->name);
+ return Error("missing type field for this union value: " + field->name);
}
uint8_t enum_idx;
if (vector_of_union_types) {
@@ -917,7 +962,7 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
} else {
ECHECK(atot(constant.c_str(), *this, &enum_idx));
}
- auto enum_val = val.type.enum_def->ReverseLookup(enum_idx);
+ auto enum_val = val.type.enum_def->ReverseLookup(enum_idx, true);
if (!enum_val) return Error("illegal type id for: " + field->name);
if (enum_val->union_type.base_type == BASE_TYPE_STRUCT) {
ECHECK(ParseTable(*enum_val->union_type.struct_def, &val.constant,
@@ -948,6 +993,10 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
val.constant = NumToString(off);
break;
}
+ case BASE_TYPE_ARRAY: {
+ ECHECK(ParseArray(val));
+ break;
+ }
case BASE_TYPE_INT:
case BASE_TYPE_UINT:
case BASE_TYPE_LONG:
@@ -968,17 +1017,21 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
}
void Parser::SerializeStruct(const StructDef &struct_def, const Value &val) {
+ SerializeStruct(builder_, struct_def, val);
+}
+
+void Parser::SerializeStruct(FlatBufferBuilder &builder,
+ const StructDef &struct_def, const Value &val) {
FLATBUFFERS_ASSERT(val.constant.length() == struct_def.bytesize);
- builder_.Align(struct_def.minalign);
- builder_.PushBytes(reinterpret_cast<const uint8_t *>(val.constant.c_str()),
- struct_def.bytesize);
- builder_.AddStructOffset(val.offset, builder_.GetSize());
+ builder.Align(struct_def.minalign);
+ builder.PushBytes(reinterpret_cast<const uint8_t *>(val.constant.c_str()),
+ struct_def.bytesize);
+ builder.AddStructOffset(val.offset, builder.GetSize());
}
-template <typename F>
+template<typename F>
CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
- const StructDef *struct_def,
- F body) {
+ const StructDef *struct_def, F body) {
// We allow tables both as JSON object{ .. } with field names
// or vector[..] with all fields in order
char terminator = '}';
@@ -1115,8 +1168,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
size == SizeOf(field_value.type.base_type)) {
switch (field_value.type.base_type) {
// clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
case BASE_TYPE_ ## ENUM: \
builder_.Pad(field->padding); \
if (struct_def.fixed) { \
@@ -1130,10 +1182,9 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
builder_.AddElement(field_value.offset, val, valdef); \
} \
break;
- FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
+ FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
case BASE_TYPE_ ## ENUM: \
builder_.Pad(field->padding); \
if (IsStruct(field->value.type)) { \
@@ -1144,9 +1195,15 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
builder_.AddOffset(field_value.offset, val); \
} \
break;
- FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD);
+ FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
- // clang-format on
+ case BASE_TYPE_ARRAY:
+ builder_.Pad(field->padding);
+ builder_.PushBytes(
+ reinterpret_cast<const uint8_t*>(field_value.constant.c_str()),
+ InlineSize(field_value.type));
+ break;
+ // clang-format on
}
}
}
@@ -1172,7 +1229,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
return NoError();
}
-template <typename F>
+template<typename F>
CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) {
EXPECT('[');
for (;;) {
@@ -1186,6 +1243,42 @@ CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) {
return NoError();
}
+static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) {
+ switch (ftype) {
+#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ case BASE_TYPE_##ENUM: return ReadScalar<CTYPE>(a) < ReadScalar<CTYPE>(b);
+ FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
+#undef FLATBUFFERS_TD
+ case BASE_TYPE_STRING:
+ // Indirect offset pointer to string pointer.
+ a += ReadScalar<uoffset_t>(a);
+ b += ReadScalar<uoffset_t>(b);
+ return *reinterpret_cast<const String *>(a) <
+ *reinterpret_cast<const String *>(b);
+ default: return false;
+ }
+}
+
+// See below for why we need our own sort :(
+template<typename T, typename F, typename S>
+void SimpleQsort(T *begin, T *end, size_t width, F comparator, S swapper) {
+ if (end - begin <= static_cast<ptrdiff_t>(width)) return;
+ auto l = begin + width;
+ auto r = end;
+ while (l < r) {
+ if (comparator(begin, l)) {
+ r -= width;
+ swapper(l, r);
+ } else {
+ l++;
+ }
+ }
+ l -= width;
+ swapper(begin, l);
+ SimpleQsort(begin, l, width, comparator, swapper);
+ SimpleQsort(r, end, width, comparator, swapper);
+}
+
CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
FieldDef *field, size_t fieldn) {
uoffset_t count = 0;
@@ -1200,15 +1293,21 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
});
ECHECK(err);
- builder_.StartVector(count * InlineSize(type) / InlineAlignment(type),
- InlineAlignment(type));
+ const auto *force_align = field->attributes.Lookup("force_align");
+ const size_t align =
+ force_align ? static_cast<size_t>(atoi(force_align->constant.c_str()))
+ : 1;
+ const size_t len = count * InlineSize(type) / InlineAlignment(type);
+ const size_t elemsize = InlineAlignment(type);
+ if (align > 1) { builder_.ForceVectorAlignment(len, elemsize, align); }
+
+ builder_.StartVector(len, elemsize);
for (uoffset_t i = 0; i < count; i++) {
// start at the back, since we're building the data backwards.
auto &val = field_stack_.back().first;
switch (val.type.base_type) {
// clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE,...) \
case BASE_TYPE_ ## ENUM: \
if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \
else { \
@@ -1226,6 +1325,122 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
builder_.ClearOffsets();
*ovalue = builder_.EndVector(count);
+
+ if (type.base_type == BASE_TYPE_STRUCT && type.struct_def->has_key) {
+ // We should sort this vector. Find the key first.
+ const FieldDef *key = nullptr;
+ for (auto it = type.struct_def->fields.vec.begin();
+ it != type.struct_def->fields.vec.end(); ++it) {
+ if ((*it)->key) {
+ key = (*it);
+ break;
+ }
+ }
+ FLATBUFFERS_ASSERT(key);
+ // Now sort it.
+ // We can't use std::sort because for structs the size is not known at
+ // compile time, and for tables our iterators dereference offsets, so can't
+ // be used to swap elements.
+ // And we can't use C qsort either, since that would force use to use
+ // globals, making parsing thread-unsafe.
+ // So for now, we use SimpleQsort above.
+ // TODO: replace with something better, preferably not recursive.
+ static voffset_t offset = key->value.offset;
+ static BaseType ftype = key->value.type.base_type;
+
+ if (type.struct_def->fixed) {
+ auto v =
+ reinterpret_cast<VectorOfAny *>(builder_.GetCurrentBufferPointer());
+ SimpleQsort<uint8_t>(
+ v->Data(), v->Data() + v->size() * type.struct_def->bytesize,
+ type.struct_def->bytesize,
+ [](const uint8_t *a, const uint8_t *b) -> bool {
+ return CompareType(a + offset, b + offset, ftype);
+ },
+ [&](uint8_t *a, uint8_t *b) {
+ // FIXME: faster?
+ for (size_t i = 0; i < type.struct_def->bytesize; i++) {
+ std::swap(a[i], b[i]);
+ }
+ });
+ } else {
+ auto v = reinterpret_cast<Vector<Offset<Table>> *>(
+ builder_.GetCurrentBufferPointer());
+ // Here also can't use std::sort. We do have an iterator type for it,
+ // but it is non-standard as it will dereference the offsets, and thus
+ // can't be used to swap elements.
+ SimpleQsort<Offset<Table>>(
+ v->data(), v->data() + v->size(), 1,
+ [](const Offset<Table> *_a, const Offset<Table> *_b) -> bool {
+ // Indirect offset pointer to table pointer.
+ auto a = reinterpret_cast<const uint8_t *>(_a) +
+ ReadScalar<uoffset_t>(_a);
+ auto b = reinterpret_cast<const uint8_t *>(_b) +
+ ReadScalar<uoffset_t>(_b);
+ // Fetch field address from table.
+ a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset);
+ b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset);
+ return CompareType(a, b, ftype);
+ },
+ [&](Offset<Table> *a, Offset<Table> *b) {
+ // These are serialized offsets, so are relative where they are
+ // stored in memory, so compute the distance between these pointers:
+ ptrdiff_t diff = (b - a) * sizeof(Offset<Table>);
+ FLATBUFFERS_ASSERT(diff >= 0); // Guaranteed by SimpleQsort.
+ auto udiff = static_cast<uoffset_t>(diff);
+ a->o = EndianScalar(ReadScalar<uoffset_t>(a) - udiff);
+ b->o = EndianScalar(ReadScalar<uoffset_t>(b) + udiff);
+ std::swap(*a, *b);
+ });
+ }
+ }
+ return NoError();
+}
+
+CheckedError Parser::ParseArray(Value &array) {
+ std::vector<Value> stack;
+ FlatBufferBuilder builder;
+ const auto &type = array.type.VectorType();
+ auto length = array.type.fixed_length;
+ uoffset_t count = 0;
+ auto err = ParseVectorDelimiters(count, [&](uoffset_t &) -> CheckedError {
+ vector_emplace_back(&stack, Value());
+ auto &val = stack.back();
+ val.type = type;
+ if (IsStruct(type)) {
+ ECHECK(ParseTable(*val.type.struct_def, &val.constant, nullptr));
+ } else {
+ ECHECK(ParseSingleValue(nullptr, val, false));
+ }
+ return NoError();
+ });
+ ECHECK(err);
+ if (length != count) return Error("Fixed-length array size is incorrect.");
+
+ for (auto it = stack.rbegin(); it != stack.rend(); ++it) {
+ auto &val = *it;
+ // clang-format off
+ switch (val.type.base_type) {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ case BASE_TYPE_ ## ENUM: \
+ if (IsStruct(val.type)) { \
+ SerializeStruct(builder, *val.type.struct_def, val); \
+ } else { \
+ CTYPE elem; \
+ ECHECK(atot(val.constant.c_str(), *this, &elem)); \
+ builder.PushElement(elem); \
+ } \
+ break;
+ FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ default: FLATBUFFERS_ASSERT(0);
+ }
+ // clang-format on
+ }
+
+ array.constant.assign(
+ reinterpret_cast<const char *>(builder.GetCurrentBufferPointer()),
+ InlineSize(array.type));
return NoError();
}
@@ -1255,12 +1470,11 @@ CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field,
nested_parser.enums_.dict.clear();
nested_parser.enums_.vec.clear();
- if (!ok) {
- ECHECK(Error(nested_parser.error_));
- }
+ if (!ok) { ECHECK(Error(nested_parser.error_)); }
// Force alignment for nested flatbuffer
- builder_.ForceVectorAlignment(nested_parser.builder_.GetSize(), sizeof(uint8_t),
- nested_parser.builder_.GetBufferMinAlignment());
+ builder_.ForceVectorAlignment(
+ nested_parser.builder_.GetSize(), sizeof(uint8_t),
+ nested_parser.builder_.GetBufferMinAlignment());
auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(),
nested_parser.builder_.GetSize());
@@ -1276,7 +1490,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
auto name = attribute_;
if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant)))
return Error("attribute name must be either identifier or string: " +
- name);
+ name);
if (known_attributes_.find(name) == known_attributes_.end())
return Error("user define attributes must be declared before use: " +
name);
@@ -1322,7 +1536,7 @@ CheckedError Parser::TryTypedValue(const std::string *name, int dtoken,
const auto &s = e.constant;
const auto k = s.find_first_of("0123456789.");
if ((std::string::npos != k) && (s.length() > (k + 1)) &&
- (s.at(k) == '0' && is_alpha_char(s.at(k + 1), 'X')) &&
+ (s[k] == '0' && is_alpha_char(s[k + 1], 'X')) &&
(std::string::npos == s.find_first_of("pP", k + 2))) {
return Error(
"invalid number, the exponent suffix of hexadecimal "
@@ -1338,42 +1552,33 @@ CheckedError Parser::TryTypedValue(const std::string *name, int dtoken,
CheckedError Parser::ParseEnumFromString(const Type &type,
std::string *result) {
- int64_t i64 = 0;
- // Parse one or more enum identifiers, separated by spaces.
- const char *next = attribute_.c_str();
- do {
- const char *divider = strchr(next, ' ');
- std::string word;
- if (divider) {
- word = std::string(next, divider);
- next = divider + strspn(divider, " ");
+ const auto base_type =
+ type.enum_def ? type.enum_def->underlying_type.base_type : type.base_type;
+ if (!IsInteger(base_type)) return Error("not a valid value for this field");
+ uint64_t u64 = 0;
+ for (size_t pos = 0; pos != std::string::npos;) {
+ const auto delim = attribute_.find_first_of(' ', pos);
+ const auto last = (std::string::npos == delim);
+ auto word = attribute_.substr(pos, !last ? delim - pos : std::string::npos);
+ pos = !last ? delim + 1 : std::string::npos;
+ const EnumVal *ev = nullptr;
+ if (type.enum_def) {
+ ev = type.enum_def->Lookup(word);
} else {
- word = next;
- next += word.length();
- }
- if (type.enum_def) { // The field has an enum type
- auto enum_val = type.enum_def->vals.Lookup(word);
- if (!enum_val)
- return Error("unknown enum value: " + word +
- ", for enum: " + type.enum_def->name);
- i64 |= enum_val->value;
- } else { // No enum type, probably integral field.
- if (!IsInteger(type.base_type))
- return Error("not a valid value for this field: " + word);
- // TODO: could check if its a valid number constant here.
- const char *dot = strrchr(word.c_str(), '.');
- if (!dot)
+ auto dot = word.find_first_of('.');
+ if (std::string::npos == dot)
return Error("enum values need to be qualified by an enum type");
- std::string enum_def_str(word.c_str(), dot);
- std::string enum_val_str(dot + 1, word.c_str() + word.length());
- auto enum_def = LookupEnum(enum_def_str);
+ auto enum_def_str = word.substr(0, dot);
+ const auto enum_def = LookupEnum(enum_def_str);
if (!enum_def) return Error("unknown enum: " + enum_def_str);
- auto enum_val = enum_def->vals.Lookup(enum_val_str);
- if (!enum_val) return Error("unknown enum value: " + enum_val_str);
- i64 |= enum_val->value;
+ auto enum_val_str = word.substr(dot + 1);
+ ev = enum_def->Lookup(enum_val_str);
}
- } while (*next);
- *result = NumToString(i64);
+ if (!ev) return Error("unknown enum value: " + word);
+ u64 |= ev->GetAsUInt64();
+ }
+ *result = IsUnsigned(base_type) ? NumToString(u64)
+ : NumToString(static_cast<int64_t>(u64));
return NoError();
}
@@ -1427,6 +1632,21 @@ CheckedError Parser::TokenError() {
return Error("cannot parse value starting with: " + TokenToStringId(token_));
}
+// Re-pack helper (ParseSingleValue) to normalize defaults of scalars.
+template<typename T> inline void SingleValueRepack(Value &e, T val) {
+ // Remove leading zeros.
+ if (IsInteger(e.type.base_type)) { e.constant = NumToString(val); }
+}
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+// Normilaze defaults NaN to unsigned quiet-NaN(0).
+static inline void SingleValueRepack(Value &e, float val) {
+ if (val != val) e.constant = "nan";
+}
+static inline void SingleValueRepack(Value &e, double val) {
+ if (val != val) e.constant = "nan";
+}
+#endif
+
CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
bool check_now) {
// First see if this could be a conversion function:
@@ -1471,96 +1691,99 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
}
auto match = false;
+ const auto in_type = e.type.base_type;
// clang-format off
- #define TRY_ECHECK(force, dtoken, check, req) \
+ #define IF_ECHECK_(force, dtoken, check, req) \
if (!match && ((check) || IsConstTrue(force))) \
ECHECK(TryTypedValue(name, dtoken, check, e, req, &match))
+ #define TRY_ECHECK(dtoken, check, req) IF_ECHECK_(false, dtoken, check, req)
+ #define FORCE_ECHECK(dtoken, check, req) IF_ECHECK_(true, dtoken, check, req)
// clang-format on
if (token_ == kTokenStringConstant || token_ == kTokenIdentifier) {
const auto kTokenStringOrIdent = token_;
// The string type is a most probable type, check it first.
- TRY_ECHECK(false, kTokenStringConstant,
- e.type.base_type == BASE_TYPE_STRING, BASE_TYPE_STRING);
+ TRY_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING,
+ BASE_TYPE_STRING);
// avoid escaped and non-ascii in the string
- if ((token_ == kTokenStringConstant) && IsScalar(e.type.base_type) &&
+ if (!match && (token_ == kTokenStringConstant) && IsScalar(in_type) &&
!attr_is_trivial_ascii_string_) {
return Error(
std::string("type mismatch or invalid value, an initializer of "
"non-string field must be trivial ASCII string: type: ") +
- kTypeNames[e.type.base_type] + ", name: " + (name ? *name : "") +
+ kTypeNames[in_type] + ", name: " + (name ? *name : "") +
", value: " + attribute_);
}
// A boolean as true/false. Boolean as Integer check below.
- if (!match && IsBool(e.type.base_type)) {
+ if (!match && IsBool(in_type)) {
auto is_true = attribute_ == "true";
if (is_true || attribute_ == "false") {
attribute_ = is_true ? "1" : "0";
// accepts both kTokenStringConstant and kTokenIdentifier
- TRY_ECHECK(false, kTokenStringOrIdent, IsBool(e.type.base_type),
- BASE_TYPE_BOOL);
+ TRY_ECHECK(kTokenStringOrIdent, IsBool(in_type), BASE_TYPE_BOOL);
}
}
// Check if this could be a string/identifier enum value.
// Enum can have only true integer base type.
- if (!match && IsInteger(e.type.base_type) && !IsBool(e.type.base_type) &&
+ if (!match && IsInteger(in_type) && !IsBool(in_type) &&
IsIdentifierStart(*attribute_.c_str())) {
ECHECK(ParseEnumFromString(e.type, &e.constant));
NEXT();
match = true;
}
- // float/integer number in string
- if ((token_ == kTokenStringConstant) && IsScalar(e.type.base_type)) {
+ // Parse a float/integer number from the string.
+ if (!match) check_now = true; // Re-pack if parsed from string literal.
+ if (!match && (token_ == kTokenStringConstant) && IsScalar(in_type)) {
// remove trailing whitespaces from attribute_
auto last = attribute_.find_last_not_of(' ');
if (std::string::npos != last) // has non-whitespace
attribute_.resize(last + 1);
}
// Float numbers or nan, inf, pi, etc.
- TRY_ECHECK(false, kTokenStringOrIdent, IsFloat(e.type.base_type),
- BASE_TYPE_FLOAT);
+ TRY_ECHECK(kTokenStringOrIdent, IsFloat(in_type), BASE_TYPE_FLOAT);
// An integer constant in string.
- TRY_ECHECK(false, kTokenStringOrIdent, IsInteger(e.type.base_type),
- BASE_TYPE_INT);
+ TRY_ECHECK(kTokenStringOrIdent, IsInteger(in_type), BASE_TYPE_INT);
// Unknown tokens will be interpreted as string type.
- TRY_ECHECK(true, kTokenStringConstant, e.type.base_type == BASE_TYPE_STRING,
- BASE_TYPE_STRING);
+ // An attribute value may be a scalar or string constant.
+ FORCE_ECHECK(kTokenStringConstant, in_type == BASE_TYPE_STRING,
+ BASE_TYPE_STRING);
} else {
// Try a float number.
- TRY_ECHECK(false, kTokenFloatConstant, IsFloat(e.type.base_type),
- BASE_TYPE_FLOAT);
+ TRY_ECHECK(kTokenFloatConstant, IsFloat(in_type), BASE_TYPE_FLOAT);
// Integer token can init any scalar (integer of float).
- TRY_ECHECK(true, kTokenIntegerConstant, IsScalar(e.type.base_type),
- BASE_TYPE_INT);
+ FORCE_ECHECK(kTokenIntegerConstant, IsScalar(in_type), BASE_TYPE_INT);
}
- #undef TRY_ECHECK
-
- if (!match) return TokenError();
+#undef FORCE_ECHECK
+#undef TRY_ECHECK
+#undef IF_ECHECK_
+ if (!match) {
+ std::string msg;
+ msg += "Cannot assign token starting with '" + TokenToStringId(token_) +
+ "' to value of <" + std::string(kTypeNames[in_type]) + "> type.";
+ return Error(msg);
+ }
+ const auto match_type = e.type.base_type; // may differ from in_type
// The check_now flag must be true when parse a fbs-schema.
// This flag forces to check default scalar values or metadata of field.
// For JSON parser the flag should be false.
// If it is set for JSON each value will be checked twice (see ParseTable).
- if (check_now && IsScalar(e.type.base_type)) {
- // "re-pack" an integer scalar to remove any ambiguities like leading zeros
- // which can be treated as octal-literal (idl_gen_cpp/GenDefaultConstant).
- const auto repack = IsInteger(e.type.base_type);
- switch (e.type.base_type) {
+ if (check_now && IsScalar(match_type)) {
// clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
- CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
- case BASE_TYPE_ ## ENUM: {\
- CTYPE val; \
- ECHECK(atot(e.constant.c_str(), *this, &val)); \
- if(repack) e.constant = NumToString(val); \
- break; }
- FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
+ switch (match_type) {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ case BASE_TYPE_ ## ENUM: {\
+ CTYPE val; \
+ ECHECK(atot(e.constant.c_str(), *this, &val)); \
+ SingleValueRepack(e, val); \
+ break; }
+ FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
default: break;
- // clang-format on
}
+ // clang-format on
}
return NoError();
}
@@ -1618,7 +1841,203 @@ StructDef *Parser::LookupCreateStruct(const std::string &name,
return struct_def;
}
-CheckedError Parser::ParseEnum(bool is_union, EnumDef **dest) {
+const EnumVal *EnumDef::MinValue() const {
+ return vals.vec.empty() ? nullptr : vals.vec.front();
+}
+const EnumVal *EnumDef::MaxValue() const {
+ return vals.vec.empty() ? nullptr : vals.vec.back();
+}
+
+template<typename T> static uint64_t EnumDistanceImpl(T e1, T e2) {
+ if (e1 < e2) { std::swap(e1, e2); } // use std for scalars
+ // Signed overflow may occur, use unsigned calculation.
+ // The unsigned overflow is well-defined by C++ standard (modulo 2^n).
+ return static_cast<uint64_t>(e1) - static_cast<uint64_t>(e2);
+}
+
+uint64_t EnumDef::Distance(const EnumVal *v1, const EnumVal *v2) const {
+ return IsUInt64() ? EnumDistanceImpl(v1->GetAsUInt64(), v2->GetAsUInt64())
+ : EnumDistanceImpl(v1->GetAsInt64(), v2->GetAsInt64());
+}
+
+std::string EnumDef::AllFlags() const {
+ FLATBUFFERS_ASSERT(attributes.Lookup("bit_flags"));
+ uint64_t u64 = 0;
+ for (auto it = Vals().begin(); it != Vals().end(); ++it) {
+ u64 |= (*it)->GetAsUInt64();
+ }
+ return IsUInt64() ? NumToString(u64) : NumToString(static_cast<int64_t>(u64));
+}
+
+EnumVal *EnumDef::ReverseLookup(int64_t enum_idx,
+ bool skip_union_default) const {
+ auto skip_first = static_cast<int>(is_union && skip_union_default);
+ for (auto it = Vals().begin() + skip_first; it != Vals().end(); ++it) {
+ if ((*it)->GetAsInt64() == enum_idx) { return *it; }
+ }
+ return nullptr;
+}
+
+EnumVal *EnumDef::FindByValue(const std::string &constant) const {
+ int64_t i64;
+ auto done = false;
+ if (IsUInt64()) {
+ uint64_t u64; // avoid reinterpret_cast of pointers
+ done = StringToNumber(constant.c_str(), &u64);
+ i64 = static_cast<int64_t>(u64);
+ } else {
+ done = StringToNumber(constant.c_str(), &i64);
+ }
+ FLATBUFFERS_ASSERT(done);
+ if (!done) return nullptr;
+ return ReverseLookup(i64, false);
+}
+
+void EnumDef::SortByValue() {
+ auto &v = vals.vec;
+ if (IsUInt64())
+ std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) {
+ return e1->GetAsUInt64() < e2->GetAsUInt64();
+ });
+ else
+ std::sort(v.begin(), v.end(), [](const EnumVal *e1, const EnumVal *e2) {
+ return e1->GetAsInt64() < e2->GetAsInt64();
+ });
+}
+
+void EnumDef::RemoveDuplicates() {
+ // This method depends form SymbolTable implementation!
+ // 1) vals.vec - owner (raw pointer)
+ // 2) vals.dict - access map
+ auto first = vals.vec.begin();
+ auto last = vals.vec.end();
+ if (first == last) return;
+ auto result = first;
+ while (++first != last) {
+ if ((*result)->value != (*first)->value) {
+ *(++result) = *first;
+ } else {
+ auto ev = *first;
+ for (auto it = vals.dict.begin(); it != vals.dict.end(); ++it) {
+ if (it->second == ev) it->second = *result; // reassign
+ }
+ delete ev; // delete enum value
+ *first = nullptr;
+ }
+ }
+ vals.vec.erase(++result, last);
+}
+
+template<typename T> void EnumDef::ChangeEnumValue(EnumVal *ev, T new_value) {
+ ev->value = static_cast<int64_t>(new_value);
+}
+
+namespace EnumHelper {
+template<BaseType E> struct EnumValType { typedef int64_t type; };
+template<> struct EnumValType<BASE_TYPE_ULONG> { typedef uint64_t type; };
+} // namespace EnumHelper
+
+struct EnumValBuilder {
+ EnumVal *CreateEnumerator(const std::string &ev_name) {
+ FLATBUFFERS_ASSERT(!temp);
+ auto first = enum_def.vals.vec.empty();
+ user_value = first;
+ temp = new EnumVal(ev_name, first ? 0 : enum_def.vals.vec.back()->value);
+ return temp;
+ }
+
+ EnumVal *CreateEnumerator(const std::string &ev_name, int64_t val) {
+ FLATBUFFERS_ASSERT(!temp);
+ user_value = true;
+ temp = new EnumVal(ev_name, val);
+ return temp;
+ }
+
+ FLATBUFFERS_CHECKED_ERROR AcceptEnumerator(const std::string &name) {
+ FLATBUFFERS_ASSERT(temp);
+ ECHECK(ValidateValue(&temp->value, false == user_value));
+ FLATBUFFERS_ASSERT((temp->union_type.enum_def == nullptr) ||
+ (temp->union_type.enum_def == &enum_def));
+ auto not_unique = enum_def.vals.Add(name, temp);
+ temp = nullptr;
+ if (not_unique) return parser.Error("enum value already exists: " + name);
+ return NoError();
+ }
+
+ FLATBUFFERS_CHECKED_ERROR AcceptEnumerator() {
+ return AcceptEnumerator(temp->name);
+ }
+
+ FLATBUFFERS_CHECKED_ERROR AssignEnumeratorValue(const std::string &value) {
+ user_value = true;
+ auto fit = false;
+ auto ascending = false;
+ if (enum_def.IsUInt64()) {
+ uint64_t u64;
+ fit = StringToNumber(value.c_str(), &u64);
+ ascending = u64 > temp->GetAsUInt64();
+ temp->value = static_cast<int64_t>(u64); // well-defined since C++20.
+ } else {
+ int64_t i64;
+ fit = StringToNumber(value.c_str(), &i64);
+ ascending = i64 > temp->GetAsInt64();
+ temp->value = i64;
+ }
+ if (!fit) return parser.Error("enum value does not fit, \"" + value + "\"");
+ if (!ascending && strict_ascending && !enum_def.vals.vec.empty())
+ return parser.Error("enum values must be specified in ascending order");
+ return NoError();
+ }
+
+ template<BaseType E, typename CTYPE>
+ inline FLATBUFFERS_CHECKED_ERROR ValidateImpl(int64_t *ev, int m) {
+ typedef typename EnumHelper::EnumValType<E>::type T; // int64_t or uint64_t
+ static_assert(sizeof(T) == sizeof(int64_t), "invalid EnumValType");
+ const auto v = static_cast<T>(*ev);
+ auto up = static_cast<T>((flatbuffers::numeric_limits<CTYPE>::max)());
+ auto dn = static_cast<T>((flatbuffers::numeric_limits<CTYPE>::lowest)());
+ if (v < dn || v > (up - m)) {
+ return parser.Error("enum value does not fit, \"" + NumToString(v) +
+ (m ? " + 1\"" : "\"") + " out of " +
+ TypeToIntervalString<CTYPE>());
+ }
+ *ev = static_cast<int64_t>(v + m); // well-defined since C++20.
+ return NoError();
+ }
+
+ FLATBUFFERS_CHECKED_ERROR ValidateValue(int64_t *ev, bool next) {
+ // clang-format off
+ switch (enum_def.underlying_type.base_type) {
+ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
+ case BASE_TYPE_##ENUM: { \
+ if (!IsInteger(BASE_TYPE_##ENUM)) break; \
+ return ValidateImpl<BASE_TYPE_##ENUM, CTYPE>(ev, next ? 1 : 0); \
+ }
+ FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
+ #undef FLATBUFFERS_TD
+ default: break;
+ }
+ // clang-format on
+ return parser.Error("fatal: invalid enum underlying type");
+ }
+
+ EnumValBuilder(Parser &_parser, EnumDef &_enum_def, bool strict_order = true)
+ : parser(_parser),
+ enum_def(_enum_def),
+ temp(nullptr),
+ strict_ascending(strict_order),
+ user_value(false) {}
+
+ ~EnumValBuilder() { delete temp; }
+
+ Parser &parser;
+ EnumDef &enum_def;
+ EnumVal *temp;
+ const bool strict_ascending;
+ bool user_value;
+};
+
+CheckedError Parser::ParseEnum(const bool is_union, EnumDef **dest) {
std::vector<std::string> enum_comment = doc_comment_;
NEXT();
std::string enum_name = attribute_;
@@ -1645,33 +2064,38 @@ CheckedError Parser::ParseEnum(bool is_union, EnumDef **dest) {
enum_def->underlying_type.enum_def = enum_def;
}
ECHECK(ParseMetaData(&enum_def->attributes));
+ const auto underlying_type = enum_def->underlying_type.base_type;
+ if (enum_def->attributes.Lookup("bit_flags") &&
+ !IsUnsigned(underlying_type)) {
+ // todo: Convert to the Error in the future?
+ Warning("underlying type of bit_flags enum must be unsigned");
+ }
+ // Protobuf allows them to be specified in any order, so sort afterwards.
+ const auto strict_ascending = (false == opts.proto_mode);
+ EnumValBuilder evb(*this, *enum_def, strict_ascending);
EXPECT('{');
- if (is_union) enum_def->vals.Add("NONE", new EnumVal("NONE", 0));
- std::set<std::pair<BaseType, StructDef*>> union_types;
- for (;;) {
+ // A lot of code generatos expect that an enum is not-empty.
+ if ((is_union || Is('}')) && !opts.proto_mode) {
+ evb.CreateEnumerator("NONE");
+ ECHECK(evb.AcceptEnumerator());
+ }
+ std::set<std::pair<BaseType, StructDef *>> union_types;
+ while (!Is('}')) {
if (opts.proto_mode && attribute_ == "option") {
ECHECK(ParseProtoOption());
} else {
- auto value_name = attribute_;
- auto full_name = value_name;
- std::vector<std::string> value_comment = doc_comment_;
+ auto &ev = *evb.CreateEnumerator(attribute_);
+ auto full_name = ev.name;
+ ev.doc_comment = doc_comment_;
EXPECT(kTokenIdentifier);
if (is_union) {
- ECHECK(ParseNamespacing(&full_name, &value_name));
+ ECHECK(ParseNamespacing(&full_name, &ev.name));
if (opts.union_value_namespacing) {
// Since we can't namespace the actual enum identifiers, turn
// namespace parts into part of the identifier.
- value_name = full_name;
- std::replace(value_name.begin(), value_name.end(), '.', '_');
+ ev.name = full_name;
+ std::replace(ev.name.begin(), ev.name.end(), '.', '_');
}
- }
- auto prevsize = enum_def->vals.vec.size();
- auto prevvalue = prevsize > 0 ? enum_def->vals.vec.back()->value : 0;
- auto &ev = *new EnumVal(value_name, 0);
- if (enum_def->vals.Add(value_name, &ev))
- return Error("enum value already exists: " + value_name);
- ev.doc_comment = value_comment;
- if (is_union) {
if (Is(':')) {
NEXT();
ECHECK(ParseType(ev.union_type));
@@ -1682,51 +2106,22 @@ CheckedError Parser::ParseEnum(bool is_union, EnumDef **dest) {
ev.union_type = Type(BASE_TYPE_STRUCT, LookupCreateStruct(full_name));
}
if (!enum_def->uses_multiple_type_instances) {
- auto union_type_key = std::make_pair(ev.union_type.base_type, ev.union_type.struct_def);
- if (union_types.count(union_type_key) > 0) {
- enum_def->uses_multiple_type_instances = true;
- } else {
- union_types.insert(union_type_key);
- }
+ auto ins = union_types.insert(std::make_pair(
+ ev.union_type.base_type, ev.union_type.struct_def));
+ enum_def->uses_multiple_type_instances = (false == ins.second);
}
}
+
if (Is('=')) {
NEXT();
- ECHECK(atot(attribute_.c_str(), *this, &ev.value));
+ ECHECK(evb.AssignEnumeratorValue(attribute_));
EXPECT(kTokenIntegerConstant);
- if (!opts.proto_mode && prevsize &&
- enum_def->vals.vec[prevsize - 1]->value >= ev.value)
- return Error("enum values must be specified in ascending order");
- } else if (prevsize == 0) {
- // already set to zero
- } else if (prevvalue != flatbuffers::numeric_limits<int64_t>::max()) {
- ev.value = prevvalue + 1;
- } else {
- return Error("enum value overflows");
+ } else if (false == strict_ascending) {
+ // The opts.proto_mode flag is active.
+ return Error("Protobuf mode doesn't allow implicit enum values.");
}
- // Check that value fits into the underlying type.
- switch (enum_def->underlying_type.base_type) {
- // clang-format off
- #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
- PTYPE, RTYPE) \
- case BASE_TYPE_##ENUM: { \
- int64_t min_value = static_cast<int64_t>( \
- flatbuffers::numeric_limits<CTYPE>::lowest()); \
- int64_t max_value = static_cast<int64_t>( \
- flatbuffers::numeric_limits<CTYPE>::max()); \
- if (ev.value < min_value || ev.value > max_value) { \
- return Error( \
- "enum value does not fit [" + NumToString(min_value) + \
- "; " + NumToString(max_value) + "]"); \
- } \
- break; \
- }
- FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
- #undef FLATBUFFERS_TD
- default: break;
- // clang-format on
- }
+ ECHECK(evb.AcceptEnumerator());
if (opts.proto_mode && Is('[')) {
NEXT();
@@ -1737,18 +2132,31 @@ CheckedError Parser::ParseEnum(bool is_union, EnumDef **dest) {
}
if (!Is(opts.proto_mode ? ';' : ',')) break;
NEXT();
- if (Is('}')) break;
}
EXPECT('}');
+
+ // At this point, the enum can be empty if input is invalid proto-file.
+ if (!enum_def->size())
+ return Error("incomplete enum declaration, values not found");
+
if (enum_def->attributes.Lookup("bit_flags")) {
- for (auto it = enum_def->vals.vec.begin(); it != enum_def->vals.vec.end();
+ const auto base_width = static_cast<uint64_t>(8 * SizeOf(underlying_type));
+ for (auto it = enum_def->Vals().begin(); it != enum_def->Vals().end();
++it) {
- if (static_cast<size_t>((*it)->value) >=
- SizeOf(enum_def->underlying_type.base_type) * 8)
+ auto ev = *it;
+ const auto u = ev->GetAsUInt64();
+ // Stop manipulations with the sign.
+ if (!IsUnsigned(underlying_type) && u == (base_width - 1))
+ return Error("underlying type of bit_flags enum must be unsigned");
+ if (u >= base_width)
return Error("bit flag out of range of underlying integral type");
- (*it)->value = 1LL << (*it)->value;
+ enum_def->ChangeEnumValue(ev, 1ULL << u);
}
}
+
+ if (false == strict_ascending)
+ enum_def->SortByValue(); // Must be sorted to use MinValue/MaxValue.
+
if (dest) *dest = enum_def;
types_.Add(current_namespace_->GetFullyQualifiedName(enum_def->name),
new Type(BASE_TYPE_UNION, nullptr, enum_def));
@@ -1791,10 +2199,18 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
bool Parser::SupportsAdvancedUnionFeatures() const {
return opts.lang_to_generate != 0 &&
- (opts.lang_to_generate & ~(IDLOptions::kCpp | IDLOptions::kJs |
- IDLOptions::kTs | IDLOptions::kPhp |
- IDLOptions::kJava | IDLOptions::kCSharp |
- IDLOptions::kBinary)) == 0;
+ (opts.lang_to_generate &
+ ~(IDLOptions::kCpp | IDLOptions::kJs | IDLOptions::kTs |
+ IDLOptions::kPhp | IDLOptions::kJava | IDLOptions::kCSharp |
+ IDLOptions::kKotlin | IDLOptions::kBinary | IDLOptions::kSwift)) ==
+ 0;
+}
+
+bool Parser::SupportsAdvancedArrayFeatures() const {
+ return (opts.lang_to_generate &
+ ~(IDLOptions::kCpp | IDLOptions::kPython | IDLOptions::kJava |
+ IDLOptions::kCSharp | IDLOptions::kJsonSchema | IDLOptions::kJson |
+ IDLOptions::kBinary)) == 0;
}
Namespace *Parser::UniqueNamespace(Namespace *ns) {
@@ -1808,7 +2224,7 @@ Namespace *Parser::UniqueNamespace(Namespace *ns) {
return ns;
}
-std::string Parser::UnqualifiedName(std::string full_qualified_name) {
+std::string Parser::UnqualifiedName(const std::string &full_qualified_name) {
Namespace *ns = new Namespace();
std::size_t current, previous = 0;
@@ -1982,10 +2398,6 @@ CheckedError Parser::ParseNamespace() {
return NoError();
}
-static bool compareEnumVals(const EnumVal *a, const EnumVal *b) {
- return a->value < b->value;
-}
-
// Best effort parsing of .proto declarations, with the aim to turn them
// in the closest corresponding FlatBuffer equivalent.
// We parse everything as identifiers instead of keywords, since we don't
@@ -2031,25 +2443,8 @@ CheckedError Parser::ParseProtoDecl() {
EnumDef *enum_def;
ECHECK(ParseEnum(false, &enum_def));
if (Is(';')) NEXT();
- // Protobuf allows them to be specified in any order, so sort afterwards.
- auto &v = enum_def->vals.vec;
- std::sort(v.begin(), v.end(), compareEnumVals);
-
// Temp: remove any duplicates, as .fbs files can't handle them.
- for (auto it = v.begin(); it != v.end();) {
- if (it != v.begin() && it[0]->value == it[-1]->value) {
- auto ref = it[-1];
- auto ev = it[0];
- for (auto dit = enum_def->vals.dict.begin();
- dit != enum_def->vals.dict.end(); ++dit) {
- if (dit->second == ev) dit->second = ref; // reassign
- }
- delete ev; // delete enum value
- it = v.erase(it);
- } else {
- ++it;
- }
- }
+ enum_def->RemoveDuplicates();
} else if (IsIdent("syntax")) { // Skip these.
NEXT();
EXPECT('=');
@@ -2080,8 +2475,8 @@ CheckedError Parser::StartEnum(const std::string &enum_name, bool is_union,
if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name),
&enum_def))
return Error("enum already exists: " + enum_name);
- enum_def.underlying_type.base_type = is_union ? BASE_TYPE_UTYPE
- : BASE_TYPE_INT;
+ enum_def.underlying_type.base_type =
+ is_union ? BASE_TYPE_UTYPE : BASE_TYPE_INT;
enum_def.underlying_type.enum_def = &enum_def;
if (dest) *dest = &enum_def;
return NoError();
@@ -2217,13 +2612,13 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
if (oneof_type.base_type != BASE_TYPE_STRUCT ||
!oneof_type.struct_def || oneof_type.struct_def->fixed)
return Error("oneof '" + name +
- "' cannot be mapped to a union because member '" +
- oneof_field.name + "' is not a table type.");
- auto enum_val = new EnumVal(oneof_type.struct_def->name,
- oneof_union->vals.vec.size());
- enum_val->union_type = oneof_type;
- enum_val->doc_comment = oneof_field.doc_comment;
- oneof_union->vals.Add(oneof_field.name, enum_val);
+ "' cannot be mapped to a union because member '" +
+ oneof_field.name + "' is not a table type.");
+ EnumValBuilder evb(*this, *oneof_union);
+ auto ev = evb.CreateEnumerator(oneof_type.struct_def->name);
+ ev->union_type = oneof_type;
+ ev->doc_comment = oneof_field.doc_comment;
+ ECHECK(evb.AcceptEnumerator(oneof_field.name));
}
} else {
EXPECT(';');
@@ -2377,10 +2772,13 @@ CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
builder->Int(StringToInt(attribute_.c_str()));
EXPECT(kTokenIntegerConstant);
break;
- case kTokenFloatConstant:
- builder->Double(strtod(attribute_.c_str(), nullptr));
+ case kTokenFloatConstant: {
+ double d;
+ StringToNumber(attribute_.c_str(), &d);
+ builder->Double(d);
EXPECT(kTokenFloatConstant);
break;
+ }
default:
if (IsIdent("true")) {
builder->Bool(true);
@@ -2408,7 +2806,13 @@ bool Parser::ParseFlexBuffer(const char *source, const char *source_filename,
bool Parser::Parse(const char *source, const char **include_paths,
const char *source_filename) {
FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
- auto r = !ParseRoot(source, include_paths, source_filename).Check();
+ bool r;
+
+ if (opts.use_flexbuffers) {
+ r = ParseFlexBuffer(source, source_filename, &flex_builder_);
+ } else {
+ r = !ParseRoot(source, include_paths, source_filename).Check();
+ }
FLATBUFFERS_ASSERT(0 == recurse_protection_counter);
return r;
}
@@ -2577,9 +2981,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
// entered into included_files_.
// This is recursive, but only go as deep as the number of include
// statements.
- if (source_filename) {
- included_files_.erase(source_filename);
- }
+ if (source_filename) { included_files_.erase(source_filename); }
return DoParse(source, include_paths, source_filename,
include_filename);
}
@@ -2603,9 +3005,9 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
uoffset_t toff;
ECHECK(ParseTable(*root_struct_def_, nullptr, &toff));
if (opts.size_prefixed) {
- builder_.FinishSizePrefixed(Offset<Table>(toff), file_identifier_.length()
- ? file_identifier_.c_str()
- : nullptr);
+ builder_.FinishSizePrefixed(
+ Offset<Table>(toff),
+ file_identifier_.length() ? file_identifier_.c_str() : nullptr);
} else {
builder_.Finish(Offset<Table>(toff), file_identifier_.length()
? file_identifier_.c_str()
@@ -2626,8 +3028,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
if (opts.root_type.empty()) {
if (!SetRootType(root_type.c_str()))
return Error("unknown root type: " + root_type);
- if (root_struct_def_->fixed)
- return Error("root type must be a table");
+ if (root_struct_def_->fixed) return Error("root type must be a table");
}
EXPECT(';');
} else if (IsIdent("file_identifier")) {
@@ -2732,10 +3133,9 @@ void Parser::Serialize() {
auto fiid__ = builder_.CreateString(file_identifier_);
auto fext__ = builder_.CreateString(file_extension_);
auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets);
- auto schema_offset =
- reflection::CreateSchema(builder_, objs__, enum__, fiid__, fext__,
- (root_struct_def_ ? root_struct_def_->serialized_location : 0),
- serv__);
+ auto schema_offset = reflection::CreateSchema(
+ builder_, objs__, enum__, fiid__, fext__,
+ (root_struct_def_ ? root_struct_def_->serialized_location : 0), serv__);
if (opts.size_prefixed) {
builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier());
} else {
@@ -2761,7 +3161,7 @@ static Namespace *GetNamespace(
for (;;) {
dot = qualified_name.find('.', pos);
if (dot == std::string::npos) { break; }
- ns->components.push_back(qualified_name.substr(pos, dot-pos));
+ ns->components.push_back(qualified_name.substr(pos, dot - pos));
pos = dot + 1;
}
}
@@ -2781,29 +3181,25 @@ Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder,
auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets);
auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments
- ? builder->CreateVectorOfStrings(doc_comment)
- : 0;
+ ? builder->CreateVectorOfStrings(doc_comment)
+ : 0;
return reflection::CreateObject(*builder, name__, flds__, fixed,
static_cast<int>(minalign),
- static_cast<int>(bytesize),
- attr__, docs__);
+ static_cast<int>(bytesize), attr__, docs__);
}
bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
- if (!DeserializeAttributes(parser, object->attributes()))
- return false;
+ if (!DeserializeAttributes(parser, object->attributes())) return false;
DeserializeDoc(doc_comment, object->documentation());
name = parser.UnqualifiedName(object->name()->str());
- fixed = object->is_struct();
- minalign = object->minalign();
predecl = false;
sortbysize = attributes.Lookup("original_order") == nullptr && !fixed;
- std::vector<uoffset_t> indexes =
- std::vector<uoffset_t>(object->fields()->size());
- for (uoffset_t i = 0; i < object->fields()->size(); i++)
- indexes[object->fields()->Get(i)->id()] = i;
+ const auto &of = *(object->fields());
+ auto indexes = std::vector<uoffset_t>(of.size());
+ for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i;
+ size_t tmp_struct_size = 0;
for (size_t i = 0; i < indexes.size(); i++) {
- auto field = object->fields()->Get(indexes[i]);
+ auto field = of.Get(indexes[i]);
auto field_def = new FieldDef();
if (!field_def->Deserialize(parser, field) ||
fields.Add(field_def->name, field_def)) {
@@ -2814,17 +3210,15 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
// Recompute padding since that's currently not serialized.
auto size = InlineSize(field_def->value.type);
auto next_field =
- i + 1 < indexes.size()
- ? object->fields()->Get(indexes[i+1])
- : nullptr;
- bytesize += size;
+ i + 1 < indexes.size() ? of.Get(indexes[i + 1]) : nullptr;
+ tmp_struct_size += size;
field_def->padding =
next_field ? (next_field->offset() - field_def->value.offset) - size
- : PaddingBytes(bytesize, minalign);
- bytesize += field_def->padding;
+ : PaddingBytes(tmp_struct_size, minalign);
+ tmp_struct_size += field_def->padding;
}
}
- FLATBUFFERS_ASSERT(static_cast<int>(bytesize) == object->bytesize());
+ FLATBUFFERS_ASSERT(static_cast<int>(tmp_struct_size) == object->bytesize());
return true;
}
@@ -2835,24 +3229,25 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
auto type__ = value.type.Serialize(builder);
auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments
- ? builder->CreateVectorOfStrings(doc_comment)
- : 0;
- return reflection::CreateField(*builder, name__, type__, id, value.offset,
+ ? builder->CreateVectorOfStrings(doc_comment)
+ : 0;
+ double d;
+ StringToNumber(value.constant.c_str(), &d);
+ return reflection::CreateField(
+ *builder, name__, type__, id, value.offset,
// Is uint64>max(int64) tested?
IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
// result may be platform-dependent if underlying is float (not double)
- IsFloat(value.type.base_type) ? strtod(value.constant.c_str(), nullptr)
- : 0.0,
- deprecated, required, key, attr__, docs__);
+ IsFloat(value.type.base_type) ? d : 0.0, deprecated, required, key,
+ attr__, docs__);
// TODO: value.constant is almost always "0", we could save quite a bit of
// space by sharing it. Same for common values of value.type.
}
bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
- name = parser.UnqualifiedName(field->name()->str());
+ name = field->name()->str();
defined_namespace = parser.current_namespace_;
- if (!value.type.Deserialize(parser, field->type()))
- return false;
+ if (!value.type.Deserialize(parser, field->type())) return false;
value.offset = field->offset();
if (IsInteger(value.type.base_type)) {
value.constant = NumToString(field->default_integer());
@@ -2866,8 +3261,7 @@ bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
deprecated = field->deprecated();
required = field->required();
key = field->key();
- if (!DeserializeAttributes(parser, field->attributes()))
- return false;
+ if (!DeserializeAttributes(parser, field->attributes())) return false;
// TODO: this should probably be handled by a separate attribute
if (attributes.Lookup("flexbuffer")) {
flexbuffer = true;
@@ -2876,6 +3270,12 @@ bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
value.type.element != BASE_TYPE_UCHAR)
return false;
}
+ if (auto nested = attributes.Lookup("nested_flatbuffer")) {
+ auto nested_qualified_name =
+ parser.current_namespace_->GetFullyQualifiedName(nested->constant);
+ nested_flatbuffer = parser.LookupStruct(nested_qualified_name);
+ if (!nested_flatbuffer) return false;
+ }
DeserializeDoc(doc_comment, field->documentation());
return true;
}
@@ -2885,18 +3285,16 @@ Offset<reflection::RPCCall> RPCCall::Serialize(FlatBufferBuilder *builder,
auto name__ = builder->CreateString(name);
auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments
- ? builder->CreateVectorOfStrings(doc_comment)
- : 0;
- return reflection::CreateRPCCall(*builder, name__,
- request->serialized_location,
- response->serialized_location,
- attr__, docs__);
+ ? builder->CreateVectorOfStrings(doc_comment)
+ : 0;
+ return reflection::CreateRPCCall(
+ *builder, name__, request->serialized_location,
+ response->serialized_location, attr__, docs__);
}
bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) {
name = call->name()->str();
- if (!DeserializeAttributes(parser, call->attributes()))
- return false;
+ if (!DeserializeAttributes(parser, call->attributes())) return false;
DeserializeDoc(doc_comment, call->documentation());
request = parser.structs_.Lookup(call->request()->name()->str());
response = parser.structs_.Lookup(call->response()->name()->str());
@@ -2915,8 +3313,8 @@ Offset<reflection::Service> ServiceDef::Serialize(FlatBufferBuilder *builder,
auto call__ = builder->CreateVector(servicecall_offsets);
auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments
- ? builder->CreateVectorOfStrings(doc_comment)
- : 0;
+ ? builder->CreateVectorOfStrings(doc_comment)
+ : 0;
return reflection::CreateService(*builder, name__, call__, attr__, docs__);
}
@@ -2933,8 +3331,7 @@ bool ServiceDef::Deserialize(Parser &parser,
}
}
}
- if (!DeserializeAttributes(parser, service->attributes()))
- return false;
+ if (!DeserializeAttributes(parser, service->attributes())) return false;
DeserializeDoc(doc_comment, service->documentation());
return true;
}
@@ -2951,8 +3348,8 @@ Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder,
auto type__ = underlying_type.Serialize(builder);
auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments
- ? builder->CreateVectorOfStrings(doc_comment)
- : 0;
+ ? builder->CreateVectorOfStrings(doc_comment)
+ : 0;
return reflection::CreateEnum(*builder, name__, vals__, is_union, type__,
attr__, docs__);
}
@@ -2971,8 +3368,7 @@ bool EnumDef::Deserialize(Parser &parser, const reflection::Enum *_enum) {
if (!underlying_type.Deserialize(parser, _enum->underlying_type())) {
return false;
}
- if (!DeserializeAttributes(parser, _enum->attributes()))
- return false;
+ if (!DeserializeAttributes(parser, _enum->attributes())) return false;
DeserializeDoc(doc_comment, _enum->documentation());
return true;
}
@@ -2982,9 +3378,10 @@ Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder,
auto name__ = builder->CreateString(name);
auto type__ = union_type.Serialize(builder);
auto docs__ = parser.opts.binary_schema_comments
- ? builder->CreateVectorOfStrings(doc_comment)
- : 0;
- return reflection::CreateEnumVal(*builder, name__, value,
+ ? builder->CreateVectorOfStrings(doc_comment)
+ : 0;
+ return reflection::CreateEnumVal(
+ *builder, name__, value,
union_type.struct_def ? union_type.struct_def->serialized_location : 0,
type__, docs__);
}
@@ -2993,28 +3390,29 @@ bool EnumVal::Deserialize(const Parser &parser,
const reflection::EnumVal *val) {
name = val->name()->str();
value = val->value();
- if (!union_type.Deserialize(parser, val->union_type()))
- return false;
+ if (!union_type.Deserialize(parser, val->union_type())) return false;
DeserializeDoc(doc_comment, val->documentation());
return true;
}
Offset<reflection::Type> Type::Serialize(FlatBufferBuilder *builder) const {
return reflection::CreateType(
- *builder,
- static_cast<reflection::BaseType>(base_type),
+ *builder, static_cast<reflection::BaseType>(base_type),
static_cast<reflection::BaseType>(element),
- struct_def ? struct_def->index : (enum_def ? enum_def->index : -1));
+ struct_def ? struct_def->index : (enum_def ? enum_def->index : -1),
+ fixed_length);
}
bool Type::Deserialize(const Parser &parser, const reflection::Type *type) {
if (type == nullptr) return true;
base_type = static_cast<BaseType>(type->base_type());
element = static_cast<BaseType>(type->element());
+ fixed_length = type->fixed_length();
if (type->index() >= 0) {
+ bool is_series = type->base_type() == reflection::Vector ||
+ type->base_type() == reflection::Array;
if (type->base_type() == reflection::Obj ||
- (type->base_type() == reflection::Vector &&
- type->element() == reflection::Obj)) {
+ (is_series && type->element() == reflection::Obj)) {
if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) {
struct_def = parser.structs_.vec[type->index()];
struct_def->refcount++;
@@ -3055,8 +3453,7 @@ Definition::SerializeAttributes(FlatBufferBuilder *builder,
bool Definition::DeserializeAttributes(
Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) {
- if (attrs == nullptr)
- return true;
+ if (attrs == nullptr) return true;
for (uoffset_t i = 0; i < attrs->size(); ++i) {
auto kv = attrs->Get(i);
auto value = new Value();
@@ -3076,7 +3473,7 @@ bool Definition::DeserializeAttributes(
bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t *>(buf), size);
bool size_prefixed = false;
- if(!reflection::SchemaBufferHasIdentifier(buf)) {
+ if (!reflection::SchemaBufferHasIdentifier(buf)) {
if (!flatbuffers::BufferHasIdentifier(buf, reflection::SchemaIdentifier(),
true))
return false;
@@ -3085,9 +3482,7 @@ bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
}
auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer
: &reflection::VerifySchemaBuffer;
- if (!verify_fn(verifier)) {
- return false;
- }
+ if (!verify_fn(verifier)) { return false; }
auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf)
: reflection::GetSchema(buf);
return Deserialize(schema);
@@ -3103,6 +3498,9 @@ bool Parser::Deserialize(const reflection::Schema *schema) {
for (auto it = schema->objects()->begin(); it != schema->objects()->end();
++it) {
auto struct_def = new StructDef();
+ struct_def->bytesize = it->bytesize();
+ struct_def->fixed = it->is_struct();
+ struct_def->minalign = it->minalign();
if (structs_.Add(it->name()->str(), struct_def)) {
delete struct_def;
return false;
@@ -3133,7 +3531,7 @@ bool Parser::Deserialize(const reflection::Schema *schema) {
auto struct_def = structs_.Lookup(qualified_name);
struct_def->defined_namespace =
GetNamespace(qualified_name, namespaces_, namespaces_index);
- if (!struct_def->Deserialize(*this, * it)) { return false; }
+ if (!struct_def->Deserialize(*this, *it)) { return false; }
if (schema->root_table() == *it) { root_struct_def_ = struct_def; }
}
for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) {
@@ -3205,9 +3603,9 @@ std::string Parser::ConformTo(const Parser &base) {
for (auto evit = enum_def.Vals().begin(); evit != enum_def.Vals().end();
++evit) {
auto &enum_val = **evit;
- auto enum_val_base = enum_def_base->vals.Lookup(enum_val.name);
+ auto enum_val_base = enum_def_base->Lookup(enum_val.name);
if (enum_val_base) {
- if (enum_val.value != enum_val_base->value)
+ if (enum_val != *enum_val_base)
return "values differ for enum: " + enum_val.name;
}
}
diff --git a/src/reflection.cpp b/src/reflection.cpp
index 89ce7838..77ea0dcf 100644
--- a/src/reflection.cpp
+++ b/src/reflection.cpp
@@ -15,6 +15,7 @@
*/
#include "flatbuffers/reflection.h"
+
#include "flatbuffers/util.h"
// Helper functionality for reflection.
@@ -55,7 +56,13 @@ double GetAnyValueF(reflection::BaseType type, const uint8_t *data) {
case reflection::String: {
auto s =
reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data);
- return s ? strtod(s->c_str(), nullptr) : 0.0;
+ if (s) {
+ double d;
+ StringToNumber(s->c_str(), &d);
+ return d;
+ } else {
+ return 0.0;
+ }
}
default: return static_cast<double>(GetAnyValueI(type, data));
}
@@ -148,9 +155,12 @@ void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val) {
void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val) {
switch (type) {
case reflection::Float:
- case reflection::Double:
- SetAnyValueF(type, data, strtod(val, nullptr));
+ case reflection::Double: {
+ double d;
+ StringToNumber(val, &d);
+ SetAnyValueF(type, data, d);
break;
+ }
// TODO: support strings.
default: SetAnyValueI(type, data, StringToInt(val)); break;
}
@@ -431,8 +441,8 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
break;
}
}
- FLATBUFFERS_FALLTHROUGH(); // fall thru
- default: { // Scalars and structs.
+ FLATBUFFERS_FALLTHROUGH(); // fall thru
+ default: { // Scalars and structs.
auto element_size = GetTypeSize(element_base_type);
if (elemobjectdef && elemobjectdef->is_struct())
element_size = elemobjectdef->bytesize();
@@ -466,7 +476,7 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
break;
}
}
- FLATBUFFERS_FALLTHROUGH(); // fall thru
+ FLATBUFFERS_FALLTHROUGH(); // fall thru
case reflection::Union:
case reflection::String:
case reflection::Vector:
@@ -495,9 +505,8 @@ bool VerifyStruct(flatbuffers::Verifier &v,
auto offset = parent_table.GetOptionalFieldOffset(field_offset);
if (required && !offset) { return false; }
- return !offset ||
- v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), offset,
- obj.bytesize());
+ return !offset || v.Verify(reinterpret_cast<const uint8_t *>(&parent_table),
+ offset, obj.bytesize());
}
bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
@@ -515,6 +524,31 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
const reflection::Object &obj,
const flatbuffers::Table *table, bool required);
+bool VerifyUnion(flatbuffers::Verifier &v, const reflection::Schema &schema,
+ uint8_t utype, const uint8_t *elem,
+ const reflection::Field &union_field) {
+ if (!utype) return true; // Not present.
+ auto fb_enum = schema.enums()->Get(union_field.type()->index());
+ if (utype >= fb_enum->values()->size()) return false;
+ auto elem_type = fb_enum->values()->Get(utype)->union_type();
+ switch (elem_type->base_type()) {
+ case reflection::Obj: {
+ auto elem_obj = schema.objects()->Get(elem_type->index());
+ if (elem_obj->is_struct()) {
+ return v.VerifyFromPointer(elem, elem_obj->bytesize());
+ } else {
+ return VerifyObject(v, schema, *elem_obj,
+ reinterpret_cast<const flatbuffers::Table *>(elem),
+ true);
+ }
+ }
+ case reflection::String:
+ return v.VerifyString(
+ reinterpret_cast<const flatbuffers::String *>(elem));
+ default: return false;
+ }
+}
+
bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
const flatbuffers::Table &table,
const reflection::Field &vec_field) {
@@ -522,7 +556,6 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
if (!table.VerifyField<uoffset_t>(v, vec_field.offset())) return false;
switch (vec_field.type()->element()) {
- case reflection::None: FLATBUFFERS_ASSERT(false); break;
case reflection::UType:
return v.VerifyVector(flatbuffers::GetFieldV<uint8_t>(table, vec_field));
case reflection::Bool:
@@ -552,48 +585,52 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
return false;
}
}
- case reflection::Vector: FLATBUFFERS_ASSERT(false); break;
case reflection::Obj: {
auto obj = schema.objects()->Get(vec_field.type()->index());
if (obj->is_struct()) {
- if (!VerifyVectorOfStructs(v, table, vec_field.offset(), *obj,
- vec_field.required())) {
- return false;
- }
+ return VerifyVectorOfStructs(v, table, vec_field.offset(), *obj,
+ vec_field.required());
} else {
auto vec =
flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::Table>>(
table, vec_field);
if (!v.VerifyVector(vec)) return false;
- if (vec) {
- for (uoffset_t j = 0; j < vec->size(); j++) {
- if (!VerifyObject(v, schema, *obj, vec->Get(j), true)) {
- return false;
- }
+ if (!vec) return true;
+ for (uoffset_t j = 0; j < vec->size(); j++) {
+ if (!VerifyObject(v, schema, *obj, vec->Get(j), true)) {
+ return false;
}
}
+ return true;
+ }
+ }
+ case reflection::Union: {
+ auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(
+ table, vec_field);
+ if (!v.VerifyVector(vec)) return false;
+ if (!vec) return true;
+ auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() -
+ sizeof(voffset_t));
+ if (!v.VerifyVector(type_vec)) return false;
+ for (uoffset_t j = 0; j < vec->size(); j++) {
+ // get union type from the prev field
+ auto utype = type_vec->Get(j);
+ auto elem = vec->Get(j);
+ if (!VerifyUnion(v, schema, utype, elem, vec_field)) return false;
}
return true;
}
- case reflection::Union: FLATBUFFERS_ASSERT(false); break;
- default: FLATBUFFERS_ASSERT(false); break;
+ case reflection::Vector:
+ case reflection::None:
+ default: FLATBUFFERS_ASSERT(false); return false;
}
-
- return false;
}
bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
const reflection::Object &obj,
const flatbuffers::Table *table, bool required) {
- if (!table) {
- if (!required)
- return true;
- else
- return false;
- }
-
+ if (!table) return !required;
if (!table->VerifyTableStart(v)) return false;
-
for (uoffset_t i = 0; i < obj.fields()->size(); i++) {
auto field_def = obj.fields()->Get(i);
switch (field_def->type()->base_type()) {
@@ -653,16 +690,9 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
// get union type from the prev field
voffset_t utype_offset = field_def->offset() - sizeof(voffset_t);
auto utype = table->GetField<uint8_t>(utype_offset, 0);
- if (utype != 0) {
- // Means we have this union field present
- auto fb_enum = schema.enums()->Get(field_def->type()->index());
- auto child_obj = fb_enum->values()->Get(utype)->object();
- if (!VerifyObject(v, schema, *child_obj,
- flatbuffers::GetFieldT(*table, *field_def),
- field_def->required())) {
- return false;
- }
- }
+ auto uval = reinterpret_cast<const uint8_t *>(
+ flatbuffers::GetFieldT(*table, *field_def));
+ if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; }
break;
}
default: FLATBUFFERS_ASSERT(false); break;
diff --git a/src/util.cpp b/src/util.cpp
index c1bb1975..08b77918 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -16,6 +16,7 @@
// clang-format off
// Dont't remove `format off`, it prevent reordering of win-includes.
+#define _POSIX_C_SOURCE 200112L // For stat from stat/stat.h and fseeko() (POSIX extensions).
#ifdef _WIN32
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
@@ -23,11 +24,15 @@
# ifndef NOMINMAX
# define NOMINMAX
# endif
+# ifdef _MSC_VER
+# include <crtdbg.h>
+# endif
# include <windows.h> // Must be included before <direct.h>
# include <direct.h>
# include <winbase.h>
# undef interface // This is also important because of reasons
#else
+# define _XOPEN_SOURCE 600 // For PATH_MAX from limits.h (SUSv2 extension)
# include <limits.h>
#endif
// clang-format on
@@ -124,12 +129,12 @@ static const char kPathSeparatorWindows = '\\';
static const char *PathSeparatorSet = "\\/"; // Intentionally no ':'
std::string StripExtension(const std::string &filepath) {
- size_t i = filepath.find_last_of(".");
+ size_t i = filepath.find_last_of('.');
return i != std::string::npos ? filepath.substr(0, i) : filepath;
}
std::string GetExtension(const std::string &filepath) {
- size_t i = filepath.find_last_of(".");
+ size_t i = filepath.find_last_of('.');
return i != std::string::npos ? filepath.substr(i + 1) : "";
}
@@ -235,14 +240,38 @@ bool SetGlobalTestLocale(const char *locale_name, std::string *_value) {
if (_value) *_value = std::string(the_locale);
return true;
}
+
bool ReadEnvironmentVariable(const char *var_name, std::string *_value) {
- #ifdef _MSC_VER
- __pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS
- #endif
+#ifdef _MSC_VER
+ __pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS
+#endif
auto env_str = std::getenv(var_name);
if (!env_str) return false;
if (_value) *_value = std::string(env_str);
return true;
}
+void SetupDefaultCRTReportMode() {
+ // clang-format off
+
+ #ifdef _MSC_VER
+ // By default, send all reports to STDOUT to prevent CI hangs.
+ // Enable assert report box [Abort|Retry|Ignore] if a debugger is present.
+ const int dbg_mode = (_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG) |
+ (IsDebuggerPresent() ? _CRTDBG_MODE_WNDW : 0);
+ (void)dbg_mode; // release mode fix
+ // CrtDebug reports to _CRT_WARN channel.
+ _CrtSetReportMode(_CRT_WARN, dbg_mode);
+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
+ // The assert from <assert.h> reports to _CRT_ERROR channel
+ _CrtSetReportMode(_CRT_ERROR, dbg_mode);
+ _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
+ // Internal CRT assert channel?
+ _CrtSetReportMode(_CRT_ASSERT, dbg_mode);
+ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
+ #endif
+
+ // clang-format on
+}
+
} // namespace flatbuffers
diff --git a/swift/FlatBuffers.podspec b/swift/FlatBuffers.podspec
new file mode 100644
index 00000000..db877878
--- /dev/null
+++ b/swift/FlatBuffers.podspec
@@ -0,0 +1,21 @@
+Pod::Spec.new do |s|
+ s.name = 'FlatBuffers'
+ s.version = '0.2.0'
+ s.summary = 'FlatBuffers: Memory Efficient Serialization Library'
+
+ s.description = "FlatBuffers is a cross platform serialization library architected for
+ maximum memory efficiency. It allows you to directly access serialized
+ data without parsing/unpacking it first, while still having great
+ forwards/backwards compatibility."
+
+ s.homepage = 'https://github.com/google/flatbuffers'
+ s.license = { :type => 'Apache2.0', :file => 'LICENSE' }
+ s.author = { 'mustii' => 'mustii@mmk.one' }
+ s.source = { :git => 'https://github.com/mustiikhalil/flatbuffers.git', :tag => s.version.to_s, :submodules => true }
+
+ s.ios.deployment_target = '11.0'
+ s.osx.deployment_target = '10.14'
+
+ s.swift_version = '5.0'
+ s.source_files = 'Sources/**/*'
+end
diff --git a/NOTICE b/swift/LICENSE
index 6c4f91c6..d6456956 100644
--- a/NOTICE
+++ b/swift/LICENSE
@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright 2014 Google Inc.
+ Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -199,4 +199,4 @@
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
- limitations under the License. \ No newline at end of file
+ limitations under the License.
diff --git a/swift/Package.swift b/swift/Package.swift
new file mode 100644
index 00000000..18bb90a4
--- /dev/null
+++ b/swift/Package.swift
@@ -0,0 +1,22 @@
+// swift-tools-version:5.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "FlatBuffers",
+ platforms: [
+ .iOS(.v11),
+ .macOS(.v10_14),
+ ],
+ products: [
+ .library(
+ name: "FlatBuffers",
+ targets: ["FlatBuffers"]),
+ ],
+ targets: [
+ .target(
+ name: "FlatBuffers",
+ dependencies: []),
+ ]
+)
diff --git a/swift/README.md b/swift/README.md
new file mode 100644
index 00000000..656223dc
--- /dev/null
+++ b/swift/README.md
@@ -0,0 +1,10 @@
+FlatBuffers swift can be found in both SPM
+
+`.package(url: "https://github.com/mustiikhalil/flatbuffers.git", .branch("swift"))`
+
+and Cocoapods
+
+`pod 'FlatBuffers', :git => 'https://github.com/mustiikhalil/flatbuffers.git' :branch => 'swift'`
+
+To report any error please use the main repository.
+
diff --git a/swift/Sources/FlatBuffers/ByteBuffer.swift b/swift/Sources/FlatBuffers/ByteBuffer.swift
new file mode 100644
index 00000000..e468227c
--- /dev/null
+++ b/swift/Sources/FlatBuffers/ByteBuffer.swift
@@ -0,0 +1,273 @@
+import Foundation
+
+public final class ByteBuffer {
+
+ /// pointer to the start of the buffer object in memory
+ private var _memory: UnsafeMutableRawPointer
+ /// The size of the elements written to the buffer + their paddings
+ private var _writerSize: Int = 0
+ /// Capacity of UInt8 the buffer can hold
+ private var _capacity: Int
+
+ /// Aliginment of the current memory being written to the buffer
+ internal var alignment = 1
+ /// Current Index which is being used to write to the buffer, it is written from the end to the start of the buffer
+ internal var writerIndex: Int { return _capacity - _writerSize }
+
+ /// Reader is the position of the current Writer Index (capacity - size)
+ public var reader: Int { return writerIndex }
+ /// Current size of the buffer
+ public var size: UOffset { return UOffset(_writerSize) }
+ /// Public Pointer to the buffer object in memory. This should NOT be modified for any reason
+ public var memory: UnsafeMutableRawPointer { return _memory }
+ /// Current capacity for the buffer
+ public var capacity: Int { return _capacity }
+
+ /// Constructor that creates a Flatbuffer object from a UInt8
+ /// - Parameter bytes: Array of UInt8
+ public init(bytes: [UInt8]) {
+ let ptr = UnsafePointer(bytes)
+ _memory = UnsafeMutableRawPointer.allocate(byteCount: bytes.count, alignment: alignment)
+ _memory.copyMemory(from: ptr, byteCount: bytes.count)
+ _capacity = bytes.count
+ _writerSize = _capacity
+ }
+
+ /// Constructor that creates a Flatbuffer from the Swift Data type object
+ /// - Parameter data: Swift data Object
+ public init(data: Data) {
+ let pointer = UnsafeMutablePointer<UInt8>.allocate(capacity: data.count)
+ data.copyBytes(to: pointer, count: data.count)
+ _memory = UnsafeMutableRawPointer(pointer)
+ _capacity = data.count
+ _writerSize = _capacity
+ }
+
+ /// Constructor that creates a Flatbuffer instance with a size
+ /// - Parameter size: Length of the buffer
+ init(initialSize size: Int) {
+ let size = size.convertToPowerofTwo
+ _memory = UnsafeMutableRawPointer.allocate(byteCount: size, alignment: alignment)
+ _memory.initializeMemory(as: UInt8.self, repeating: 0, count: size)
+ _capacity = size
+ }
+
+#if swift(>=5.0)
+ /// Constructor that creates a Flatbuffer object from a ContiguousBytes
+ /// - Parameters:
+ /// - contiguousBytes: Binary stripe to use as the buffer
+ /// - count: amount of readable bytes
+ public init<Bytes: ContiguousBytes>(
+ contiguousBytes: Bytes,
+ count: Int
+ ) {
+ _memory = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: alignment)
+ _capacity = count
+ _writerSize = _capacity
+ contiguousBytes.withUnsafeBytes { buf in
+ _memory.copyMemory(from: buf.baseAddress!, byteCount: buf.count)
+ }
+ }
+#endif
+
+ /// Creates a copy of the buffer that's being built by calling sizedBuffer
+ /// - Parameters:
+ /// - memory: Current memory of the buffer
+ /// - count: count of bytes
+ internal init(memory: UnsafeMutableRawPointer, count: Int) {
+ _memory = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: alignment)
+ _memory.copyMemory(from: memory, byteCount: count)
+ _capacity = count
+ _writerSize = _capacity
+ }
+
+ /// Creates a copy of the existing flatbuffer, by copying it to a different memory.
+ /// - Parameters:
+ /// - memory: Current memory of the buffer
+ /// - count: count of bytes
+ /// - removeBytes: Removes a number of bytes from the current size
+ internal init(memory: UnsafeMutableRawPointer, count: Int, removing removeBytes: Int) {
+ _memory = UnsafeMutableRawPointer.allocate(byteCount: count, alignment: alignment)
+ _memory.copyMemory(from: memory, byteCount: count)
+ _capacity = count
+ _writerSize = removeBytes
+ }
+
+ deinit { _memory.deallocate() }
+
+ /// Fills the buffer with padding by adding to the writersize
+ /// - Parameter padding: Amount of padding between two to be serialized objects
+ func fill(padding: UInt32) {
+ ensureSpace(size: padding)
+ _writerSize += (MemoryLayout<UInt8>.size * Int(padding))
+ }
+
+ ///Adds an array of type Scalar to the buffer memory
+ /// - Parameter elements: An array of Scalars
+ func push<T: Scalar>(elements: [T]) {
+ let size = elements.count * MemoryLayout<T>.size
+ ensureSpace(size: UInt32(size))
+ elements.lazy.reversed().forEach { (s) in
+ push(value: s, len: MemoryLayout.size(ofValue: s))
+ }
+ }
+
+ /// A custom type of structs that are padded according to the flatbuffer padding,
+ /// - Parameters:
+ /// - value: Pointer to the object in memory
+ /// - size: Size of Value being written to the buffer
+ func push(struct value: UnsafeMutableRawPointer, size: Int) {
+ ensureSpace(size: UInt32(size))
+ memcpy(_memory.advanced(by: writerIndex - size), value, size)
+ defer { value.deallocate() }
+ _writerSize += size
+ }
+
+ /// Adds an object of type Scalar into the buffer
+ /// - Parameters:
+ /// - value: Object that will be written to the buffer
+ /// - len: Offset to subtract from the WriterIndex
+ func push<T: Scalar>(value: T, len: Int) {
+ ensureSpace(size: UInt32(len))
+ var v = value.convertedEndian
+ memcpy(_memory.advanced(by: writerIndex - len), &v, len)
+ _writerSize += len
+ }
+
+ /// Adds a string to the buffer using swift.utf8 object
+ /// - Parameter str: String that will be added to the buffer
+ /// - Parameter len: length of the string
+ func push(string str: String, len: Int) {
+ ensureSpace(size: UInt32(len))
+ if str.utf8.withContiguousStorageIfAvailable({ self.push(bytes: $0, len: len) }) != nil {
+ } else {
+ let utf8View = str.utf8
+ for c in utf8View.lazy.reversed() {
+ push(value: c, len: 1)
+ }
+ }
+ }
+
+ /// Writes a string to Bytebuffer using UTF8View
+ /// - Parameters:
+ /// - bytes: Pointer to the view
+ /// - len: Size of string
+ private func push(bytes: UnsafeBufferPointer<String.UTF8View.Element>, len: Int) -> Bool {
+ _memory.advanced(by: writerIndex - len).copyMemory(from:
+ UnsafeRawPointer(bytes.baseAddress!), byteCount: len)
+ _writerSize += len
+ return true
+ }
+
+ /// Write stores an object into the buffer directly or indirectly.
+ ///
+ /// Direct: ignores the capacity of buffer which would mean we are referring to the direct point in memory
+ /// indirect: takes into respect the current capacity of the buffer (capacity - index), writing to the buffer from the end
+ /// - Parameters:
+ /// - value: Value that needs to be written to the buffer
+ /// - index: index to write to
+ /// - direct: Should take into consideration the capacity of the buffer
+ func write<T>(value: T, index: Int, direct: Bool = false) {
+ var index = index
+ if !direct {
+ index = _capacity - index
+ }
+ _memory.storeBytes(of: value, toByteOffset: index, as: T.self)
+ }
+
+ /// Makes sure that buffer has enouch space for each of the objects that will be written into it
+ /// - Parameter size: size of object
+ @discardableResult
+ func ensureSpace(size: UInt32) -> UInt32 {
+ if Int(size) + _writerSize > _capacity { reallocate(size) }
+ assert(size < FlatBufferMaxSize, "Buffer can't grow beyond 2 Gigabytes")
+ return size
+ }
+
+ /// Reallocates the buffer incase the object to be written doesnt fit in the current buffer
+ /// - Parameter size: Size of the current object
+ fileprivate func reallocate(_ size: UInt32) {
+ let currentWritingIndex = writerIndex
+ while _capacity <= _writerSize + Int(size) {
+ _capacity = _capacity << 1
+ }
+
+ /// solution take from Apple-NIO
+ _capacity = _capacity.convertToPowerofTwo
+
+ let newData = UnsafeMutableRawPointer.allocate(byteCount: _capacity, alignment: alignment)
+ newData.initializeMemory(as: UInt8.self, repeating: 0, count: _capacity)
+ newData
+ .advanced(by: writerIndex)
+ .copyMemory(from: _memory.advanced(by: currentWritingIndex), byteCount: _writerSize)
+ _memory.deallocate()
+ _memory = newData
+ }
+
+ /// Clears the current size of the buffer
+ public func clearSize() {
+ _writerSize = 0
+ }
+
+ /// Clears the current instance of the buffer, replacing it with new memory
+ public func clear() {
+ _writerSize = 0
+ alignment = 1
+ _memory.deallocate()
+ _memory = UnsafeMutableRawPointer.allocate(byteCount: _capacity, alignment: alignment)
+ }
+
+ /// Resizes the buffer size
+ /// - Parameter size: new size for the buffer
+ internal func resize(_ size: Int) {
+ _writerSize = size
+ }
+
+ /// Reads an object from the buffer
+ /// - Parameters:
+ /// - def: Type of the object
+ /// - position: the index of the object in the buffer
+ public func read<T>(def: T.Type, position: Int) -> T {
+ return _memory.advanced(by: position).load(as: T.self)
+ }
+
+ /// Reads a slice from the memory assuming a type of T
+ /// - Parameters:
+ /// - index: index of the object to be read from the buffer
+ /// - count: count of bytes in memory
+ public func readSlice<T>(index: Int32,
+ count: Int32) -> [T] {
+ let start = _memory.advanced(by: Int(index)).assumingMemoryBound(to: T.self)
+ let array = UnsafeBufferPointer(start: start, count: Int(count))
+ return Array(array)
+ }
+
+ /// Reads a string from the buffer and encodes it to a swift string
+ /// - Parameters:
+ /// - index: index of the string in the buffer
+ /// - count: length of the string
+ /// - type: Encoding of the string
+ public func readString(at index: Int32,
+ count: Int32,
+ type: String.Encoding = .utf8) -> String? {
+ let start = _memory.advanced(by: Int(index)).assumingMemoryBound(to: UInt8.self)
+ let bufprt = UnsafeBufferPointer(start: start, count: Int(count))
+ return String(bytes: Array(bufprt), encoding: type)
+ }
+
+ /// Creates a new Flatbuffer object that's duplicated from the current one
+ /// - Parameter removeBytes: the amount of bytes to remove from the current Size
+ public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
+ return ByteBuffer(memory: _memory, count: _capacity, removing: _writerSize - removeBytes)
+ }
+}
+
+extension ByteBuffer: CustomDebugStringConvertible {
+
+ public var debugDescription: String {
+ """
+ buffer located at: \(_memory), with capacity of \(_capacity)
+ { writerSize: \(_writerSize), readerSize: \(reader), writerIndex: \(writerIndex) }
+ """
+ }
+}
diff --git a/swift/Sources/FlatBuffers/Constants.swift b/swift/Sources/FlatBuffers/Constants.swift
new file mode 100644
index 00000000..b17e87c6
--- /dev/null
+++ b/swift/Sources/FlatBuffers/Constants.swift
@@ -0,0 +1,91 @@
+#if os(Linux)
+import CoreFoundation
+#else
+import Foundation
+#endif
+
+/// A boolean to see if the system is littleEndian
+let isLitteEndian = CFByteOrderGetCurrent() == Int(CFByteOrderLittleEndian.rawValue)
+/// Constant for the file id length
+let FileIdLength = 4
+/// Type aliases
+public typealias Byte = UInt8
+public typealias UOffset = UInt32
+public typealias SOffset = Int32
+public typealias VOffset = UInt16
+/// Maximum size for a buffer
+public let FlatBufferMaxSize = UInt32.max << ((MemoryLayout<SOffset>.size * 8 - 1) - 1)
+
+/// Protocol that confirms all the numbers
+///
+/// Scalar is used to confirm all the numbers that can be represented in a FlatBuffer. It's used to write/read from the buffer.
+public protocol Scalar: Equatable {
+ associatedtype NumericValue
+ var convertedEndian: NumericValue { get }
+}
+
+extension Scalar where Self: FixedWidthInteger {
+ /// Converts the value from BigEndian to LittleEndian
+ ///
+ /// Converts values to little endian on machines that work with BigEndian, however this is NOT TESTED yet.
+ public var convertedEndian: NumericValue {
+ if isLitteEndian { return self as! Self.NumericValue }
+ fatalError("This is not tested! please report an issue on the offical flatbuffers repo")
+ }
+}
+
+extension Double: Scalar {
+ public typealias NumericValue = UInt64
+
+ public var convertedEndian: UInt64 {
+ if isLitteEndian { return self.bitPattern }
+ return self.bitPattern.littleEndian
+ }
+}
+
+extension Float32: Scalar {
+ public typealias NumericValue = UInt32
+
+ public var convertedEndian: UInt32 {
+ if isLitteEndian { return self.bitPattern }
+ return self.bitPattern.littleEndian
+ }
+}
+
+extension Int: Scalar {
+ public typealias NumericValue = Int
+}
+
+extension Int8: Scalar {
+ public typealias NumericValue = Int8
+}
+
+extension Int16: Scalar {
+ public typealias NumericValue = Int16
+}
+
+extension Int32: Scalar {
+ public typealias NumericValue = Int32
+}
+
+extension Int64: Scalar {
+ public typealias NumericValue = Int64
+}
+
+extension UInt8: Scalar {
+ public typealias NumericValue = UInt8
+}
+
+extension UInt16: Scalar {
+ public typealias NumericValue = UInt16
+}
+
+extension UInt32: Scalar {
+ public typealias NumericValue = UInt32
+}
+
+extension UInt64: Scalar {
+ public typealias NumericValue = UInt64
+}
+
+public func FlatBuffersVersion_1_12_0() {}
diff --git a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
new file mode 100644
index 00000000..8afa7596
--- /dev/null
+++ b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
@@ -0,0 +1,492 @@
+import Foundation
+
+public final class FlatBufferBuilder {
+
+ /// Vtables used in the buffer are stored in here, so they would be written later in EndTable
+ private var _vtable: [UInt32] = []
+ /// Reference Vtables that were already written to the buffer
+ private var _vtables: [UOffset] = []
+ /// Flatbuffer data will be written into
+ private var _bb: ByteBuffer
+ /// A check if the buffer is being written into by a different table
+ private var isNested = false
+ /// Dictonary that stores a map of all the strings that were written to the buffer
+ private var stringOffsetMap: [String: Offset<String>] = [:]
+ /// A check to see if finish(::) was ever called to retreive data object
+ private var finished = false
+ /// A check to see if the buffer should serialize Default values
+ private var serializeDefaults: Bool
+
+ /// Current alignment for the buffer
+ var _minAlignment: Int = 0 {
+ didSet {
+ _bb.alignment = _minAlignment
+ }
+ }
+
+ /// Gives a read access to the buffer's size
+ public var size: UOffset { return _bb.size }
+ /// Data representation of the buffer
+ public var data: Data {
+ assert(finished, "Data shouldn't be called before finish()")
+ return Data(bytes: _bb.memory.advanced(by: _bb.writerIndex),
+ count: _bb.capacity - _bb.writerIndex)
+ }
+ /// Get's the fully sized buffer stored in memory
+ public var fullSizedByteArray: [UInt8] {
+ let ptr = UnsafeBufferPointer(start: _bb.memory.assumingMemoryBound(to: UInt8.self),
+ count: _bb.capacity)
+ return Array(ptr)
+ }
+ /// Returns the written size of the buffer
+ public var sizedByteArray: [UInt8] {
+ let cp = _bb.capacity - _bb.writerIndex
+ let start = _bb.memory.advanced(by: _bb.writerIndex)
+ .bindMemory(to: UInt8.self, capacity: cp)
+
+ let ptr = UnsafeBufferPointer(start: start, count: cp)
+ return Array(ptr)
+ }
+ /// Returns the buffer
+ public var buffer: ByteBuffer { return _bb }
+
+ /// Returns A sized Buffer from the readable bytes
+ public var sizedBuffer: ByteBuffer {
+ assert(finished, "Data shouldn't be called before finish()")
+ return ByteBuffer(memory: _bb.memory.advanced(by: _bb.reader), count: _bb.reader)
+ }
+
+ // MARK: - Init
+
+ /// initialize the buffer with a size
+ /// - Parameters:
+ /// - initialSize: Initial size for the buffer
+ /// - force: Allows default to be serialized into the buffer
+ public init(initialSize: Int32 = 1024, serializeDefaults force: Bool = false) {
+ assert(initialSize > 0, "Size should be greater than zero!")
+ guard isLitteEndian else {
+ fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
+ }
+ serializeDefaults = force
+ _bb = ByteBuffer(initialSize: Int(initialSize))
+ }
+
+ /// Clears the buffer and the builder from it's data
+ public func clear() {
+ _minAlignment = 0
+ isNested = false
+ _bb.clear()
+ stringOffsetMap = [:]
+ }
+
+ /// Removes all the offsets from the VTable
+ public func clearOffsets() {
+ _vtable = []
+ }
+
+ // MARK: - Create Tables
+
+ /// Checks if the required fields were serialized into the buffer
+ /// - Parameters:
+ /// - table: offset for the table
+ /// - fields: Array of all the important fields to be serialized
+ public func require(table: Offset<UOffset>, fields: [Int32]) {
+ for field in fields {
+ let start = _bb.capacity - Int(table.o)
+ let startTable = start - Int(_bb.read(def: Int32.self, position: start))
+ let isOkay = _bb.read(def: VOffset.self, position: startTable + Int(field)) != 0
+ assert(isOkay, "Flatbuffers requires the following field")
+ }
+ }
+
+ /// Finished the buffer by adding the file id and then calling finish
+ /// - Parameters:
+ /// - offset: Offset of the table
+ /// - fileId: Takes the fileId
+ /// - prefix: if false it wont add the size of the buffer
+ public func finish<T>(offset: Offset<T>, fileId: String, addPrefix prefix: Bool = false) {
+ let size = MemoryLayout<UOffset>.size
+ preAlign(len: size + (prefix ? size : 0) + FileIdLength, alignment: _minAlignment)
+ assert(fileId.count == FileIdLength, "Flatbuffers requires file id to be 4")
+ _bb.push(string: fileId, len: 4)
+ finish(offset: offset, addPrefix: prefix)
+ }
+
+ /// Finished the buffer by adding the file id, offset, and prefix to it.
+ /// - Parameters:
+ /// - offset: Offset of the table
+ /// - prefix: if false it wont add the size of the buffer
+ public func finish<T>(offset: Offset<T>, addPrefix prefix: Bool = false) {
+ notNested()
+ let size = MemoryLayout<UOffset>.size
+ preAlign(len: size + (prefix ? size : 0), alignment: _minAlignment)
+ push(element: refer(to: offset.o))
+ if prefix { push(element: _bb.size) }
+ clearOffsets()
+ finished = true
+ }
+
+ /// starttable will let the builder know, that a new object is being serialized.
+ ///
+ /// The function will fatalerror if called while there is another object being serialized
+ /// - Parameter numOfFields: Number of elements to be written to the buffer
+ public func startTable(with numOfFields: Int) -> UOffset {
+ notNested()
+ isNested = true
+ _vtable = [UInt32](repeating: 0, count: numOfFields)
+ return _bb.size
+ }
+
+
+ /// Endtable will let the builder know that the object that's written to it is completed
+ ///
+ /// This would be called after all the elements are serialized, it will add the vtable into the buffer.
+ /// it will fatalError in case the object is called without starttable, or the object has exceeded the limit of
+ /// 2GB,
+ /// - Parameter startOffset:Start point of the object written
+ /// - returns: The root of the table
+ public func endTable(at startOffset: UOffset) -> UOffset {
+ assert(isNested, "Calling endtable without calling starttable")
+ let sizeofVoffset = MemoryLayout<VOffset>.size
+ let vTableOffset = push(element: SOffset(0))
+
+ let tableObjectSize = vTableOffset - startOffset
+ assert(tableObjectSize < 0x10000, "Buffer can't grow beyond 2 Gigabytes")
+
+ var writeIndex = 0
+ for (index,j) in _vtable.lazy.reversed().enumerated() {
+ if j != 0 {
+ writeIndex = _vtable.count - index
+ break
+ }
+ }
+
+ for i in stride(from: writeIndex - 1, to: -1, by: -1) {
+ let off = _vtable[i] == 0 ? 0 : vTableOffset - _vtable[i]
+ _bb.push(value: VOffset(off), len: sizeofVoffset)
+ }
+
+ _bb.push(value: VOffset(tableObjectSize), len: sizeofVoffset)
+ _bb.push(value: (UInt16(writeIndex + 2) * UInt16(sizeofVoffset)), len: sizeofVoffset)
+
+ clearOffsets()
+ let vt_use = _bb.size
+
+ var isAlreadyAdded: Int?
+
+ let vt2 = _bb.memory.advanced(by: _bb.writerIndex)
+ let len2 = vt2.load(fromByteOffset: 0, as: Int16.self)
+
+ for table in _vtables {
+ let position = _bb.capacity - Int(table)
+ let vt1 = _bb.memory.advanced(by: position)
+ let len1 = _bb.read(def: Int16.self, position: position)
+ if (len2 != len1 || 0 != memcmp(vt1, vt2, Int(len2))) { continue }
+
+ isAlreadyAdded = Int(table)
+ break
+ }
+
+ if let offset = isAlreadyAdded {
+ let vTableOff = Int(vTableOffset)
+ let space = _bb.capacity - vTableOff
+ _bb.write(value: Int32(offset - vTableOff), index: space, direct: true)
+ _bb.resize(_bb.capacity - space)
+ } else {
+ _bb.write(value: Int32(vt_use) - Int32(vTableOffset), index: Int(vTableOffset))
+ _vtables.append(_bb.size)
+ }
+ isNested = false
+ return vTableOffset
+ }
+
+ // MARK: - Builds Buffer
+
+ /// asserts to see if the object is not nested
+ fileprivate func notNested() {
+ assert(!isNested, "Object serialization must not be nested")
+ }
+
+ /// Changes the minimuim alignment of the buffer
+ /// - Parameter size: size of the current alignment
+ fileprivate func minAlignment(size: Int) {
+ if size > _minAlignment {
+ _minAlignment = size
+ }
+ }
+
+ /// Gets the padding for the current element
+ /// - Parameters:
+ /// - bufSize: Current size of the buffer + the offset of the object to be written
+ /// - elementSize: Element size
+ fileprivate func padding(bufSize: UInt32, elementSize: UInt32) -> UInt32 {
+ ((~bufSize) &+ 1) & (elementSize - 1)
+ }
+
+ /// Prealigns the buffer before writting a new object into the buffer
+ /// - Parameters:
+ /// - len:Length of the object
+ /// - alignment: Alignment type
+ fileprivate func preAlign(len: Int, alignment: Int) {
+ minAlignment(size: alignment)
+ _bb.fill(padding: padding(bufSize: _bb.size + UOffset(len), elementSize: UOffset(alignment)))
+ }
+
+ /// Prealigns the buffer before writting a new object into the buffer
+ /// - Parameters:
+ /// - len: Length of the object
+ /// - type: Type of the object to be written
+ fileprivate func preAlign<T: Scalar>(len: Int, type: T.Type) {
+ preAlign(len: len, alignment: MemoryLayout<T>.size)
+ }
+
+ /// Refers to an object that's written in the buffer
+ /// - Parameter off: the objects index value
+ fileprivate func refer(to off: UOffset) -> UOffset {
+ let size = MemoryLayout<UOffset>.size
+ preAlign(len: size, alignment: size)
+ return _bb.size - off + UInt32(size)
+ }
+
+ /// Tracks the elements written into the buffer
+ /// - Parameters:
+ /// - offset: The offset of the element witten
+ /// - position: The position of the element
+ fileprivate func track(offset: UOffset, at position: VOffset) {
+ _vtable[Int(position)] = offset
+ }
+
+ // MARK: - Vectors
+
+ /// Starts a vector of length and Element size
+ public func startVector(_ len: Int, elementSize: Int) {
+ notNested()
+ isNested = true
+ preAlign(len: len * elementSize, type: UOffset.self)
+ preAlign(len: len * elementSize, alignment: elementSize)
+ }
+
+ /// Ends the vector of at length
+ ///
+ /// The current function will fatalError if startVector is called before serializing the vector
+ /// - Parameter len: Length of the buffer
+ public func endVector(len: Int) -> UOffset {
+ assert(isNested, "Calling endVector without calling startVector")
+ isNested = false
+ return push(element: Int32(len))
+ }
+
+ /// Creates a vector of type Scalar in the buffer
+ /// - Parameter elements: elements to be written into the buffer
+ /// - returns: Offset of the vector
+ public func createVector<T: Scalar>(_ elements: [T]) -> Offset<UOffset> {
+ return createVector(elements, size: elements.count)
+ }
+
+ /// Creates a vector of type Scalar in the buffer
+ /// - Parameter elements: Elements to be written into the buffer
+ /// - Parameter size: Count of elements
+ /// - returns: Offset of the vector
+ public func createVector<T: Scalar>(_ elements: [T], size: Int) -> Offset<UOffset> {
+ let size = size
+ startVector(size, elementSize: MemoryLayout<T>.size)
+ _bb.push(elements: elements)
+ return Offset(offset: endVector(len: size))
+ }
+
+ /// Creates a vector of type Enums in the buffer
+ /// - Parameter elements: elements to be written into the buffer
+ /// - returns: Offset of the vector
+ public func createVector<T: Enum>(_ elements: [T]) -> Offset<UOffset> {
+ return createVector(elements, size: elements.count)
+ }
+
+ /// Creates a vector of type Enums in the buffer
+ /// - Parameter elements: Elements to be written into the buffer
+ /// - Parameter size: Count of elements
+ /// - returns: Offset of the vector
+ public func createVector<T: Enum>(_ elements: [T], size: Int) -> Offset<UOffset> {
+ let size = size
+ startVector(size, elementSize: T.byteSize)
+ for e in elements.lazy.reversed() {
+ _bb.push(value: e.value, len: T.byteSize)
+ }
+ return Offset(offset: endVector(len: size))
+ }
+
+ /// Creates a vector of type Offsets in the buffer
+ /// - Parameter offsets:Array of offsets of type T
+ /// - returns: Offset of the vector
+ public func createVector<T>(ofOffsets offsets: [Offset<T>]) -> Offset<UOffset> {
+ createVector(ofOffsets: offsets, len: offsets.count)
+ }
+
+ /// Creates a vector of type Offsets in the buffer
+ /// - Parameter elements: Array of offsets of type T
+ /// - Parameter size: Count of elements
+ /// - returns: Offset of the vector
+ public func createVector<T>(ofOffsets offsets: [Offset<T>], len: Int) -> Offset<UOffset> {
+ startVector(len, elementSize: MemoryLayout<Offset<T>>.size)
+ for o in offsets.lazy.reversed() {
+ push(element: o)
+ }
+ return Offset(offset: endVector(len: len))
+ }
+
+ /// Creates a vector of Strings
+ /// - Parameter str: a vector of strings that will be written into the buffer
+ /// - returns: Offset of the vector
+ public func createVector(ofStrings str: [String]) -> Offset<UOffset> {
+ var offsets: [Offset<String>] = []
+ for s in str {
+ offsets.append(create(string: s))
+ }
+ return createVector(ofOffsets: offsets)
+ }
+
+ /// Creates a vector of Flatbuffer structs.
+ ///
+ /// The function takes a Type to know what size it is, and alignment
+ /// - Parameters:
+ /// - structs: An array of UnsafeMutableRawPointer
+ /// - type: Type of the struct being written
+ /// - returns: Offset of the vector
+ public func createVector<T: Readable>(structs: [UnsafeMutableRawPointer],
+ type: T.Type) -> Offset<UOffset> {
+ startVector(structs.count * T.size, elementSize: T.alignment)
+ for i in structs.lazy.reversed() {
+ create(struct: i, type: T.self)
+ }
+ return Offset(offset: endVector(len: structs.count))
+ }
+
+ // MARK: - Inserting Structs
+
+ /// Writes a Flatbuffer struct into the buffer
+ /// - Parameters:
+ /// - s: Flatbuffer struct
+ /// - type: Type of the element to be serialized
+ /// - returns: Offset of the Object
+ @discardableResult
+ public func create<T: Readable>(struct s: UnsafeMutableRawPointer,
+ type: T.Type) -> Offset<UOffset> {
+ let size = T.size
+ preAlign(len: size, alignment: T.alignment)
+ _bb.push(struct: s, size: size)
+ return Offset(offset: _bb.size)
+ }
+
+ /// Adds the offset of a struct into the vTable
+ ///
+ /// The function fatalErrors if we pass an offset that is out of range
+ /// - Parameter o: offset
+ public func add(structOffset o: UOffset) {
+ guard Int(o) < _vtable.count else { fatalError("Out of the table range") }
+ _vtable[Int(o)] = _bb.size
+ }
+
+ // MARK: - Inserting Strings
+
+ /// Insets a string into the buffer using UTF8
+ /// - Parameter str: String to be serialized
+ /// - returns: The strings offset in the buffer
+ public func create(string str: String) -> Offset<String> {
+ let len = str.count
+ notNested()
+ preAlign(len: len + 1, type: UOffset.self)
+ _bb.fill(padding: 1)
+ _bb.push(string: str, len: len)
+ push(element: UOffset(len))
+ return Offset(offset: _bb.size)
+ }
+
+ /// Inserts a shared string to the buffer
+ ///
+ /// The function checks the stringOffsetmap if it's seen a similar string before
+ /// - Parameter str: String to be serialized
+ /// - returns: The strings offset in the buffer
+ public func createShared(string str: String) -> Offset<String> {
+ if let offset = stringOffsetMap[str] {
+ return offset
+ }
+ let offset = create(string: str)
+ stringOffsetMap[str] = offset
+ return offset
+ }
+
+ // MARK: - Inseting offsets
+
+ /// Adds the offset of an object into the buffer
+ /// - Parameters:
+ /// - offset: Offset of another object to be written
+ /// - position: The predefined position of the object
+ public func add<T>(offset: Offset<T>, at position: VOffset) {
+ if offset.isEmpty {
+ track(offset: 0, at: position)
+ return
+ }
+ add(element: refer(to: offset.o), def: 0, at: position)
+ }
+
+ /// Pushes a value of type offset into the buffer
+ /// - Parameter o: Offset
+ /// - returns: Position of the offset
+ @discardableResult
+ public func push<T>(element o: Offset<T>) -> UOffset {
+ push(element: refer(to: o.o))
+ }
+
+ // MARK: - Inserting Scalars to Buffer
+
+ /// Adds a value into the buffer of type Scalar
+ ///
+ /// - Parameters:
+ /// - element: Element to insert
+ /// - def: Default value for that element
+ /// - position: The predefined position of the element
+ public func add<T: Scalar>(element: T, def: T, at position: VOffset) {
+ if (element == def && !serializeDefaults) {
+ track(offset: 0, at: position)
+ return
+ }
+ let off = push(element: element)
+ track(offset: off, at: position)
+ }
+
+ /// Adds Boolean values into the buffer
+ /// - Parameters:
+ /// - condition: Condition to insert
+ /// - def: Default condition
+ /// - position: The predefined position of the element
+ public func add(condition: Bool, def: Bool, at position: VOffset) {
+ if (condition == def && !serializeDefaults) {
+ track(offset: 0, at: position)
+ return
+ }
+ let off = push(element: Byte(condition ? 1 : 0))
+ track(offset: off, at: position)
+ }
+
+ /// Pushes the values into the buffer
+ /// - Parameter element: Element to insert
+ /// - returns: Postion of the Element
+ @discardableResult
+ public func push<T: Scalar>(element: T) -> UOffset {
+ preAlign(len: MemoryLayout<T>.size,
+ alignment: MemoryLayout<T>.size)
+ _bb.push(value: element, len: MemoryLayout<T>.size)
+ return _bb.size
+ }
+}
+
+extension FlatBufferBuilder: CustomDebugStringConvertible {
+
+ public var debugDescription: String {
+ """
+ buffer debug:
+ \(_bb)
+ builder debug:
+ { finished: \(finished), serializeDefaults: \(serializeDefaults), isNested: \(isNested) }
+ """
+ }
+}
diff --git a/swift/Sources/FlatBuffers/FlatBufferObject.swift b/swift/Sources/FlatBuffers/FlatBufferObject.swift
new file mode 100644
index 00000000..a247b142
--- /dev/null
+++ b/swift/Sources/FlatBuffers/FlatBufferObject.swift
@@ -0,0 +1,88 @@
+import Foundation
+
+/// FlatbufferObject structures all the Flatbuffers objects
+public protocol FlatBufferObject {
+ var __buffer: ByteBuffer! { get }
+ init(_ bb: ByteBuffer, o: Int32)
+}
+
+/// Readable is structures all the Flatbuffers structs
+///
+/// Readable is a procotol that each Flatbuffer struct should confirm to since
+/// FlatBufferBuilder would require a Type to both create(struct:) and createVector(structs:) functions
+public protocol Readable: FlatBufferObject {
+ static var size: Int { get }
+ static var alignment: Int { get }
+}
+
+public protocol Enum {
+ associatedtype T: Scalar
+ static var byteSize: Int { get }
+ var value: T { get }
+}
+
+/// Mutable is a protocol that allows us to mutate Scalar values within the buffer
+public protocol Mutable {
+ /// makes Flatbuffer accessed within the Protocol
+ var bb: ByteBuffer { get }
+ /// makes position of the table/struct accessed within the Protocol
+ var postion: Int32 { get }
+}
+
+extension Mutable {
+
+ /// Mutates the memory in the buffer, this is only called from the access function of table and structs
+ /// - Parameters:
+ /// - value: New value to be inserted to the buffer
+ /// - index: index of the Element
+ func mutate<T: Scalar>(value: T, o: Int32) -> Bool {
+ guard o != 0 else { return false }
+ bb.write(value: value, index: Int(o), direct: true)
+ return true
+ }
+}
+
+extension Mutable where Self == Table {
+
+ /// Mutates a value by calling mutate with respect to the position in the table
+ /// - Parameters:
+ /// - value: New value to be inserted to the buffer
+ /// - index: index of the Element
+ public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
+ guard index != 0 else { return false }
+ return mutate(value: value, o: index + postion)
+ }
+
+ /// Directly mutates the element by calling mutate
+ ///
+ /// Mutates the Element at index ignoring the current position by calling mutate
+ /// - Parameters:
+ /// - value: New value to be inserted to the buffer
+ /// - index: index of the Element
+ public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
+ return mutate(value: value, o: index)
+ }
+}
+
+extension Mutable where Self == Struct {
+
+ /// Mutates a value by calling mutate with respect to the position in the struct
+ /// - Parameters:
+ /// - value: New value to be inserted to the buffer
+ /// - index: index of the Element
+ public func mutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
+ return mutate(value: value, o: index + postion)
+ }
+
+ /// Directly mutates the element by calling mutate
+ ///
+ /// Mutates the Element at index ignoring the current position by calling mutate
+ /// - Parameters:
+ /// - value: New value to be inserted to the buffer
+ /// - index: index of the Element
+ public func directMutate<T: Scalar>(_ value: T, index: Int32) -> Bool {
+ return mutate(value: value, o: index)
+ }
+}
+extension Struct: Mutable {}
+extension Table: Mutable {}
diff --git a/swift/Sources/FlatBuffers/FlatBuffersUtils.swift b/swift/Sources/FlatBuffers/FlatBuffersUtils.swift
new file mode 100644
index 00000000..6838f862
--- /dev/null
+++ b/swift/Sources/FlatBuffers/FlatBuffersUtils.swift
@@ -0,0 +1,16 @@
+import Foundation
+
+public final class FlatBuffersUtils {
+
+ /// Gets the size of the prefix
+ /// - Parameter bb: Flatbuffer object
+ public static func getSizePrefix(bb: ByteBuffer) -> Int32 {
+ return bb.read(def: Int32.self, position: bb.reader)
+ }
+
+ /// Removes the prefix by duplicating the Flatbuffer
+ /// - Parameter bb: Flatbuffer object
+ public static func removeSizePrefix(bb: ByteBuffer) -> ByteBuffer {
+ return bb.duplicate(removing: MemoryLayout<Int32>.size)
+ }
+}
diff --git a/swift/Sources/FlatBuffers/Int+extension.swift b/swift/Sources/FlatBuffers/Int+extension.swift
new file mode 100644
index 00000000..e52bdab6
--- /dev/null
+++ b/swift/Sources/FlatBuffers/Int+extension.swift
@@ -0,0 +1,31 @@
+import Foundation
+
+extension Int {
+
+ /// Moves the current int into the nearest power of two
+ ///
+ /// This is used since the UnsafeMutableRawPointer will face issues when writing/reading
+ /// if the buffer alignment exceeds that actual size of the buffer
+ var convertToPowerofTwo: Int {
+ guard self > 0 else { return 1 }
+ var n = UOffset(self)
+
+ #if arch(arm) || arch(i386)
+ let max = UInt32(Int.max)
+ #else
+ let max = UInt32.max
+ #endif
+
+ n -= 1
+ n |= n >> 1
+ n |= n >> 2
+ n |= n >> 4
+ n |= n >> 8
+ n |= n >> 16
+ if n != max {
+ n += 1
+ }
+
+ return Int(n)
+ }
+}
diff --git a/swift/Sources/FlatBuffers/Message.swift b/swift/Sources/FlatBuffers/Message.swift
new file mode 100644
index 00000000..590d3d7f
--- /dev/null
+++ b/swift/Sources/FlatBuffers/Message.swift
@@ -0,0 +1,41 @@
+public protocol FlatBufferGRPCMessage {
+
+ /// Raw pointer which would be pointing to the beginning of the readable bytes
+ var rawPointer: UnsafeMutableRawPointer { get }
+
+ /// Size of readable bytes in the buffer
+ var size: Int { get }
+
+ init(byteBuffer: ByteBuffer)
+}
+
+/// Message is a wrapper around Buffers to to able to send Flatbuffers `Buffers` through the
+/// GRPC library
+public final class Message<T: FlatBufferObject>: FlatBufferGRPCMessage {
+ internal var buffer: ByteBuffer
+
+ /// Returns the an object of type T that would be read from the buffer
+ public var object: T {
+ T.init(buffer, o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) + Int32(buffer.reader))
+ }
+
+ public var rawPointer: UnsafeMutableRawPointer { return buffer.memory.advanced(by: buffer.reader) }
+
+ public var size: Int { return Int(buffer.size) }
+
+ /// Initializes the message with the type Flatbuffer.Bytebuffer that is transmitted over
+ /// GRPC
+ /// - Parameter byteBuffer: Flatbuffer ByteBuffer object
+ public init(byteBuffer: ByteBuffer) {
+ buffer = byteBuffer
+ }
+
+ /// Initializes the message by copying the buffer to the message to be sent.
+ /// from the builder
+ /// - Parameter builder: FlatbufferBuilder that has the bytes created in
+ /// - Note: Use `builder.finish(offset)` before passing the builder without prefixing anything to it
+ public init(builder: inout FlatBufferBuilder) {
+ buffer = builder.sizedBuffer
+ builder.clear()
+ }
+}
diff --git a/swift/Sources/FlatBuffers/Offset.swift b/swift/Sources/FlatBuffers/Offset.swift
new file mode 100644
index 00000000..cdb02278
--- /dev/null
+++ b/swift/Sources/FlatBuffers/Offset.swift
@@ -0,0 +1,12 @@
+import Foundation
+
+/// Offset object for all the Objects that are written into the buffer
+public struct Offset<T> {
+ /// Offset of the object in the buffer
+ public var o: UOffset
+ /// Returns false if the offset is equal to zero
+ public var isEmpty: Bool { return o == 0 }
+
+ public init(offset: UOffset) { o = offset }
+ public init() { o = 0 }
+}
diff --git a/swift/Sources/FlatBuffers/Struct.swift b/swift/Sources/FlatBuffers/Struct.swift
new file mode 100644
index 00000000..88e3a41a
--- /dev/null
+++ b/swift/Sources/FlatBuffers/Struct.swift
@@ -0,0 +1,16 @@
+import Foundation
+
+public struct Struct {
+ public private(set) var bb: ByteBuffer
+ public private(set) var postion: Int32
+
+ public init(bb: ByteBuffer, position: Int32 = 0) {
+ self.bb = bb
+ self.postion = position
+ }
+
+ public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
+ let r = bb.read(def: T.self, position: Int(o + postion))
+ return r
+ }
+}
diff --git a/swift/Sources/FlatBuffers/Table.swift b/swift/Sources/FlatBuffers/Table.swift
new file mode 100644
index 00000000..0f783bfe
--- /dev/null
+++ b/swift/Sources/FlatBuffers/Table.swift
@@ -0,0 +1,144 @@
+import Foundation
+
+public struct Table {
+ public private(set) var bb: ByteBuffer
+ public private(set) var postion: Int32
+
+ public init(bb: ByteBuffer, position: Int32 = 0) {
+ guard isLitteEndian else {
+ fatalError("Reading/Writing a buffer in big endian machine is not supported on swift")
+ }
+ self.bb = bb
+ self.postion = position
+ }
+
+ public func offset(_ o: Int32) -> Int32 {
+ let vtable = postion - bb.read(def: Int32.self, position: Int(postion))
+ return o < bb.read(def: VOffset.self, position: Int(vtable)) ? Int32(bb.read(def: Int16.self, position: Int(vtable + o))) : 0
+ }
+
+ public func indirect(_ o: Int32) -> Int32 { return o + bb.read(def: Int32.self, position: Int(o)) }
+
+ /// String reads from the buffer with respect to position of the current table.
+ /// - Parameter offset: Offset of the string
+ public func string(at offset: Int32) -> String? {
+ return directString(at: offset + postion)
+ }
+
+ /// Direct string reads from the buffer disregarding the position of the table.
+ /// It would be preferable to use string unless the current position of the table is not needed
+ /// - Parameter offset: Offset of the string
+ public func directString(at offset: Int32) -> String? {
+ var offset = offset
+ offset += bb.read(def: Int32.self, position: Int(offset))
+ let count = bb.read(def: Int32.self, position: Int(offset))
+ let position = offset + Int32(MemoryLayout<Int32>.size)
+ return bb.readString(at: position, count: count)
+ }
+
+ /// Reads from the buffer with respect to the position in the table.
+ /// - Parameters:
+ /// - type: Type of Scalar that needs to be read from the buffer
+ /// - o: Offset of the Element
+ public func readBuffer<T: Scalar>(of type: T.Type, at o: Int32) -> T {
+ return directRead(of: T.self, offset: o + postion)
+ }
+
+ /// Reads from the buffer disregarding the position of the table.
+ /// It would be used when reading from an
+ /// ```
+ /// let offset = __t.offset(10)
+ /// //Only used when the we already know what is the
+ /// // position in the table since __t.vector(at:)
+ /// // returns the index with respect to the position
+ /// __t.directRead(of: Byte.self,
+ /// offset: __t.vector(at: offset) + index * 1)
+ /// ```
+ /// - Parameters:
+ /// - type: Type of Scalar that needs to be read from the buffer
+ /// - o: Offset of the Element
+ public func directRead<T: Scalar>(of type: T.Type, offset o: Int32) -> T {
+ let r = bb.read(def: T.self, position: Int(o))
+ return r
+ }
+
+ public func union<T: FlatBufferObject>(_ o: Int32) -> T {
+ let o = o + postion
+ return directUnion(o)
+ }
+
+ public func directUnion<T: FlatBufferObject>(_ o: Int32) -> T {
+ return T.init(bb, o: o + bb.read(def: Int32.self, position: Int(o)))
+ }
+
+ public func getVector<T>(at off: Int32) -> [T]? {
+ let o = offset(off)
+ guard o != 0 else { return nil }
+ return bb.readSlice(index: vector(at: o), count: vector(count: o))
+ }
+
+ /// Vector count gets the count of Elements within the array
+ /// - Parameter o: start offset of the vector
+ /// - returns: Count of elements
+ public func vector(count o: Int32) -> Int32 {
+ var o = o
+ o += postion
+ o += bb.read(def: Int32.self, position: Int(o))
+ return bb.read(def: Int32.self, position: Int(o))
+ }
+
+ /// Vector start index in the buffer
+ /// - Parameter o:start offset of the vector
+ /// - returns: the start index of the vector
+ public func vector(at o: Int32) -> Int32 {
+ var o = o
+ o += postion
+ return o + bb.read(def: Int32.self, position: Int(o)) + 4
+ }
+}
+
+extension Table {
+
+ static public func indirect(_ o: Int32, _ fbb: ByteBuffer) -> Int32 { return o + fbb.read(def: Int32.self, position: Int(o)) }
+
+ static public func offset(_ o: Int32, vOffset: Int32, fbb: ByteBuffer) -> Int32 {
+ let vTable = Int32(fbb.capacity) - o
+ return vTable + Int32(fbb.read(def: Int16.self, position: Int(vTable + vOffset - fbb.read(def: Int32.self, position: Int(vTable)))))
+ }
+
+ static public func compare(_ off1: Int32, _ off2: Int32, fbb: ByteBuffer) -> Int32 {
+ let memorySize = Int32(MemoryLayout<Int32>.size)
+ let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
+ let _off2 = off2 + fbb.read(def: Int32.self, position: Int(off2))
+ let len1 = fbb.read(def: Int32.self, position: Int(_off1))
+ let len2 = fbb.read(def: Int32.self, position: Int(_off2))
+ let startPos1 = _off1 + memorySize
+ let startPos2 = _off2 + memorySize
+ let minValue = min(len1, len2)
+ for i in 0...minValue {
+ let b1 = fbb.read(def: Int8.self, position: Int(i + startPos1))
+ let b2 = fbb.read(def: Int8.self, position: Int(i + startPos2))
+ if b1 != b2 {
+ return Int32(b2 - b1)
+ }
+ }
+ return len1 - len2
+ }
+
+ static public func compare(_ off1: Int32, _ key: [Byte], fbb: ByteBuffer) -> Int32 {
+ let memorySize = Int32(MemoryLayout<Int32>.size)
+ let _off1 = off1 + fbb.read(def: Int32.self, position: Int(off1))
+ let len1 = fbb.read(def: Int32.self, position: Int(_off1))
+ let len2 = Int32(key.count)
+ let startPos1 = _off1 + memorySize
+ let minValue = min(len1, len2)
+ for i in 0..<minValue {
+ let b = fbb.read(def: Int8.self, position: Int(i + startPos1))
+ let byte = key[Int(i)]
+ if b != byte {
+ return Int32(b - Int8(byte))
+ }
+ }
+ return len1 - len2
+ }
+}
diff --git a/tests/BUILD b/tests/BUILD
new file mode 100644
index 00000000..97ef6748
--- /dev/null
+++ b/tests/BUILD
@@ -0,0 +1,110 @@
+load("@rules_cc//cc:defs.bzl", "cc_test")
+
+package(default_visibility = ["//visibility:private"])
+
+# Test binary.
+cc_test(
+ name = "flatbuffers_test",
+ testonly = 1,
+ srcs = [
+ "evolution_test/evolution_v1_generated.h",
+ "evolution_test/evolution_v2_generated.h",
+ "namespace_test/namespace_test1_generated.h",
+ "namespace_test/namespace_test2_generated.h",
+ "native_type_test_impl.cpp",
+ "native_type_test_impl.h",
+ "test.cpp",
+ "test_assert.cpp",
+ "test_assert.h",
+ "test_builder.cpp",
+ "test_builder.h",
+ "union_vector/union_vector_generated.h",
+ "monster_test_bfbs_generated.h",
+ ],
+ copts = [
+ "-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE",
+ "-DBAZEL_TEST_DATA_PATH",
+ ],
+ data = [
+ ":arrays_test.bfbs",
+ ":arrays_test.fbs",
+ ":arrays_test.golden",
+ ":evolution_test/evolution_v1.fbs",
+ ":evolution_test/evolution_v1.json",
+ ":evolution_test/evolution_v2.fbs",
+ ":evolution_test/evolution_v2.json",
+ ":include_test/include_test1.fbs",
+ ":include_test/sub/include_test2.fbs",
+ ":monster_extra.fbs",
+ ":monster_test.bfbs",
+ ":monster_test.fbs",
+ ":monsterdata_extra.json",
+ ":monsterdata_test.golden",
+ ":monsterdata_test.json",
+ ":native_type_test.fbs",
+ ":prototest/imported.proto",
+ ":prototest/test.golden",
+ ":prototest/test.proto",
+ ":prototest/test_include.golden",
+ ":prototest/test_suffix.golden",
+ ":prototest/test_union.golden",
+ ":prototest/test_union_include.golden",
+ ":prototest/test_union_suffix.golden",
+ ":unicode_test.json",
+ ":union_vector/union_vector.fbs",
+ ":union_vector/union_vector.json",
+ ],
+ includes = [
+ "",
+ "include/",
+ ],
+ deps = [
+ ":arrays_test_cc_fbs",
+ ":monster_extra_cc_fbs",
+ ":monster_test_cc_fbs",
+ ":native_type_test_cc_fbs",
+ "//:flatbuffers",
+ ],
+)
+
+# Test bzl rules
+load("//:build_defs.bzl", "flatbuffer_cc_library")
+
+flatbuffer_cc_library(
+ name = "monster_test_cc_fbs",
+ srcs = ["monster_test.fbs"],
+ include_paths = ["tests/include_test"],
+ includes = [
+ "include_test/include_test1.fbs",
+ "include_test/sub/include_test2.fbs",
+ ],
+)
+
+flatbuffer_cc_library(
+ name = "monster_extra_cc_fbs",
+ srcs = ["monster_extra.fbs"],
+)
+
+flatbuffer_cc_library(
+ name = "arrays_test_cc_fbs",
+ srcs = ["arrays_test.fbs"],
+ flatc_args = [
+ "--gen-object-api",
+ "--gen-compare",
+ "--no-includes",
+ "--gen-mutable",
+ "--reflect-names",
+ "--cpp-ptr-type flatbuffers::unique_ptr",
+ "--scoped-enums",
+ ],
+)
+
+flatbuffer_cc_library(
+ name = "native_type_test_cc_fbs",
+ srcs = ["native_type_test.fbs"],
+ flatc_args = [
+ "--gen-object-api",
+ "--gen-mutable",
+ "--cpp-ptr-type flatbuffers::unique_ptr",
+ ],
+)
diff --git a/tests/FlatBuffers.Benchmarks.swift/Package.swift b/tests/FlatBuffers.Benchmarks.swift/Package.swift
new file mode 100644
index 00000000..9360b10f
--- /dev/null
+++ b/tests/FlatBuffers.Benchmarks.swift/Package.swift
@@ -0,0 +1,19 @@
+// swift-tools-version:5.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "FlatBuffers.Benchmarks.swift",
+ platforms: [
+ .macOS(.v10_14)
+ ],
+ dependencies: [
+ .package(path: "../../swift")
+ ],
+ targets: [
+ .target(
+ name: "FlatBuffers.Benchmarks.swift",
+ dependencies: ["FlatBuffers"]),
+ ]
+)
diff --git a/tests/FlatBuffers.Benchmarks.swift/Sources/FlatBuffers.Benchmarks.swift/main.swift b/tests/FlatBuffers.Benchmarks.swift/Sources/FlatBuffers.Benchmarks.swift/main.swift
new file mode 100644
index 00000000..2fac8590
--- /dev/null
+++ b/tests/FlatBuffers.Benchmarks.swift/Sources/FlatBuffers.Benchmarks.swift/main.swift
@@ -0,0 +1,75 @@
+import CoreFoundation
+import FlatBuffers
+
+struct Benchmark {
+ var name: String
+ var value: Double
+
+ var description: String { "\(String(format: "|\t%@\t\t|\t\t%fs\t|", name, value))"}
+}
+
+func run(name: String, runs: Int, action: () -> Void) -> Benchmark {
+ action()
+ let start = CFAbsoluteTimeGetCurrent()
+ for _ in 0..<runs {
+ action()
+ }
+ let ends = CFAbsoluteTimeGetCurrent()
+ let value = Double(ends - start) / Double(runs)
+ print("done \(name): in \(value)")
+ return Benchmark(name: name, value: value)
+}
+
+
+func createDocument(Benchmarks: [Benchmark]) -> String {
+ let separator = "-------------------------------------"
+ var document = "\(separator)\n"
+ document += "\(String(format: "|\t%@\t\t|\t\t%@\t\t|", "Name", "Scores"))\n"
+ document += "\(separator)\n"
+ for i in Benchmarks {
+ document += "\(i.description) \n"
+ document += "\(separator)\n"
+ }
+ return document
+}
+
+@inlinable func create10Strings() {
+ let fb = FlatBufferBuilder(initialSize: 1<<20)
+ for _ in 0..<10_000 {
+ _ = fb.create(string: "foobarbaz")
+ }
+}
+
+@inlinable func create100Strings(str: String) {
+ let fb = FlatBufferBuilder(initialSize: 1<<20)
+ for _ in 0..<10_000 {
+ _ = fb.create(string: str)
+ }
+}
+
+@inlinable func benchmarkFiveHundredAdds() {
+ let fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
+ for _ in 0..<500_000 {
+ let off = fb.create(string: "T")
+ let s = fb.startTable(with: 4)
+ fb.add(element: 3.2, def: 0, at: 0)
+ fb.add(element: 4.2, def: 0, at: 1)
+ fb.add(element: 5.2, def: 0, at: 2)
+ fb.add(offset: off, at: 3)
+ _ = fb.endTable(at: s)
+ }
+}
+
+func benchmark(numberOfRuns runs: Int) {
+ var benchmarks: [Benchmark] = []
+ let str = (0...99).map { _ -> String in return "x" }.joined()
+ benchmarks.append(run(name: "500_000", runs: runs, action: benchmarkFiveHundredAdds))
+ benchmarks.append(run(name: "10 str", runs: runs, action: create10Strings))
+ let hundredStr = run(name: "100 str", runs: runs) {
+ create100Strings(str: str)
+ }
+ benchmarks.append(hundredStr)
+ print(createDocument(Benchmarks: benchmarks))
+}
+
+benchmark(numberOfRuns: 20)
diff --git a/tests/FlatBuffers.GRPC.Swift/Package.swift b/tests/FlatBuffers.GRPC.Swift/Package.swift
new file mode 100644
index 00000000..e9f3bbe4
--- /dev/null
+++ b/tests/FlatBuffers.GRPC.Swift/Package.swift
@@ -0,0 +1,49 @@
+// swift-tools-version:5.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "FlatBuffers.GRPC.Swift",
+ platforms: [
+ .iOS(.v11),
+ .macOS(.v10_14),
+ ],
+ dependencies: [
+ // Main SwiftNIO package
+ .package(path: "../../swift"),
+ .package(url: "https://github.com/grpc/grpc-swift.git", .branch("nio"))
+ ],
+ targets: [
+ // Targets are the basic building blocks of a package. A target can define a module or a test suite.
+ // Targets can depend on other targets in this package, and on products in packages which this package depends on.
+ .target(
+ name: "Model",
+ dependencies: [
+ "GRPC",
+ "FlatBuffers"
+ ],
+ path: "Sources/Model"
+ ),
+
+ // Client for the HelloWorld example
+ .target(
+ name: "Client",
+ dependencies: [
+ "GRPC",
+ "Model",
+ ],
+ path: "Sources/client"
+ ),
+
+ // Server for the HelloWorld example
+ .target(
+ name: "Server",
+ dependencies: [
+ "GRPC",
+ "Model",
+ ],
+ path: "Sources/server"
+ ),
+ ]
+)
diff --git a/tests/FlatBuffers.GRPC.Swift/README.md b/tests/FlatBuffers.GRPC.Swift/README.md
new file mode 100644
index 00000000..4a14f9e8
--- /dev/null
+++ b/tests/FlatBuffers.GRPC.Swift/README.md
@@ -0,0 +1,3 @@
+# FlatBuffers.GRPC.Swift
+
+The following is Swift example on how GRPC would be with Swift Flatbuffers
diff --git a/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.fbs b/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.fbs
new file mode 100644
index 00000000..811303c9
--- /dev/null
+++ b/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.fbs
@@ -0,0 +1,17 @@
+table HelloReply {
+ message:string;
+}
+
+table HelloRequest {
+ name:string;
+}
+
+table ManyHellosRequest {
+ name:string;
+ num_greetings:int;
+}
+
+rpc_service Greeter {
+ SayHello(HelloRequest):HelloReply;
+ SayManyHellos(ManyHellosRequest):HelloReply (streaming: "server");
+}
diff --git a/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.grpc.swift b/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.grpc.swift
new file mode 100644
index 00000000..6ad1f18d
--- /dev/null
+++ b/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.grpc.swift
@@ -0,0 +1,73 @@
+// Generated GRPC code for FlatBuffers swift!
+/// The following code is generated by the Flatbuffers library which might not be in sync with grpc-swift
+/// in case of an issue please open github issue, though it would be maintained
+import Foundation
+import GRPC
+import NIO
+import NIOHTTP1
+import FlatBuffers
+
+public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage {}
+public extension GRPCFlatBufPayload {
+ init(serializedByteBuffer: inout NIO.ByteBuffer) throws {
+ self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: serializedByteBuffer.readableBytesView, count: serializedByteBuffer.readableBytes))
+ }
+ func serialize(into buffer: inout NIO.ByteBuffer) throws {
+ let buf = UnsafeRawBufferPointer(start: self.rawPointer, count: Int(self.size))
+ buffer.writeBytes(buf)
+ }
+}
+extension Message: GRPCFlatBufPayload {}
+
+/// Usage: instantiate GreeterServiceClient, then call methods of this protocol to make API calls.
+public protocol GreeterService {
+ func SayHello(_ request: Message<HelloRequest>, callOptions: CallOptions?) -> UnaryCall<Message<HelloRequest>,Message<HelloReply>>
+ func SayManyHellos(_ request: Message<ManyHellosRequest>, callOptions: CallOptions?, handler: @escaping (Message<HelloReply>) -> Void) -> ServerStreamingCall<Message<ManyHellosRequest>, Message<HelloReply>>
+}
+
+public final class GreeterServiceClient: GRPCClient, GreeterService {
+ public let connection: ClientConnection
+ public var defaultCallOptions: CallOptions
+
+ public init(connection: ClientConnection, defaultCallOptions: CallOptions = CallOptions()) {
+ self.connection = connection
+ self.defaultCallOptions = defaultCallOptions
+ }
+
+ public func SayHello(_ request: Message<HelloRequest>, callOptions: CallOptions? = nil) -> UnaryCall<Message<HelloRequest>,Message<HelloReply>> {
+ return self.makeUnaryCall(path: "/Greeter/SayHello", request: request, callOptions: callOptions ?? self.defaultCallOptions)
+ }
+
+ public func SayManyHellos(_ request: Message<ManyHellosRequest>, callOptions: CallOptions? = nil, handler: @escaping (Message<HelloReply>) -> Void) -> ServerStreamingCall<Message<ManyHellosRequest>, Message<HelloReply>> {
+ return self.makeServerStreamingCall(path: "/Greeter/SayManyHellos", request: request, callOptions: callOptions ?? self.defaultCallOptions, handler: handler)
+ }
+}
+
+public protocol GreeterProvider: CallHandlerProvider {
+ func SayHello(_ request: Message<HelloRequest>, context: StatusOnlyCallContext) -> EventLoopFuture<Message<HelloReply>>
+ func SayManyHellos(request: Message<ManyHellosRequest>, context: StreamingResponseCallContext<Message<HelloReply>>) -> EventLoopFuture<GRPCStatus>
+}
+
+public extension GreeterProvider {
+ var serviceName: String { return "Greeter" }
+ func handleMethod(_ methodName: String, callHandlerContext: CallHandlerContext) -> GRPCCallHandler? {
+ switch methodName {
+ case "SayHello":
+ return UnaryCallHandler(callHandlerContext: callHandlerContext) { context in
+ return { request in
+ self.SayHello(request, context: context)
+ }
+ }
+ case "SayManyHellos":
+ return ServerStreamingCallHandler(callHandlerContext: callHandlerContext) { context in
+ return { request in
+ self.SayManyHellos(request: request, context: context)
+ }
+ }
+ default: return nil;
+ }
+ }
+
+}
+
+
diff --git a/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter_generated.swift b/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter_generated.swift
new file mode 100644
index 00000000..91973f58
--- /dev/null
+++ b/tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter_generated.swift
@@ -0,0 +1,80 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import FlatBuffers
+
+public struct HelloReply: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func getRootAsHelloReply(bb: ByteBuffer) -> HelloReply { return HelloReply(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var message: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
+ public var messageSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
+ public static func startHelloReply(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
+ public static func add(message: Offset<String>, _ fbb: FlatBufferBuilder) { fbb.add(offset: message, at: 0) }
+ public static func endHelloReply(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createHelloReply(_ fbb: FlatBufferBuilder,
+ offsetOfMessage message: Offset<String> = Offset()) -> Offset<UOffset> {
+ let __start = HelloReply.startHelloReply(fbb)
+ HelloReply.add(message: message, fbb)
+ return HelloReply.endHelloReply(fbb, start: __start)
+ }
+}
+
+public struct HelloRequest: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func getRootAsHelloRequest(bb: ByteBuffer) -> HelloRequest { return HelloRequest(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var name: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
+ public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
+ public static func startHelloRequest(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
+ public static func add(name: Offset<String>, _ fbb: FlatBufferBuilder) { fbb.add(offset: name, at: 0) }
+ public static func endHelloRequest(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createHelloRequest(_ fbb: FlatBufferBuilder,
+ offsetOfName name: Offset<String> = Offset()) -> Offset<UOffset> {
+ let __start = HelloRequest.startHelloRequest(fbb)
+ HelloRequest.add(name: name, fbb)
+ return HelloRequest.endHelloRequest(fbb, start: __start)
+ }
+}
+
+public struct ManyHellosRequest: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func getRootAsManyHellosRequest(bb: ByteBuffer) -> ManyHellosRequest { return ManyHellosRequest(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var name: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
+ public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
+ public var numGreetings: Int32 { let o = _accessor.offset(6); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
+ public static func startManyHellosRequest(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) }
+ public static func add(name: Offset<String>, _ fbb: FlatBufferBuilder) { fbb.add(offset: name, at: 0) }
+ public static func add(numGreetings: Int32, _ fbb: FlatBufferBuilder) { fbb.add(element: numGreetings, def: 0, at: 1) }
+ public static func endManyHellosRequest(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createManyHellosRequest(_ fbb: FlatBufferBuilder,
+ offsetOfName name: Offset<String> = Offset(),
+ numGreetings: Int32 = 0) -> Offset<UOffset> {
+ let __start = ManyHellosRequest.startManyHellosRequest(fbb)
+ ManyHellosRequest.add(name: name, fbb)
+ ManyHellosRequest.add(numGreetings: numGreetings, fbb)
+ return ManyHellosRequest.endManyHellosRequest(fbb, start: __start)
+ }
+}
+
diff --git a/tests/FlatBuffers.GRPC.Swift/Sources/client/main.swift b/tests/FlatBuffers.GRPC.Swift/Sources/client/main.swift
new file mode 100644
index 00000000..cc9374b2
--- /dev/null
+++ b/tests/FlatBuffers.GRPC.Swift/Sources/client/main.swift
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2020, gRPC Authors All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import GRPC
+import Model
+import NIO
+import Logging
+import FlatBuffers
+
+// Quieten the logs.
+LoggingSystem.bootstrap {
+ var handler = StreamLogHandler.standardOutput(label: $0)
+ handler.logLevel = .critical
+ return handler
+}
+
+func greet(name: String, client greeter: GreeterServiceClient) {
+ // Form the request with the name, if one was provided.
+ var builder = FlatBufferBuilder()
+ let name = builder.create(string: name)
+ let root = HelloRequest.createHelloRequest(builder, offsetOfName: name)
+ builder.finish(offset: root)
+
+ // Make the RPC call to the server.
+ let sayHello = greeter.SayHello(Message<HelloRequest>(builder: &builder))
+ // wait() on the response to stop the program from exiting before the response is received.
+ do {
+ let response = try sayHello.response.wait()
+ print("Greeter received: \(response.object.message)")
+ } catch {
+ print("Greeter failed: \(error)")
+ }
+
+ let surname = builder.create(string: "Name")
+ let manyRoot = ManyHellosRequest.createManyHellosRequest(builder, offsetOfName: surname, numGreetings: 2)
+ builder.finish(offset: manyRoot)
+
+ let call = greeter.SayManyHellos(Message(builder: &builder)) { message in
+ print(message.object.message)
+ }
+
+ let status = try! call.status.recover { _ in .processingError }.wait()
+ if status.code != .ok {
+ print("RPC failed: \(status)")
+ }
+}
+
+func main(args: [String]) {
+ // arg0 (dropped) is the program name. We expect arg1 to be the port, and arg2 (optional) to be
+ // the name sent in the request.
+ let arg1 = args.dropFirst(1).first
+ let arg2 = args.dropFirst(2).first
+
+ switch (arg1.flatMap(Int.init), arg2) {
+ case (.none, _):
+ print("Usage: PORT [NAME]")
+ exit(1)
+
+ case let (.some(port), name):
+ // Setup an `EventLoopGroup` for the connection to run on.
+ //
+ // See: https://github.com/apple/swift-nio#eventloops-and-eventloopgroups
+ let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
+
+ // Make sure the group is shutdown when we're done with it.
+ defer {
+ try! group.syncShutdownGracefully()
+ }
+
+ // Provide some basic configuration for the connection, in this case we connect to an endpoint on
+ // localhost at the given port.
+ let configuration = ClientConnection.Configuration(
+ target: .hostAndPort("localhost", port),
+ eventLoopGroup: group
+ )
+
+ // Create a connection using the configuration.
+ let connection = ClientConnection(configuration: configuration)
+
+ // Provide the connection to the generated client.
+ let greeter = GreeterServiceClient(connection: connection)
+
+ // Do the greeting.
+ greet(name: "Hello FlatBuffers!", client: greeter)
+ }
+}
+
+main(args: CommandLine.arguments)
diff --git a/tests/FlatBuffers.GRPC.Swift/Sources/server/main.swift b/tests/FlatBuffers.GRPC.Swift/Sources/server/main.swift
new file mode 100644
index 00000000..5595b640
--- /dev/null
+++ b/tests/FlatBuffers.GRPC.Swift/Sources/server/main.swift
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2020, gRPC Authors All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import GRPC
+import NIO
+import FlatBuffers
+import Logging
+import Model
+
+class Greeter: GreeterProvider {
+
+ var hellos: [Message<HelloReply>] = []
+
+ init() {
+ let names = ["Stranger1", "Stranger2", "Stranger4", "Stranger3", "Stranger5", "Stranger6"]
+ for name in names {
+ var builder = FlatBufferBuilder()
+ let off = builder.create(string: name)
+ let root = HelloReply.createHelloReply(builder, offsetOfMessage: off)
+ builder.finish(offset: root)
+ hellos.append(Message(builder: &builder))
+ }
+ }
+
+ func SayHello(
+ _ request: Message<HelloRequest>,
+ context: StatusOnlyCallContext
+ ) -> EventLoopFuture<Message<HelloReply>> {
+ let recipient = request.object.name ?? "Stranger"
+
+ var builder = FlatBufferBuilder()
+ let off = builder.create(string: recipient)
+ let root = HelloReply.createHelloReply(builder, offsetOfMessage: off)
+ builder.finish(offset: root)
+ return context.eventLoop.makeSucceededFuture(Message<HelloReply>(builder: &builder))
+ }
+
+ func SayManyHellos(
+ request: Message<ManyHellosRequest>,
+ context: StreamingResponseCallContext<Message<HelloReply>>
+ ) -> EventLoopFuture<GRPCStatus> {
+ for _ in 0..<Int(request.object.numGreetings) {
+ let index = Int.random(in: 0..<hellos.count)
+ _ = context.sendResponse(hellos[index])
+ }
+ return context.eventLoop.makeSucceededFuture(.ok)
+ }
+}
+
+// Quieten the logs.
+LoggingSystem.bootstrap {
+ var handler = StreamLogHandler.standardOutput(label: $0)
+ handler.logLevel = .critical
+ return handler
+}
+
+let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
+defer {
+ try! group.syncShutdownGracefully()
+}
+
+// Create some configuration for the server:
+let configuration = Server.Configuration(
+ target: .hostAndPort("localhost", 0),
+ eventLoopGroup: group,
+ serviceProviders: [Greeter()]
+)
+
+// Start the server and print its address once it has started.
+let server = Server.start(configuration: configuration)
+server.map {
+ $0.channel.localAddress
+}.whenSuccess { address in
+ print("server started on port \(address!.port!)")
+}
+
+// Wait on the server's `onClose` future to stop the program from exiting.
+_ = try server.flatMap {
+ $0.onClose
+}.wait()
diff --git a/tests/FlatBuffers.Test.Swift/Package.swift b/tests/FlatBuffers.Test.Swift/Package.swift
new file mode 100644
index 00000000..bbe5a6ab
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Package.swift
@@ -0,0 +1,20 @@
+// swift-tools-version:5.1
+// The swift-tools-version declares the minimum version of Swift required to build this package.
+
+import PackageDescription
+
+let package = Package(
+ name: "FlatBuffers.Test.Swift",
+ platforms: [
+ .iOS(.v11),
+ .macOS(.v10_14),
+ ],
+ dependencies: [
+ .package(path: "../../swift/")
+ ],
+ targets: [
+ .testTarget(
+ name: "FlatBuffers.Test.SwiftTests",
+ dependencies: ["FlatBuffers"]),
+ ]
+)
diff --git a/tests/FlatBuffers.Test.Swift/SwiftTest.sh b/tests/FlatBuffers.Test.Swift/SwiftTest.sh
new file mode 100644
index 00000000..aa8b5aca
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/SwiftTest.sh
@@ -0,0 +1,10 @@
+swift_dir=`pwd`
+cd ..
+test_dir=`pwd`
+
+${test_dir}/../flatc --swift --gen-mutable -I ${test_dir}/include_test ${test_dir}/monster_test.fbs ${test_dir}/union_vector/union_vector.fbs
+cd ${test_dir}
+mv *_generated.swift ${swift_dir}/Tests/FlatBuffers.Test.SwiftTests
+cd ${swift_dir}
+swift build --build-tests
+swift test \ No newline at end of file
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift
new file mode 100644
index 00000000..486cd1a4
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersMonsterWriterTests.swift
@@ -0,0 +1,190 @@
+import XCTest
+import Foundation
+@testable import FlatBuffers
+
+typealias Test1 = MyGame.Example.Test
+typealias Monster1 = MyGame.Example.Monster
+typealias Vec3 = MyGame.Example.Vec3
+
+class FlatBuffersMonsterWriterTests: XCTestCase {
+
+ func testData() {
+ let data = Data([48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0])
+ let _data = ByteBuffer(data: data)
+ readMonster(fb: _data)
+ }
+
+ func testReadFromOtherLangagues() {
+ let path = FileManager.default.currentDirectoryPath
+ let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon")
+ guard let data = try? Data(contentsOf: url) else { return }
+ let _data = ByteBuffer(data: data)
+ readMonster(fb: _data)
+ }
+
+ func testCreateMonster() {
+ let bytes = createMonster(withPrefix: false)
+ XCTAssertEqual(bytes.sizedByteArray, [48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0])
+ readMonster(fb: bytes.buffer)
+ mutateMonster(fb: bytes.buffer)
+ readMonster(fb: bytes.buffer)
+ }
+
+ func testCreateMonsterResizedBuffer() {
+ let bytes = createMonster(withPrefix: false)
+ XCTAssertEqual(bytes.sizedByteArray, [48, 0, 0, 0, 77, 79, 78, 83, 0, 0, 0, 0, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0])
+ readMonster(fb: ByteBuffer(data: bytes.data))
+ }
+
+ func testCreateMonsterPrefixed() {
+ let bytes = createMonster(withPrefix: true)
+ XCTAssertEqual(bytes.sizedByteArray, [44, 1, 0, 0, 44, 0, 0, 0, 77, 79, 78, 83, 36, 0, 72, 0, 40, 0, 0, 0, 38, 0, 32, 0, 0, 0, 28, 0, 0, 0, 27, 0, 20, 0, 16, 0, 12, 0, 4, 0, 0, 0, 0, 0, 0, 0, 11, 0, 36, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 68, 0, 0, 0, 76, 0, 0, 0, 0, 0, 0, 1, 88, 0, 0, 0, 120, 0, 0, 0, 0, 0, 80, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 64, 2, 0, 5, 0, 6, 0, 0, 0, 2, 0, 0, 0, 64, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 30, 0, 40, 0, 10, 0, 20, 0, 152, 255, 255, 255, 4, 0, 0, 0, 4, 0, 0, 0, 70, 114, 101, 100, 0, 0, 0, 0, 5, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 50, 0, 0, 0, 5, 0, 0, 0, 116, 101, 115, 116, 49, 0, 0, 0, 9, 0, 0, 0, 77, 121, 77, 111, 110, 115, 116, 101, 114, 0, 0, 0, 3, 0, 0, 0, 20, 0, 0, 0, 36, 0, 0, 0, 4, 0, 0, 0, 240, 255, 255, 255, 32, 0, 0, 0, 248, 255, 255, 255, 36, 0, 0, 0, 12, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 12, 0, 0, 0, 28, 0, 0, 0, 5, 0, 0, 0, 87, 105, 108, 109, 97, 0, 0, 0, 6, 0, 0, 0, 66, 97, 114, 110, 101, 121, 0, 0, 5, 0, 0, 0, 70, 114, 111, 100, 111, 0, 0, 0])
+
+ let newBuf = FlatBuffersUtils.removeSizePrefix(bb: bytes.buffer)
+ readMonster(fb: newBuf)
+ }
+
+ func createMonster(withPrefix prefix: Bool) -> FlatBufferBuilder {
+ let fbb = FlatBufferBuilder(initialSize: 1)
+ let names = [fbb.create(string: "Frodo"), fbb.create(string: "Barney"), fbb.create(string: "Wilma")]
+ var offsets: [Offset<UOffset>] = []
+ let start1 = Monster1.startMonster(fbb)
+ Monster1.add(name: names[0], fbb)
+ offsets.append(Monster1.endMonster(fbb, start: start1))
+ let start2 = Monster1.startMonster(fbb)
+ Monster1.add(name: names[1], fbb)
+ offsets.append(Monster1.endMonster(fbb, start: start2))
+ let start3 = Monster1.startMonster(fbb)
+ Monster1.add(name: names[2], fbb)
+ offsets.append(Monster1.endMonster(fbb, start: start3))
+
+ let sortedArray = Monster1.sortVectorOfMonster(offsets: offsets, fbb)
+
+ let str = fbb.create(string: "MyMonster")
+ let test1 = fbb.create(string: "test1")
+ let test2 = fbb.create(string: "test2")
+ let _inv: [Byte] = [0, 1, 2, 3, 4]
+ let inv = fbb.createVector(_inv)
+
+ let fred = fbb.create(string: "Fred")
+ let mon1Start = Monster1.startMonster(fbb)
+ Monster1.add(name: fred, fbb)
+ let mon2 = Monster1.endMonster(fbb, start: mon1Start)
+ let test4 = fbb.createVector(structs: [MyGame.Example.createTest(a: 30, b: 40),
+ MyGame.Example.createTest(a: 10, b: 20)],
+ type: Test1.self)
+
+ let stringTestVector = fbb.createVector(ofOffsets: [test1, test2])
+
+ let mStart = Monster1.startMonster(fbb)
+ let posOffset = fbb.create(struct: MyGame.Example.createVec3(x: 1, y: 2, z: 3, test1: 3, test2: .green, test3a: 5, test3b: 6), type: Vec3.self)
+ Monster1.add(pos: posOffset, fbb)
+ Monster1.add(hp: 80, fbb)
+ Monster1.add(name: str, fbb)
+ Monster1.addVectorOf(inventory: inv, fbb)
+ Monster1.add(testType: .monster, fbb)
+ Monster1.add(test: mon2, fbb)
+ Monster1.addVectorOf(test4: test4, fbb)
+ Monster1.addVectorOf(testarrayofstring: stringTestVector, fbb)
+ Monster1.add(testbool: true, fbb)
+ Monster1.addVectorOf(testarrayoftables: sortedArray, fbb)
+ let end = Monster1.endMonster(fbb, start: mStart)
+ Monster1.finish(fbb, end: end, prefix: prefix)
+ return fbb
+ }
+
+ func mutateMonster(fb: ByteBuffer) {
+ let monster = Monster1.getRootAsMonster(bb: fb)
+ XCTAssertFalse(monster.mutate(mana: 10))
+ XCTAssertEqual(monster.testarrayoftables(at: 0)?.name, "Barney")
+ XCTAssertEqual(monster.testarrayoftables(at: 1)?.name, "Frodo")
+ XCTAssertEqual(monster.testarrayoftables(at: 2)?.name, "Wilma")
+
+ // Example of searching for a table by the key
+ XCTAssertNotNil(monster.testarrayoftablesBy(key: "Frodo"))
+ XCTAssertNotNil(monster.testarrayoftablesBy(key: "Barney"))
+ XCTAssertNotNil(monster.testarrayoftablesBy(key: "Wilma"))
+
+ XCTAssertEqual(monster.testType, .monster)
+
+ XCTAssertEqual(monster.mutate(inventory: 1, at: 0), true)
+ XCTAssertEqual(monster.mutate(inventory: 2, at: 1), true)
+ XCTAssertEqual(monster.mutate(inventory: 3, at: 2), true)
+ XCTAssertEqual(monster.mutate(inventory: 4, at: 3), true)
+ XCTAssertEqual(monster.mutate(inventory: 5, at: 4), true)
+
+ for i in 0..<monster.inventoryCount {
+ XCTAssertEqual(monster.inventory(at: i), Byte(i + 1))
+ }
+
+ XCTAssertEqual(monster.mutate(inventory: 0, at: 0), true)
+ XCTAssertEqual(monster.mutate(inventory: 1, at: 1), true)
+ XCTAssertEqual(monster.mutate(inventory: 2, at: 2), true)
+ XCTAssertEqual(monster.mutate(inventory: 3, at: 3), true)
+ XCTAssertEqual(monster.mutate(inventory: 4, at: 4), true)
+
+ let vec = monster.pos
+ XCTAssertEqual(vec?.x, 1)
+ XCTAssertTrue(vec?.mutate(x: 55.0) ?? false)
+ XCTAssertTrue(vec?.mutate(test1: 55) ?? false)
+ XCTAssertEqual(vec?.x, 55.0)
+ XCTAssertEqual(vec?.test1, 55.0)
+ XCTAssertTrue(vec?.mutate(x: 1) ?? false)
+ XCTAssertEqual(vec?.x, 1)
+ XCTAssertTrue(vec?.mutate(test1: 3) ?? false)
+ }
+
+ func readMonster(fb: ByteBuffer) {
+ let monster = Monster1.getRootAsMonster(bb: fb)
+ XCTAssertEqual(monster.hp, 80)
+ XCTAssertEqual(monster.mana, 150)
+ XCTAssertEqual(monster.name, "MyMonster")
+ let pos = monster.pos
+ XCTAssertEqual(pos?.x, 1)
+ XCTAssertEqual(pos?.y, 2)
+ XCTAssertEqual(pos?.z, 3)
+ XCTAssertEqual(pos?.test1, 3)
+ XCTAssertEqual(pos?.test2, .green)
+ let test = pos?.test3
+ XCTAssertEqual(test?.a, 5)
+ XCTAssertEqual(test?.b, 6)
+ XCTAssertEqual(monster.testType, .monster)
+ let monster2 = monster.test(type: Monster1.self)
+ XCTAssertEqual(monster2?.name, "Fred")
+
+ XCTAssertEqual(monster.mutate(mana: 10), false)
+
+ XCTAssertEqual(monster.mana, 150)
+ XCTAssertEqual(monster.inventoryCount, 5)
+ var sum: Byte = 0
+ for i in 0...monster.inventoryCount {
+ sum += monster.inventory(at: i)
+ }
+ XCTAssertEqual(sum, 10)
+ XCTAssertEqual(monster.test4Count, 2)
+ let test0 = monster.test4(at: 0)
+ let test1 = monster.test4(at: 1)
+ var sum0 = 0
+ var sum1 = 0
+ if let a = test0?.a, let b = test0?.b {
+ sum0 = Int(a) + Int(b)
+ }
+ if let a = test1?.a, let b = test1?.b {
+ sum1 = Int(a) + Int(b)
+ }
+ XCTAssertEqual(sum0 + sum1, 100)
+ XCTAssertEqual(monster.testarrayofstringCount, 2)
+ XCTAssertEqual(monster.testarrayofstring(at: 0), "test1")
+ XCTAssertEqual(monster.testarrayofstring(at: 1), "test2")
+ XCTAssertEqual(monster.testbool, true)
+
+ let array = monster.nameSegmentArray
+ XCTAssertEqual(String(bytes: array ?? [], encoding: .utf8), "MyMonster")
+
+ if 0 == monster.testarrayofboolsCount {
+ XCTAssertEqual(monster.testarrayofbools.isEmpty, true)
+ } else {
+ XCTAssertEqual(monster.testarrayofbools.isEmpty, false)
+ }
+ }
+}
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersStructsTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersStructsTests.swift
new file mode 100644
index 00000000..f0107e2a
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersStructsTests.swift
@@ -0,0 +1,187 @@
+import XCTest
+@testable import FlatBuffers
+
+final class FlatBuffersStructsTests: XCTestCase {
+
+ func testCreatingStruct() {
+ let v = createVecWrite(x: 1.0, y: 2.0, z: 3.0)
+ let b = FlatBufferBuilder(initialSize: 20)
+ let o = b.create(struct: v, type: Vec.self)
+ let end = VPointerVec.createVPointer(b: b, o: o)
+ b.finish(offset: end)
+ XCTAssertEqual(b.sizedByteArray, [12, 0, 0, 0, 0, 0, 6, 0, 4, 0, 4, 0, 6, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64])
+ }
+
+ func testReadingStruct() {
+ let v = createVecWrite(x: 1.0, y: 2.0, z: 3.0)
+ let b = FlatBufferBuilder(initialSize: 20)
+ let o = b.create(struct: v, type: Vec.self)
+ let end = VPointerVec.createVPointer(b: b, o: o)
+ b.finish(offset: end)
+ let buffer = b.sizedByteArray
+ XCTAssertEqual(buffer, [12, 0, 0, 0, 0, 0, 6, 0, 4, 0, 4, 0, 6, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64])
+ let point = VPointerVec.getRootAsCountry(ByteBuffer(bytes: buffer))
+ XCTAssertEqual(point.vec?.z, 3.0)
+ }
+
+ func testCreatingVectorStruct() {
+ let b = FlatBufferBuilder(initialSize: 20)
+ let path = b.createVector(structs: [createVecWrite(x: 1, y: 2, z: 3), createVecWrite(x: 4.0, y: 5.0, z: 6)], type: Vec.self)
+ let end = VPointerVectorVec.createVPointer(b: b, v: path)
+ b.finish(offset: end)
+ XCTAssertEqual(b.sizedByteArray, [12, 0, 0, 0, 8, 0, 8, 0, 0, 0, 4, 0, 8, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 192, 64])
+ }
+
+ func testCreatingVectorStructWithForcedDefaults() {
+ let b = FlatBufferBuilder(initialSize: 20, serializeDefaults: true)
+ let path = b.createVector(structs: [createVecWrite(x: 1, y: 2, z: 3), createVecWrite(x: 4.0, y: 5.0, z: 6)], type: Vec.self)
+ let end = VPointerVectorVec.createVPointer(b: b, v: path)
+ b.finish(offset: end)
+ XCTAssertEqual(b.sizedByteArray, [12, 0, 0, 0, 8, 0, 12, 0, 4, 0, 8, 0, 8, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 192, 64])
+ }
+
+ func testCreatingEnums() {
+ let b = FlatBufferBuilder(initialSize: 20)
+ let path = b.createVector(structs: [createVecWrite(x: 1, y: 2, z: 3), createVecWrite(x: 4, y: 5, z: 6)], type: Vec.self)
+ let end = VPointerVectorVec.createVPointer(b: b, color: .blue, v: path)
+ b.finish(offset: end)
+ XCTAssertEqual(b.sizedByteArray, [12, 0, 0, 0, 8, 0, 12, 0, 4, 0, 8, 0, 8, 0, 0, 0, 2, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 192, 64])
+ }
+
+ func testReadingStructWithEnums() {
+ let b = FlatBufferBuilder(initialSize: 20)
+ let vec = createVec2(x: 1, y: 2, z: 3, color: .red)
+ let o = b.create(struct: vec, type: Vec2.self)
+ let end = VPointerVec2.createVPointer(b: b, o: o, type: .vec)
+ b.finish(offset: end)
+ let buffer = b.sizedByteArray
+ XCTAssertEqual(buffer, [16, 0, 0, 0, 0, 0, 10, 0, 12, 0, 12, 0, 11, 0, 4, 0, 10, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 1, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 0, 0, 0, 0])
+ let point = VPointerVec2.getRootAsCountry(ByteBuffer(bytes: buffer))
+ XCTAssertEqual(point.vec?.c, Color2.red)
+ XCTAssertEqual(point.vec?.x, 1.0)
+ XCTAssertEqual(point.vec?.y, 2.0)
+ XCTAssertEqual(point.vec?.z, 3.0)
+ XCTAssertEqual(point.UType, Test.vec)
+ }
+
+}
+
+func createVecWrite(x: Float32, y: Float32, z: Float32) -> UnsafeMutableRawPointer{
+ let memory = UnsafeMutableRawPointer.allocate(byteCount: Vec.size, alignment: Vec.alignment)
+ memory.initializeMemory(as: UInt8.self, repeating: 0, count: Vec.size)
+ memory.storeBytes(of: x, toByteOffset: 0, as: Float32.self)
+ memory.storeBytes(of: y, toByteOffset: 4, as: Float32.self)
+ memory.storeBytes(of: z, toByteOffset: 8, as: Float32.self)
+ return memory
+}
+
+struct Vec: Readable {
+ var __buffer: ByteBuffer! { __p.bb }
+
+ static var size = 12
+ static var alignment = 4
+ private var __p: Struct
+ init(_ fb: ByteBuffer, o: Int32) { __p = Struct(bb: fb, position: o) }
+ var x: Float32 { return __p.readBuffer(of: Float32.self, at: 0)}
+ var y: Float32 { return __p.readBuffer(of: Float32.self, at: 4)}
+ var z: Float32 { return __p.readBuffer(of: Float32.self, at: 8)}
+}
+
+struct VPointerVec {
+
+ private var __t: Table
+
+ private init(_ t: Table) {
+ __t = t
+ }
+
+ var vec: Vec? { let o = __t.offset(4); return o == 0 ? nil : Vec(__t.bb, o: o + __t.postion) }
+
+ @inlinable static func getRootAsCountry(_ bb: ByteBuffer) -> VPointerVec {
+ return VPointerVec(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
+ }
+
+ static func startVPointer(b: FlatBufferBuilder) -> UOffset { b.startTable(with: 1) }
+ static func finish(b: FlatBufferBuilder, s: UOffset) -> Offset<UOffset> { return Offset(offset: b.endTable(at: s)) }
+
+ static func createVPointer(b: FlatBufferBuilder, o: Offset<UOffset>) -> Offset<UOffset> {
+ let s = VPointerVec.startVPointer(b: b)
+ b.add(structOffset: 0)
+ return VPointerVec.finish(b: b, s: s)
+ }
+}
+
+enum Color: UInt32 { case red = 0, green = 1, blue = 2 }
+
+private let VPointerVectorVecOffsets: (color: VOffset, vector: VOffset) = (0, 1)
+
+struct VPointerVectorVec {
+
+ static func startVPointer(b: FlatBufferBuilder) -> UOffset { b.startTable(with: 2) }
+
+ static func addVector(b: FlatBufferBuilder, v: Offset<UOffset>) { b.add(offset: v, at: VPointerVectorVecOffsets.vector) }
+
+ static func addColor(b: FlatBufferBuilder, color: Color) { b.add(element: color.rawValue, def: 1, at: VPointerVectorVecOffsets.color) }
+
+ static func finish(b: FlatBufferBuilder, s: UOffset) -> Offset<UOffset> { return Offset(offset: b.endTable(at: s)) }
+
+ static func createVPointer(b: FlatBufferBuilder, color: Color = .green, v: Offset<UOffset>) -> Offset<UOffset> {
+ let s = VPointerVectorVec.startVPointer(b: b)
+ VPointerVectorVec.addVector(b: b, v: v)
+ VPointerVectorVec.addColor(b: b, color: color)
+ return VPointerVectorVec.finish(b: b, s: s)
+ }
+}
+
+enum Color2: Int32 { case red = 0, green = 1, blue = 2 }
+enum Test: Byte { case none = 0, vec = 1 }
+
+func createVec2(x: Float32 = 0, y: Float32 = 0, z: Float32 = 0, color: Color2) -> UnsafeMutableRawPointer {
+ let memory = UnsafeMutableRawPointer.allocate(byteCount: Vec2.size, alignment: Vec2.alignment)
+ memory.initializeMemory(as: UInt8.self, repeating: 0, count: Vec2.size)
+ memory.storeBytes(of: x, toByteOffset: 0, as: Float32.self)
+ memory.storeBytes(of: y, toByteOffset: 4, as: Float32.self)
+ memory.storeBytes(of: z, toByteOffset: 8, as: Float32.self)
+ return memory
+}
+
+struct Vec2: Readable {
+ var __buffer: ByteBuffer! { __p.bb }
+
+ static var size = 13
+ static var alignment = 4
+ private var __p: Struct
+
+ init(_ fb: ByteBuffer, o: Int32) { __p = Struct(bb: fb, position: o) }
+ var c: Color2 { return Color2(rawValue: __p.readBuffer(of: Int32.self, at: 12)) ?? .red }
+ var x: Float32 { return __p.readBuffer(of: Float32.self, at: 0)}
+ var y: Float32 { return __p.readBuffer(of: Float32.self, at: 4)}
+ var z: Float32 { return __p.readBuffer(of: Float32.self, at: 8)}
+}
+
+struct VPointerVec2 {
+
+ private var __t: Table
+
+ private init(_ t: Table) {
+ __t = t
+ }
+
+ var vec: Vec2? { let o = __t.offset(4); return o == 0 ? nil : Vec2( __t.bb, o: o + __t.postion) }
+ var UType: Test? { let o = __t.offset(6); return o == 0 ? Test.none : Test(rawValue: __t.readBuffer(of: Byte.self, at: o)) }
+
+ @inlinable static func getRootAsCountry(_ bb: ByteBuffer) -> VPointerVec2 {
+ return VPointerVec2(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
+ }
+
+ static func startVPointer(b: FlatBufferBuilder) -> UOffset { b.startTable(with: 3) }
+ static func finish(b: FlatBufferBuilder, s: UOffset) -> Offset<UOffset> { return Offset(offset: b.endTable(at: s)) }
+
+ static func createVPointer(b: FlatBufferBuilder, o: Offset<UOffset>, type: Test) -> Offset<UOffset> {
+ let s = VPointerVec2.startVPointer(b: b)
+ b.add(structOffset: 0)
+ b.add(element: type.rawValue, def: Test.none.rawValue, at: 1)
+ b.add(offset: o, at: 2)
+ return VPointerVec2.finish(b: b, s: s)
+ }
+}
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersTests.swift
new file mode 100644
index 00000000..ffd1f455
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersTests.swift
@@ -0,0 +1,120 @@
+import XCTest
+@testable import FlatBuffers
+
+final class FlatBuffersTests: XCTestCase {
+
+ let country = "Norway"
+
+ func testEndian() { XCTAssertEqual(isLitteEndian, true) }
+
+ func testOffset() {
+ let o = Offset<Int>()
+ let b = Offset<Int>(offset: 1)
+ XCTAssertEqual(o.isEmpty, true)
+ XCTAssertEqual(b.isEmpty, false)
+ }
+
+ func testCreateString() {
+ let helloWorld = "Hello, world!"
+ let b = FlatBufferBuilder(initialSize: 16)
+ XCTAssertEqual(b.create(string: country).o, 12)
+ XCTAssertEqual(b.create(string: helloWorld).o, 32)
+ b.clear()
+ XCTAssertEqual(b.create(string: helloWorld).o, 20)
+ XCTAssertEqual(b.create(string: country).o, 32)
+ b.clear()
+ XCTAssertEqual(b.create(string: String(repeating: "a", count: 257)).o, 264)
+ }
+
+ func testStartTable() {
+ let b = FlatBufferBuilder(initialSize: 16)
+ XCTAssertNoThrow(b.startTable(with: 0))
+ b.clear()
+ XCTAssertEqual(b.create(string: country).o, 12)
+ XCTAssertEqual(b.startTable(with: 0), 12)
+ }
+
+ func testCreate() {
+ var b = FlatBufferBuilder(initialSize: 16)
+ _ = Country.createCountry(builder: &b, name: country, log: 200, lan: 100)
+ let v: [UInt8] = [10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 12, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
+ XCTAssertEqual(b.sizedByteArray, v)
+ }
+
+ func testCreateFinish() {
+ var b = FlatBufferBuilder(initialSize: 16)
+ let countryOff = Country.createCountry(builder: &b, name: country, log: 200, lan: 100)
+ b.finish(offset: countryOff)
+ let v: [UInt8] = [16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 12, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
+ XCTAssertEqual(b.sizedByteArray, v)
+ }
+
+ func testCreateFinishWithPrefix() {
+ var b = FlatBufferBuilder(initialSize: 16)
+ let countryOff = Country.createCountry(builder: &b, name: country, log: 200, lan: 100)
+ b.finish(offset: countryOff, addPrefix: true)
+ let v: [UInt8] = [44, 0, 0, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 12, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
+ XCTAssertEqual(b.sizedByteArray, v)
+ }
+
+ func testReadCountry() {
+ let v: [UInt8] = [16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 12, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
+ let buffer = ByteBuffer(bytes: v)
+ let c = Country.getRootAsCountry(buffer)
+ XCTAssertEqual(c.lan, 100)
+ XCTAssertEqual(c.log, 200)
+ XCTAssertEqual(c.nameVector, [78, 111, 114, 119, 97, 121])
+ XCTAssertEqual(c.name, country)
+ }
+}
+
+class Country {
+
+ static let offsets: (name: VOffset, lan: VOffset, lng: VOffset) = (0, 1, 2)
+ private var __t: Table
+
+ private init(_ t: Table) {
+ __t = t
+ }
+
+ var lan: Int32 { let o = __t.offset(6); return o == 0 ? 0 : __t.readBuffer(of: Int32.self, at: o) }
+ var log: Int32 { let o = __t.offset(8); return o == 0 ? 0 : __t.readBuffer(of: Int32.self, at: o) }
+ var nameVector: [UInt8]? { return __t.getVector(at: 4) }
+ var name: String? { let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) }
+
+ @inlinable static func getRootAsCountry(_ bb: ByteBuffer) -> Country {
+ return Country(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
+ }
+
+ @inlinable static func createCountry(builder: inout FlatBufferBuilder, name: String, log: Int32, lan: Int32) -> Offset<Country> {
+ return createCountry(builder: &builder, offset: builder.create(string: name), log: log, lan: lan)
+ }
+
+ @inlinable static func createCountry(builder: inout FlatBufferBuilder, offset: Offset<String>, log: Int32, lan: Int32) -> Offset<Country> {
+ let _start = builder.startTable(with: 3)
+ Country.add(builder: &builder, lng: log)
+ Country.add(builder: &builder, lan: lan)
+ Country.add(builder: &builder, name: offset)
+ return Country.end(builder: &builder, startOffset: _start)
+ }
+
+ @inlinable static func end(builder: inout FlatBufferBuilder, startOffset: UOffset) -> Offset<Country> {
+ return Offset(offset: builder.endTable(at: startOffset))
+ }
+
+ @inlinable static func add(builder: inout FlatBufferBuilder, name: String) {
+ add(builder: &builder, name: builder.create(string: name))
+ }
+
+ @inlinable static func add(builder: inout FlatBufferBuilder, name: Offset<String>) {
+ builder.add(offset: name, at: Country.offsets.name)
+ }
+
+ @inlinable static func add(builder: inout FlatBufferBuilder, lan: Int32) {
+ builder.add(element: lan, def: 0, at: Country.offsets.lan)
+ }
+
+ @inlinable static func add(builder: inout FlatBufferBuilder, lng: Int32) {
+ builder.add(element: lng, def: 0, at: Country.offsets.lng)
+ }
+}
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersUnionTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersUnionTests.swift
new file mode 100644
index 00000000..f4483f03
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersUnionTests.swift
@@ -0,0 +1,228 @@
+import XCTest
+@testable import FlatBuffers
+
+final class FlatBuffersUnionTests: XCTestCase {
+
+ func testCreateMonstor() {
+
+ var b = FlatBufferBuilder(initialSize: 20)
+ let dmg: Int16 = 5
+ let str = "Axe"
+ let axe = b.create(string: str)
+ let weapon = Weapon.createWeapon(builder: &b, offset: axe, dmg: dmg)
+ let weapons = b.createVector(ofOffsets: [weapon])
+ let root = Monster.createMonster(builder: &b,
+ offset: weapons,
+ equipment: .Weapon,
+ equippedOffset: weapon.o)
+ b.finish(offset: root)
+ let buffer = b.sizedByteArray
+ XCTAssertEqual(buffer, [16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 8, 0, 7, 0, 12, 0, 10, 0, 0, 0, 0, 0, 0, 1, 8, 0, 0, 0, 20, 0, 0, 0, 1, 0, 0, 0, 12, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 5, 0, 4, 0, 0, 0, 3, 0, 0, 0, 65, 120, 101, 0])
+ let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buffer))
+ XCTAssertEqual(monster.weapon(at: 0)?.dmg, dmg)
+ XCTAssertEqual(monster.weapon(at: 0)?.name, str)
+ XCTAssertEqual(monster.weapon(at: 0)?.nameVector, [65, 120, 101])
+ let p: Weapon? = monster.equiped()
+ XCTAssertEqual(p?.dmg, dmg)
+ XCTAssertEqual(p?.name, str)
+ XCTAssertEqual(p?.nameVector, [65, 120, 101])
+ }
+
+ func testEndTableFinish() {
+ var builder = FlatBufferBuilder(initialSize: 20)
+ let sword = builder.create(string: "Sword")
+ let axe = builder.create(string: "Axe")
+ let weaponOne = Weapon.createWeapon(builder: &builder, offset: sword, dmg: 3)
+ let weaponTwo = Weapon.createWeapon(builder: &builder, offset: axe, dmg: 5)
+ let name = builder.create(string: "Orc")
+ let inventory: [UInt8] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+ let inv = builder.createVector(inventory, size: 10)
+ let weapons = builder.createVector(ofOffsets: [weaponOne, weaponTwo])
+ var vecArray: [UnsafeMutableRawPointer] = []
+ vecArray.append(createVecWrite(x: 4.0, y: 5.0, z: 6.0))
+ vecArray.append(createVecWrite(x: 1.0, y: 2.0, z: 3.0))
+ let path = builder.createVector(structs: vecArray, type: Vec.self)
+ let orc = FinalMonster.createMonster(builder: &builder,
+ position: builder.create(struct: createVecWrite(x: 1.0, y: 2.0, z: 3.0), type: Vec.self),
+ hp: 300,
+ name: name,
+ inventory: inv,
+ color: .red,
+ weapons: weapons,
+ equipment: .Weapon,
+ equippedOffset: weaponTwo,
+ path: path)
+ builder.finish(offset: orc)
+ XCTAssertEqual(builder.sizedByteArray, [32, 0, 0, 0, 0, 0, 26, 0, 36, 0, 36, 0, 0, 0, 34, 0, 28, 0, 0, 0, 24, 0, 23, 0, 16, 0, 15, 0, 8, 0, 4, 0, 26, 0, 0, 0, 44, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 1, 60, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 76, 0, 0, 0, 0, 0, 44, 1, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 2, 0, 0, 0, 0, 0, 128, 64, 0, 0, 160, 64, 0, 0, 192, 64, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 64, 64, 2, 0, 0, 0, 52, 0, 0, 0, 28, 0, 0, 0, 10, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 3, 0, 0, 0, 79, 114, 99, 0, 244, 255, 255, 255, 0, 0, 5, 0, 24, 0, 0, 0, 8, 0, 12, 0, 8, 0, 6, 0, 8, 0, 0, 0, 0, 0, 3, 0, 12, 0, 0, 0, 3, 0, 0, 0, 65, 120, 101, 0, 5, 0, 0, 0, 83, 119, 111, 114, 100, 0, 0, 0])
+ }
+
+ func testEnumVector() {
+ let vectorOfEnums: [ColorsNameSpace.RGB] = [.blue, .green]
+
+ let builder = FlatBufferBuilder(initialSize: 1)
+ let off = builder.createVector(vectorOfEnums)
+ let start = ColorsNameSpace.Monster.startMonster(builder)
+ ColorsNameSpace.Monster.add(colors: off, builder)
+ let end = ColorsNameSpace.Monster.endMonster(builder, start: start)
+ builder.finish(offset: end)
+ XCTAssertEqual(builder.sizedByteArray, [12, 0, 0, 0, 0, 0, 6, 0, 8, 0, 4, 0, 6, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0])
+ let monster = ColorsNameSpace.Monster.getRootAsMonster(bb: builder.buffer)
+ XCTAssertEqual(monster.colorsCount, 2)
+ XCTAssertEqual(monster.colors(at: 0), .blue)
+ XCTAssertEqual(monster.colors(at: 1), .green)
+ }
+
+ func testUnionVector() {
+ let fb = FlatBufferBuilder()
+
+ let swordDmg: Int32 = 8
+ let attackStart = Attacker.startAttacker(fb)
+ Attacker.add(swordAttackDamage: swordDmg, fb)
+ let attack = Attacker.endAttacker(fb, start: attackStart)
+
+ let characterType: [Character] = [.belle, .mulan, .bookfan]
+ let characters = [
+ fb.create(struct: createBookReader(booksRead: 7), type: BookReader.self),
+ attack,
+ fb.create(struct: createBookReader(booksRead: 2), type: BookReader.self),
+ ]
+ let types = fb.createVector(characterType)
+ let characterVector = fb.createVector(ofOffsets: characters)
+ let end = Movie.createMovie(fb, vectorOfCharactersType: types, vectorOfCharacters: characterVector)
+ Movie.finish(fb, end: end)
+
+ let movie = Movie.getRootAsMovie(bb: fb.buffer)
+ XCTAssertEqual(movie.charactersTypeCount, Int32(characterType.count))
+ XCTAssertEqual(movie.charactersCount, Int32(characters.count))
+
+ for i in 0..<movie.charactersTypeCount {
+ XCTAssertEqual(movie.charactersType(at: i), characterType[Int(i)])
+ }
+
+ XCTAssertEqual(movie.characters(at: 0, type: BookReader.self)?.booksRead, 7)
+ XCTAssertEqual(movie.characters(at: 1, type: Attacker.self)?.swordAttackDamage, swordDmg)
+ XCTAssertEqual(movie.characters(at: 2, type: BookReader.self)?.booksRead, 2)
+ }
+}
+
+public enum ColorsNameSpace {
+
+enum RGB: Int32, Enum {
+ typealias T = Int32
+ static var byteSize: Int { return MemoryLayout<Int32>.size }
+ var value: Int32 { return self.rawValue }
+ case red = 0, green = 1, blue = 2
+}
+
+struct Monster: FlatBufferObject {
+ var __buffer: ByteBuffer! { _accessor.bb }
+
+ private var _accessor: Table
+ static func getRootAsMonster(bb: ByteBuffer) -> Monster { return Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ init(_ t: Table) { _accessor = t }
+ init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var colorsCount: Int32 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func colors(at index: Int32) -> ColorsNameSpace.RGB? { let o = _accessor.offset(4); return o == 0 ? ColorsNameSpace.RGB(rawValue: 0)! : ColorsNameSpace.RGB(rawValue: _accessor.directRead(of: Int32.self, offset: _accessor.vector(at: o) + index * 4)) }
+ static func startMonster(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
+ static func add(colors: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: colors, at: 0) }
+ static func endMonster(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+}
+}
+
+
+enum Equipment: Byte { case none, Weapon }
+
+enum Color3: Int8 { case red = 0, green, blue }
+
+struct FinalMonster {
+
+ @inlinable static func createMonster(builder: inout FlatBufferBuilder,
+ position: Offset<UOffset>,
+ hp: Int16,
+ name: Offset<String>,
+ inventory: Offset<UOffset>,
+ color: Color3,
+ weapons: Offset<UOffset>,
+ equipment: Equipment = .none,
+ equippedOffset: Offset<Weapon>,
+ path: Offset<UOffset>) -> Offset<Monster> {
+ let start = builder.startTable(with: 11)
+ builder.add(structOffset: 0)
+ builder.add(element: hp, def: 100, at: 2)
+ builder.add(offset: name, at: 3)
+ builder.add(offset: inventory, at: 5)
+ builder.add(element: color.rawValue, def: Color3.green.rawValue, at: 6)
+ builder.add(offset: weapons, at: 7)
+ builder.add(element: equipment.rawValue, def: Equipment.none.rawValue, at: 8)
+ builder.add(offset: equippedOffset, at: 9)
+ builder.add(offset: path, at: 10)
+ return Offset(offset: builder.endTable(at: start))
+ }
+}
+
+struct Monster {
+
+ private var __t: Table
+
+ init(_ fb: ByteBuffer, o: Int32) { __t = Table(bb: fb, position: o) }
+ init(_ t: Table) { __t = t }
+
+ func weapon(at index: Int32) -> Weapon? { let o = __t.offset(4); return o == 0 ? nil : Weapon.assign(__t.indirect(__t.vector(at: o) + (index * 4)), __t.bb) }
+
+ func equiped<T: FlatBufferObject>() -> T? {
+ let o = __t.offset(8); return o == 0 ? nil : __t.union(o)
+ }
+
+ static func getRootAsMonster(bb: ByteBuffer) -> Monster {
+ return Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
+ }
+
+ @inlinable static func createMonster(builder: inout FlatBufferBuilder,
+ offset: Offset<UOffset>,
+ equipment: Equipment = .none,
+ equippedOffset: UOffset) -> Offset<Monster> {
+ let start = builder.startTable(with: 3)
+ builder.add(element: equippedOffset, def: 0, at: 2)
+ builder.add(offset: offset, at: 0)
+ builder.add(element: equipment.rawValue, def: Equipment.none.rawValue, at: 1)
+ return Offset(offset: builder.endTable(at: start))
+ }
+}
+
+struct Weapon: FlatBufferObject {
+
+ var __buffer: ByteBuffer! { __t.bb }
+
+ static let offsets: (name: VOffset, dmg: VOffset) = (0, 1)
+ private var __t: Table
+
+ init(_ t: Table) { __t = t }
+ init(_ fb: ByteBuffer, o: Int32) { __t = Table(bb: fb, position: o)}
+
+ var dmg: Int16 { let o = __t.offset(6); return o == 0 ? 0 : __t.readBuffer(of: Int16.self, at: o) }
+ var nameVector: [UInt8]? { return __t.getVector(at: 4) }
+ var name: String? { let o = __t.offset(4); return o == 0 ? nil : __t.string(at: o) }
+
+ static func assign(_ i: Int32, _ bb: ByteBuffer) -> Weapon { return Weapon(Table(bb: bb, position: i)) }
+
+ @inlinable static func createWeapon(builder: inout FlatBufferBuilder, offset: Offset<String>, dmg: Int16) -> Offset<Weapon> {
+ let _start = builder.startTable(with: 2)
+ Weapon.add(builder: &builder, name: offset)
+ Weapon.add(builder: &builder, dmg: dmg)
+ return Weapon.end(builder: &builder, startOffset: _start)
+ }
+
+ @inlinable static func end(builder: inout FlatBufferBuilder, startOffset: UOffset) -> Offset<Weapon> {
+ return Offset(offset: builder.endTable(at: startOffset))
+ }
+
+ @inlinable static func add(builder: inout FlatBufferBuilder, name: Offset<String>) {
+ builder.add(offset: name, at: Weapon.offsets.name)
+ }
+
+ @inlinable static func add(builder: inout FlatBufferBuilder, dmg: Int16) {
+ builder.add(element: dmg, def: 0, at: Weapon.offsets.dmg)
+ }
+}
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift
new file mode 100644
index 00000000..0064c06f
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatBuffersVectorsTests.swift
@@ -0,0 +1,116 @@
+import XCTest
+@testable import FlatBuffers
+
+final class FlatBuffersVectors: XCTestCase {
+
+ func testCreatingTwoCountries() {
+ let norway = "Norway"
+ let denmark = "Denmark"
+ var b = FlatBufferBuilder(initialSize: 20)
+ let noStr = b.create(string: norway)
+ let deStr = b.create(string: denmark)
+ let n = Country.createCountry(builder: &b, offset: noStr, log: 888, lan: 700)
+ let d = Country.createCountry(builder: &b, offset: deStr, log: 200, lan: 100)
+ let vector = [n, d]
+ let vectorOffset = b.createVector(ofOffsets: vector)
+ b.finish(offset: vectorOffset)
+ XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 2, 0, 0, 0, 48, 0, 0, 0, 16, 0, 0, 0, 0, 0, 10, 0, 18, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 40, 0, 0, 0, 100, 0, 0, 0, 200, 0, 0, 0, 0, 0, 10, 0, 16, 0, 4, 0, 8, 0, 12, 0, 10, 0, 0, 0, 24, 0, 0, 0, 188, 2, 0, 0, 120, 3, 0, 0, 7, 0, 0, 0, 68, 101, 110, 109, 97, 114, 107, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0])
+ }
+
+ func testCreateIntArray() {
+ let numbers: [Int32] = [1, 2, 3, 4, 5]
+ let b = FlatBufferBuilder(initialSize: 20)
+ let o = b.createVector(numbers, size: numbers.count)
+ b.finish(offset: o)
+ XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0, 5, 0, 0, 0])
+ }
+
+ func testCreateEmptyIntArray() {
+ let numbers: [Int32] = []
+ let b = FlatBufferBuilder(initialSize: 20)
+ let o = b.createVector(numbers, size: numbers.count)
+ b.finish(offset: o)
+ XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 0, 0, 0, 0])
+ }
+
+ func testCreateVectorOfStrings() {
+ let strs = ["Denmark", "Norway"]
+ let b = FlatBufferBuilder(initialSize: 20)
+ let o = b.createVector(ofStrings: strs)
+ b.finish(offset: o)
+ XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 2, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0, 7, 0, 0, 0, 68, 101, 110, 109, 97, 114, 107, 0])
+ }
+ func testCreateSharedStringVector() {
+ let norway = "Norway"
+ let denmark = "Denmark"
+ let b = FlatBufferBuilder(initialSize: 20)
+ let noStr = b.createShared(string: norway)
+ let deStr = b.createShared(string: denmark)
+ let _noStr = b.createShared(string: norway)
+ let _deStr = b.createShared(string: denmark)
+ let v = [noStr, deStr, _noStr, _deStr]
+ let end = b.createVector(ofOffsets: v)
+ b.finish(offset: end)
+ XCTAssertEqual(b.sizedByteArray, [4, 0, 0, 0, 4, 0, 0, 0, 28, 0, 0, 0, 12, 0, 0, 0, 20, 0, 0, 0, 4, 0, 0, 0, 7, 0, 0, 0, 68, 101, 110, 109, 97, 114, 107, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0])
+ }
+
+ func testReadInt32Array() {
+ let data: [Int32] = [1, 2, 3, 4, 5]
+ let b = FlatBufferBuilder(initialSize: 20)
+ let v = Numbers.createNumbersVector(b: b, array: data)
+ let end = Numbers.createNumbers(b: b, o: v)
+ b.finish(offset: end)
+ let number = Numbers.getRootAsNumbers(ByteBuffer(bytes: b.sizedByteArray))
+ XCTAssertEqual(number.vArrayInt32, [1, 2, 3, 4, 5])
+ }
+
+ func testReadDoubleArray() {
+ let data: [Double] = [1, 2, 3, 4, 5]
+ let b = FlatBufferBuilder(initialSize: 20)
+ let v = Numbers.createNumbersVector(b: b, array: data)
+ let end = Numbers.createNumbers(b: b, o: v)
+ b.finish(offset: end)
+ let number = Numbers.getRootAsNumbers(ByteBuffer(bytes: b.sizedByteArray))
+ XCTAssertEqual(number.vArrayDouble, [1, 2, 3, 4, 5])
+ }
+}
+
+struct Numbers {
+
+ private var __t: Table
+
+ private init(_ t: Table) {
+ __t = t
+ }
+
+ @inlinable static func getRootAsNumbers(_ bb: ByteBuffer) -> Numbers {
+ return Numbers(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: 0))))
+ }
+
+ var vArrayInt: [Int]? { return __t.getVector(at: 4) }
+ var vArrayInt32: [Int32]? { return __t.getVector(at: 4) }
+ var vArrayDouble: [Double]? { return __t.getVector(at: 4) }
+ var vArrayFloat: [Float32]? { return __t.getVector(at: 4) }
+
+ static func createNumbersVector(b: FlatBufferBuilder, array: [Int]) -> Offset<UOffset> {
+ return b.createVector(array, size: array.count)
+ }
+
+ static func createNumbersVector(b: FlatBufferBuilder, array: [Int32]) -> Offset<UOffset> {
+ return b.createVector(array, size: array.count)
+ }
+
+ static func createNumbersVector(b: FlatBufferBuilder, array: [Double]) -> Offset<UOffset> {
+ return b.createVector(array, size: array.count)
+ }
+
+ static func createNumbersVector(b: FlatBufferBuilder, array: [Float32]) -> Offset<UOffset> {
+ return b.createVector(array, size: array.count)
+ }
+
+ static func createNumbers(b: FlatBufferBuilder, o: Offset<UOffset>) -> Offset<UOffset> {
+ let start = b.startTable(with: 1)
+ b.add(offset: o, at: 0)
+ return Offset(offset: b.endTable(at: start))
+ }
+}
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersDoubleTests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersDoubleTests.swift
new file mode 100644
index 00000000..c044c5ca
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/FlatbuffersDoubleTests.swift
@@ -0,0 +1,76 @@
+import XCTest
+@testable import FlatBuffers
+
+final class FlatBuffersDoubleTests: XCTestCase {
+
+ let country = "Norway"
+
+ func testCreateCountry() {
+ var b = FlatBufferBuilder(initialSize: 16)
+ _ = CountryDouble.createCountry(builder: &b, name: country, log: 200, lan: 100)
+ let v: [UInt8] = [10, 0, 28, 0, 4, 0, 8, 0, 16, 0, 10, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 64, 0, 0, 0, 0, 0, 0, 105, 64, 0, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
+ XCTAssertEqual(b.sizedByteArray, v)
+ }
+
+ func testCreateFinish() {
+ var b = FlatBufferBuilder(initialSize: 16)
+ let countryOff = CountryDouble.createCountry(builder: &b, name: country, log: 200, lan: 100)
+ b.finish(offset: countryOff)
+ let v: [UInt8] = [16, 0, 0, 0, 0, 0, 10, 0, 28, 0, 4, 0, 8, 0, 16, 0, 10, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 64, 0, 0, 0, 0, 0, 0, 105, 64, 0, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
+ XCTAssertEqual(b.sizedByteArray, v)
+ }
+
+ func testCreateFinishWithPrefix() {
+ var b = FlatBufferBuilder(initialSize: 16)
+ let countryOff = CountryDouble.createCountry(builder: &b, name: country, log: 200, lan: 100)
+ b.finish(offset: countryOff, addPrefix: true)
+ let v: [UInt8] = [60, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 28, 0, 4, 0, 8, 0, 16, 0, 10, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 64, 0, 0, 0, 0, 0, 0, 105, 64, 0, 0, 0, 0, 6, 0, 0, 0, 78, 111, 114, 119, 97, 121, 0, 0]
+ XCTAssertEqual(b.sizedByteArray, v)
+ }
+}
+
+class CountryDouble {
+
+ static let offsets: (name: VOffset, lan: VOffset, lng: VOffset) = (4,6,8)
+
+ private var table: Table
+
+ private init(table t: Table) { table = t }
+
+ static func getRootAsCountry(_ bb: ByteBuffer) -> CountryDouble {
+ let pos = bb.read(def: Int32.self, position: Int(bb.size))
+ return CountryDouble(table: Table(bb: bb, position: Int32(pos)))
+ }
+
+ static func createCountry(builder: inout FlatBufferBuilder, name: String, log: Double, lan: Double) -> Offset<Country> {
+ return createCountry(builder: &builder, offset: builder.create(string: name), log: log, lan: lan)
+ }
+
+ static func createCountry(builder: inout FlatBufferBuilder, offset: Offset<String>, log: Double, lan: Double) -> Offset<Country> {
+ let _start = builder.startTable(with: 3)
+ CountryDouble.add(builder: &builder, lng: log)
+ CountryDouble.add(builder: &builder, lan: lan)
+ CountryDouble.add(builder: &builder, name: offset)
+ return CountryDouble.end(builder: &builder, startOffset: _start)
+ }
+
+ static func end(builder: inout FlatBufferBuilder, startOffset: UOffset) -> Offset<Country> {
+ return Offset(offset: builder.endTable(at: startOffset))
+ }
+
+ static func add(builder: inout FlatBufferBuilder, name: String) {
+ add(builder: &builder, name: builder.create(string: name))
+ }
+
+ static func add(builder: inout FlatBufferBuilder, name: Offset<String>) {
+ builder.add(offset: name, at: Country.offsets.name)
+ }
+
+ static func add(builder: inout FlatBufferBuilder, lan: Double) {
+ builder.add(element: lan, def: 0, at: Country.offsets.lan)
+ }
+
+ static func add(builder: inout FlatBufferBuilder, lng: Double) {
+ builder.add(element: lng, def: 0, at: Country.offsets.lng)
+ }
+}
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/XCTestManifests.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/XCTestManifests.swift
new file mode 100644
index 00000000..18ad6a06
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/XCTestManifests.swift
@@ -0,0 +1,95 @@
+#if !canImport(ObjectiveC)
+import XCTest
+
+extension FlatBuffersDoubleTests {
+ // DO NOT MODIFY: This is autogenerated, use:
+ // `swift test --generate-linuxmain`
+ // to regenerate.
+ static let __allTests__FlatBuffersDoubleTests = [
+ ("testCreateCountry", testCreateCountry),
+ ("testCreateFinish", testCreateFinish),
+ ("testCreateFinishWithPrefix", testCreateFinishWithPrefix),
+ ]
+}
+
+extension FlatBuffersMonsterWriterTests {
+ // DO NOT MODIFY: This is autogenerated, use:
+ // `swift test --generate-linuxmain`
+ // to regenerate.
+ static let __allTests__FlatBuffersMonsterWriterTests = [
+ ("testCreateMonster", testCreateMonster),
+ ("testCreateMonsterPrefixed", testCreateMonsterPrefixed),
+ ("testCreateMonsterResizedBuffer", testCreateMonsterResizedBuffer),
+ ("testData", testData),
+ ("testReadFromOtherLangagues", testReadFromOtherLangagues),
+ ]
+}
+
+extension FlatBuffersStructsTests {
+ // DO NOT MODIFY: This is autogenerated, use:
+ // `swift test --generate-linuxmain`
+ // to regenerate.
+ static let __allTests__FlatBuffersStructsTests = [
+ ("testCreatingEnums", testCreatingEnums),
+ ("testCreatingStruct", testCreatingStruct),
+ ("testCreatingVectorStruct", testCreatingVectorStruct),
+ ("testCreatingVectorStructWithForcedDefaults", testCreatingVectorStructWithForcedDefaults),
+ ("testReadingStruct", testReadingStruct),
+ ("testReadingStructWithEnums", testReadingStructWithEnums),
+ ]
+}
+
+extension FlatBuffersTests {
+ // DO NOT MODIFY: This is autogenerated, use:
+ // `swift test --generate-linuxmain`
+ // to regenerate.
+ static let __allTests__FlatBuffersTests = [
+ ("testCreate", testCreate),
+ ("testCreateFinish", testCreateFinish),
+ ("testCreateFinishWithPrefix", testCreateFinishWithPrefix),
+ ("testCreateString", testCreateString),
+ ("testEndian", testEndian),
+ ("testOffset", testOffset),
+ ("testReadCountry", testReadCountry),
+ ("testStartTable", testStartTable),
+ ]
+}
+
+extension FlatBuffersUnionTests {
+ // DO NOT MODIFY: This is autogenerated, use:
+ // `swift test --generate-linuxmain`
+ // to regenerate.
+ static let __allTests__FlatBuffersUnionTests = [
+ ("testCreateMonstor", testCreateMonstor),
+ ("testEndTableFinish", testEndTableFinish),
+ ("testEnumVector", testEnumVector),
+ ("testUnionVector", testUnionVector),
+ ]
+}
+
+extension FlatBuffersVectors {
+ // DO NOT MODIFY: This is autogenerated, use:
+ // `swift test --generate-linuxmain`
+ // to regenerate.
+ static let __allTests__FlatBuffersVectors = [
+ ("testCreateEmptyIntArray", testCreateEmptyIntArray),
+ ("testCreateIntArray", testCreateIntArray),
+ ("testCreateSharedStringVector", testCreateSharedStringVector),
+ ("testCreateVectorOfStrings", testCreateVectorOfStrings),
+ ("testCreatingTwoCountries", testCreatingTwoCountries),
+ ("testReadDoubleArray", testReadDoubleArray),
+ ("testReadInt32Array", testReadInt32Array),
+ ]
+}
+
+public func __allTests() -> [XCTestCaseEntry] {
+ return [
+ testCase(FlatBuffersDoubleTests.__allTests__FlatBuffersDoubleTests),
+ testCase(FlatBuffersMonsterWriterTests.__allTests__FlatBuffersMonsterWriterTests),
+ testCase(FlatBuffersStructsTests.__allTests__FlatBuffersStructsTests),
+ testCase(FlatBuffersTests.__allTests__FlatBuffersTests),
+ testCase(FlatBuffersUnionTests.__allTests__FlatBuffersUnionTests),
+ testCase(FlatBuffersVectors.__allTests__FlatBuffersVectors),
+ ]
+}
+#endif
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test_generated.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test_generated.swift
new file mode 100644
index 00000000..461df126
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test_generated.swift
@@ -0,0 +1,718 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import FlatBuffers
+
+public enum MyGame {
+public enum Example {
+
+/// Composite components of Monster color.
+public enum Color: UInt8, Enum {
+ public typealias T = UInt8
+ public static var byteSize: Int { return MemoryLayout<UInt8>.size }
+ public var value: UInt8 { return self.rawValue }
+ case red = 1
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
+ case green = 2
+ /// \brief color Blue (1u << 3)
+ case blue = 8
+
+
+ public static var max: Color { return .blue }
+ public static var min: Color { return .red }
+}
+
+public enum Race: Int8, Enum {
+ public typealias T = Int8
+ public static var byteSize: Int { return MemoryLayout<Int8>.size }
+ public var value: Int8 { return self.rawValue }
+ case none = -1
+ case human = 0
+ case dwarf = 1
+ case elf = 2
+
+
+ public static var max: Race { return .elf }
+ public static var min: Race { return .none }
+}
+
+public enum Any_: UInt8, Enum {
+ public typealias T = UInt8
+ public static var byteSize: Int { return MemoryLayout<UInt8>.size }
+ public var value: UInt8 { return self.rawValue }
+ case none = 0
+ case monster = 1
+ case testsimpletablewithenum = 2
+ case mygame_example2_monster = 3
+
+
+ public static var max: Any_ { return .mygame_example2_monster }
+ public static var min: Any_ { return .none }
+}
+
+public enum AnyUniqueAliases: UInt8, Enum {
+ public typealias T = UInt8
+ public static var byteSize: Int { return MemoryLayout<UInt8>.size }
+ public var value: UInt8 { return self.rawValue }
+ case none = 0
+ case m = 1
+ case ts = 2
+ case m2 = 3
+
+
+ public static var max: AnyUniqueAliases { return .m2 }
+ public static var min: AnyUniqueAliases { return .none }
+}
+
+public enum AnyAmbiguousAliases: UInt8, Enum {
+ public typealias T = UInt8
+ public static var byteSize: Int { return MemoryLayout<UInt8>.size }
+ public var value: UInt8 { return self.rawValue }
+ case none = 0
+ case m1 = 1
+ case m2 = 2
+ case m3 = 3
+
+
+ public static var max: AnyAmbiguousAliases { return .m3 }
+ public static var min: AnyAmbiguousAliases { return .none }
+}
+
+public struct Test: Readable {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Struct
+ public static var size = 4
+ public static var alignment = 2
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
+
+ public var a: Int16 { return _accessor.readBuffer(of: Int16.self, at: 0) }
+ public func mutate(a: Int16) -> Bool { return _accessor.mutate(a, index: 0) }
+ public var b: Int8 { return _accessor.readBuffer(of: Int8.self, at: 2) }
+ public func mutate(b: Int8) -> Bool { return _accessor.mutate(b, index: 2) }
+}
+
+public struct Vec3: Readable {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Struct
+ public static var size = 32
+ public static var alignment = 8
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
+
+ public var x: Float32 { return _accessor.readBuffer(of: Float32.self, at: 0) }
+ public func mutate(x: Float32) -> Bool { return _accessor.mutate(x, index: 0) }
+ public var y: Float32 { return _accessor.readBuffer(of: Float32.self, at: 4) }
+ public func mutate(y: Float32) -> Bool { return _accessor.mutate(y, index: 4) }
+ public var z: Float32 { return _accessor.readBuffer(of: Float32.self, at: 8) }
+ public func mutate(z: Float32) -> Bool { return _accessor.mutate(z, index: 8) }
+ public var test1: Double { return _accessor.readBuffer(of: Double.self, at: 16) }
+ public func mutate(test1: Double) -> Bool { return _accessor.mutate(test1, index: 16) }
+ public var test2: MyGame.Example.Color { return MyGame.Example.Color(rawValue: _accessor.readBuffer(of: UInt8.self, at: 24)) ?? .red }
+ public var test3: MyGame.Example.Test { return MyGame.Example.Test(_accessor.bb, o: _accessor.postion + 26) }
+}
+
+public struct Ability: Readable {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Struct
+ public static var size = 8
+ public static var alignment = 4
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
+
+ public var id: UInt32 { return _accessor.readBuffer(of: UInt32.self, at: 0) }
+ public func mutate(id: UInt32) -> Bool { return _accessor.mutate(id, index: 0) }
+ public var distance: UInt32 { return _accessor.readBuffer(of: UInt32.self, at: 4) }
+ public func mutate(distance: UInt32) -> Bool { return _accessor.mutate(distance, index: 4) }
+}
+
+public static func createTest(a: Int16, b: Int8) -> UnsafeMutableRawPointer {
+ let memory = UnsafeMutableRawPointer.allocate(byteCount: Test.size, alignment: Test.alignment)
+ memory.initializeMemory(as: UInt8.self, repeating: 0, count: Test.size)
+ memory.storeBytes(of: a, toByteOffset: 0, as: Int16.self)
+ memory.storeBytes(of: b, toByteOffset: 2, as: Int8.self)
+ return memory
+}
+
+public static func createVec3(x: Float32, y: Float32, z: Float32, test1: Double, test2: MyGame.Example.Color, test3a: Int16, test3b: Int8) -> UnsafeMutableRawPointer {
+ let memory = UnsafeMutableRawPointer.allocate(byteCount: Vec3.size, alignment: Vec3.alignment)
+ memory.initializeMemory(as: UInt8.self, repeating: 0, count: Vec3.size)
+ memory.storeBytes(of: x, toByteOffset: 0, as: Float32.self)
+ memory.storeBytes(of: y, toByteOffset: 4, as: Float32.self)
+ memory.storeBytes(of: z, toByteOffset: 8, as: Float32.self)
+ memory.storeBytes(of: test1, toByteOffset: 16, as: Double.self)
+ memory.storeBytes(of: test2.rawValue, toByteOffset: 24, as: UInt8.self)
+ memory.storeBytes(of: test3a, toByteOffset: 26, as: Int16.self)
+ memory.storeBytes(of: test3b, toByteOffset: 28, as: Int8.self)
+ return memory
+}
+
+public static func createAbility(id: UInt32, distance: UInt32) -> UnsafeMutableRawPointer {
+ let memory = UnsafeMutableRawPointer.allocate(byteCount: Ability.size, alignment: Ability.alignment)
+ memory.initializeMemory(as: UInt8.self, repeating: 0, count: Ability.size)
+ memory.storeBytes(of: id, toByteOffset: 0, as: UInt32.self)
+ memory.storeBytes(of: distance, toByteOffset: 4, as: UInt32.self)
+ return memory
+}
+
+}
+
+// MARK: - Example
+
+
+public struct InParentNamespace: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MONS", addPrefix: prefix) }
+ public static func getRootAsInParentNamespace(bb: ByteBuffer) -> InParentNamespace { return InParentNamespace(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public static func startInParentNamespace(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 0) }
+ public static func endInParentNamespace(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createInParentNamespace(_ fbb: FlatBufferBuilder) -> Offset<UOffset> {
+ let __start = InParentNamespace.startInParentNamespace(fbb)
+ return InParentNamespace.endInParentNamespace(fbb, start: __start)
+ }
+}
+
+public enum Example2 {
+
+public struct Monster: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MONS", addPrefix: prefix) }
+ public static func getRootAsMonster(bb: ByteBuffer) -> Monster { return Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public static func startMonster(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 0) }
+ public static func endMonster(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createMonster(_ fbb: FlatBufferBuilder) -> Offset<UOffset> {
+ let __start = Monster.startMonster(fbb)
+ return Monster.endMonster(fbb, start: __start)
+ }
+}
+
+}
+
+// MARK: - Example2
+
+
+}
+extension MyGame.Example {
+
+public struct TestSimpleTableWithEnum: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MONS", addPrefix: prefix) }
+ public static func getRootAsTestSimpleTableWithEnum(bb: ByteBuffer) -> TestSimpleTableWithEnum { return TestSimpleTableWithEnum(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var color: MyGame.Example.Color { let o = _accessor.offset(4); return o == 0 ? .green : MyGame.Example.Color(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .green }
+ public func mutate(color: MyGame.Example.Color) -> Bool {let o = _accessor.offset(4); return _accessor.mutate(color.rawValue, index: o) }
+ public static func startTestSimpleTableWithEnum(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
+ public static func add(color: MyGame.Example.Color, _ fbb: FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 2, at: 0) }
+ public static func endTestSimpleTableWithEnum(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createTestSimpleTableWithEnum(_ fbb: FlatBufferBuilder,
+ color: MyGame.Example.Color = .green) -> Offset<UOffset> {
+ let __start = TestSimpleTableWithEnum.startTestSimpleTableWithEnum(fbb)
+ TestSimpleTableWithEnum.add(color: color, fbb)
+ return TestSimpleTableWithEnum.endTestSimpleTableWithEnum(fbb, start: __start)
+ }
+}
+
+public struct Stat: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MONS", addPrefix: prefix) }
+ public static func getRootAsStat(bb: ByteBuffer) -> Stat { return Stat(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var id: String? { let o = _accessor.offset(4); return o == 0 ? nil : _accessor.string(at: o) }
+ public var idSegmentArray: [UInt8]? { return _accessor.getVector(at: 4) }
+ public var val: Int64 { let o = _accessor.offset(6); return o == 0 ? 0 : _accessor.readBuffer(of: Int64.self, at: o) }
+ public func mutate(val: Int64) -> Bool {let o = _accessor.offset(6); return _accessor.mutate(val, index: o) }
+ public var count: UInt16 { let o = _accessor.offset(8); return o == 0 ? 0 : _accessor.readBuffer(of: UInt16.self, at: o) }
+ public func mutate(count: UInt16) -> Bool {let o = _accessor.offset(8); return _accessor.mutate(count, index: o) }
+ public static func startStat(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 3) }
+ public static func add(id: Offset<String>, _ fbb: FlatBufferBuilder) { fbb.add(offset: id, at: 0) }
+ public static func add(val: Int64, _ fbb: FlatBufferBuilder) { fbb.add(element: val, def: 0, at: 1) }
+ public static func add(count: UInt16, _ fbb: FlatBufferBuilder) { fbb.add(element: count, def: 0, at: 2) }
+ public static func endStat(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createStat(_ fbb: FlatBufferBuilder,
+ offsetOfId id: Offset<String> = Offset(),
+ val: Int64 = 0,
+ count: UInt16 = 0) -> Offset<UOffset> {
+ let __start = Stat.startStat(fbb)
+ Stat.add(id: id, fbb)
+ Stat.add(val: val, fbb)
+ Stat.add(count: count, fbb)
+ return Stat.endStat(fbb, start: __start)
+ }
+}
+
+public struct Referrable: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MONS", addPrefix: prefix) }
+ public static func getRootAsReferrable(bb: ByteBuffer) -> Referrable { return Referrable(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var id: UInt64 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.readBuffer(of: UInt64.self, at: o) }
+ public func mutate(id: UInt64) -> Bool {let o = _accessor.offset(4); return _accessor.mutate(id, index: o) }
+ public static func startReferrable(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
+ public static func add(id: UInt64, _ fbb: FlatBufferBuilder) { fbb.add(element: id, def: 0, at: 0) }
+ public static func endReferrable(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createReferrable(_ fbb: FlatBufferBuilder,
+ id: UInt64 = 0) -> Offset<UOffset> {
+ let __start = Referrable.startReferrable(fbb)
+ Referrable.add(id: id, fbb)
+ return Referrable.endReferrable(fbb, start: __start)
+ }
+ public static func sortVectorOfReferrable(offsets:[Offset<UOffset>], _ fbb: FlatBufferBuilder) -> Offset<UOffset> {
+ var off = offsets
+ off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: 4, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: 4, fbb: fbb.buffer), fbb: fbb.buffer) < 0 }
+ return fbb.createVector(ofOffsets: off)
+ }
+ fileprivate static func lookupByKey(vector: Int32, key: UInt64, fbb: ByteBuffer) -> Referrable? {
+ var span = fbb.read(def: Int32.self, position: Int(vector - 4))
+ var start: Int32 = 0
+ while span != 0 {
+ var middle = span / 2
+ let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)
+ let comp = fbb.read(def: UInt64.self, position: Int(Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: 4, fbb: fbb)))
+ if comp > 0 {
+ span = middle
+ } else if comp < 0 {
+ middle += 1
+ start += middle
+ span -= middle
+ } else {
+ return Referrable(fbb, o: tableOffset)
+ }
+ }
+ return nil
+ }
+}
+
+/// an example documentation comment: "monster object"
+public struct Monster: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MONS", addPrefix: prefix) }
+ public static func getRootAsMonster(bb: ByteBuffer) -> Monster { return Monster(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var pos: MyGame.Example.Vec3? { let o = _accessor.offset(4); return o == 0 ? nil : MyGame.Example.Vec3(_accessor.bb, o: o + _accessor.postion) }
+ public var mana: Int16 { let o = _accessor.offset(6); return o == 0 ? 150 : _accessor.readBuffer(of: Int16.self, at: o) }
+ public func mutate(mana: Int16) -> Bool {let o = _accessor.offset(6); return _accessor.mutate(mana, index: o) }
+ public var hp: Int16 { let o = _accessor.offset(8); return o == 0 ? 100 : _accessor.readBuffer(of: Int16.self, at: o) }
+ public func mutate(hp: Int16) -> Bool {let o = _accessor.offset(8); return _accessor.mutate(hp, index: o) }
+ public var name: String? { let o = _accessor.offset(10); return o == 0 ? nil : _accessor.string(at: o) }
+ public var nameSegmentArray: [UInt8]? { return _accessor.getVector(at: 10) }
+ public var inventoryCount: Int32 { let o = _accessor.offset(14); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func inventory(at index: Int32) -> UInt8 { let o = _accessor.offset(14); return o == 0 ? 0 : _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1) }
+ public var inventory: [UInt8] { return _accessor.getVector(at: 14) ?? [] }
+ public func mutate(inventory: UInt8, at index: Int32) -> Bool { let o = _accessor.offset(14); return _accessor.directMutate(inventory, index: _accessor.vector(at: o) + index * 1) }
+ public var color: MyGame.Example.Color { let o = _accessor.offset(16); return o == 0 ? .blue : MyGame.Example.Color(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .blue }
+ public func mutate(color: MyGame.Example.Color) -> Bool {let o = _accessor.offset(16); return _accessor.mutate(color.rawValue, index: o) }
+ public var testType: MyGame.Example.Any_ { let o = _accessor.offset(18); return o == 0 ? .none : MyGame.Example.Any_(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none }
+ public func test<T: FlatBufferObject>(type: T.Type) -> T? { let o = _accessor.offset(20); return o == 0 ? nil : _accessor.union(o) }
+ public var test4Count: Int32 { let o = _accessor.offset(22); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func test4(at index: Int32) -> MyGame.Example.Test? { let o = _accessor.offset(22); return o == 0 ? nil : MyGame.Example.Test(_accessor.bb, o: _accessor.vector(at: o) + index * 4) }
+ public var testarrayofstringCount: Int32 { let o = _accessor.offset(24); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func testarrayofstring(at index: Int32) -> String? { let o = _accessor.offset(24); return o == 0 ? nil : _accessor.directString(at: _accessor.vector(at: o) + index * 4) }
+ /// an example documentation comment: this will end up in the generated code
+ /// multiline too
+ public var testarrayoftablesCount: Int32 { let o = _accessor.offset(26); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func testarrayoftables(at index: Int32) -> MyGame.Example.Monster? { let o = _accessor.offset(26); return o == 0 ? nil : MyGame.Example.Monster(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
+ public func testarrayoftablesBy(key: String) -> MyGame.Example.Monster? { let o = _accessor.offset(26); return o == 0 ? nil : MyGame.Example.Monster.lookupByKey(vector: _accessor.vector(at: o), key: key, fbb: _accessor.bb) }
+ public var enemy: MyGame.Example.Monster? { let o = _accessor.offset(28); return o == 0 ? nil : MyGame.Example.Monster(_accessor.bb, o: _accessor.indirect(o + _accessor.postion)) }
+ public var testnestedflatbufferCount: Int32 { let o = _accessor.offset(30); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func testnestedflatbuffer(at index: Int32) -> UInt8 { let o = _accessor.offset(30); return o == 0 ? 0 : _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1) }
+ public var testnestedflatbuffer: [UInt8] { return _accessor.getVector(at: 30) ?? [] }
+ public func mutate(testnestedflatbuffer: UInt8, at index: Int32) -> Bool { let o = _accessor.offset(30); return _accessor.directMutate(testnestedflatbuffer, index: _accessor.vector(at: o) + index * 1) }
+ public var testempty: MyGame.Example.Stat? { let o = _accessor.offset(32); return o == 0 ? nil : MyGame.Example.Stat(_accessor.bb, o: _accessor.indirect(o + _accessor.postion)) }
+ public var testbool: Bool { let o = _accessor.offset(34); return o == 0 ? false : 0 != _accessor.readBuffer(of: Byte.self, at: o) }
+ public func mutate(testbool: Byte) -> Bool {let o = _accessor.offset(34); return _accessor.mutate(testbool, index: o) }
+ public var testhashs32Fnv1: Int32 { let o = _accessor.offset(36); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
+ public func mutate(testhashs32Fnv1: Int32) -> Bool {let o = _accessor.offset(36); return _accessor.mutate(testhashs32Fnv1, index: o) }
+ public var testhashu32Fnv1: UInt32 { let o = _accessor.offset(38); return o == 0 ? 0 : _accessor.readBuffer(of: UInt32.self, at: o) }
+ public func mutate(testhashu32Fnv1: UInt32) -> Bool {let o = _accessor.offset(38); return _accessor.mutate(testhashu32Fnv1, index: o) }
+ public var testhashs64Fnv1: Int64 { let o = _accessor.offset(40); return o == 0 ? 0 : _accessor.readBuffer(of: Int64.self, at: o) }
+ public func mutate(testhashs64Fnv1: Int64) -> Bool {let o = _accessor.offset(40); return _accessor.mutate(testhashs64Fnv1, index: o) }
+ public var testhashu64Fnv1: UInt64 { let o = _accessor.offset(42); return o == 0 ? 0 : _accessor.readBuffer(of: UInt64.self, at: o) }
+ public func mutate(testhashu64Fnv1: UInt64) -> Bool {let o = _accessor.offset(42); return _accessor.mutate(testhashu64Fnv1, index: o) }
+ public var testhashs32Fnv1a: Int32 { let o = _accessor.offset(44); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
+ public func mutate(testhashs32Fnv1a: Int32) -> Bool {let o = _accessor.offset(44); return _accessor.mutate(testhashs32Fnv1a, index: o) }
+ public var testhashu32Fnv1a: UInt32 { let o = _accessor.offset(46); return o == 0 ? 0 : _accessor.readBuffer(of: UInt32.self, at: o) }
+ public func mutate(testhashu32Fnv1a: UInt32) -> Bool {let o = _accessor.offset(46); return _accessor.mutate(testhashu32Fnv1a, index: o) }
+ public var testhashs64Fnv1a: Int64 { let o = _accessor.offset(48); return o == 0 ? 0 : _accessor.readBuffer(of: Int64.self, at: o) }
+ public func mutate(testhashs64Fnv1a: Int64) -> Bool {let o = _accessor.offset(48); return _accessor.mutate(testhashs64Fnv1a, index: o) }
+ public var testhashu64Fnv1a: UInt64 { let o = _accessor.offset(50); return o == 0 ? 0 : _accessor.readBuffer(of: UInt64.self, at: o) }
+ public func mutate(testhashu64Fnv1a: UInt64) -> Bool {let o = _accessor.offset(50); return _accessor.mutate(testhashu64Fnv1a, index: o) }
+ public var testarrayofboolsCount: Int32 { let o = _accessor.offset(52); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func testarrayofbools(at index: Int32) -> Bool { let o = _accessor.offset(52); return o == 0 ? true : 0 != _accessor.directRead(of: Byte.self, offset: _accessor.vector(at: o) + index * 1) }
+ public var testarrayofbools: [Byte] { return _accessor.getVector(at: 52) ?? [] }
+ public func mutate(testarrayofbools: Byte, at index: Int32) -> Bool { let o = _accessor.offset(52); return _accessor.directMutate(testarrayofbools, index: _accessor.vector(at: o) + index * 1) }
+ public var testf: Float32 { let o = _accessor.offset(54); return o == 0 ? 3.14159 : _accessor.readBuffer(of: Float32.self, at: o) }
+ public func mutate(testf: Float32) -> Bool {let o = _accessor.offset(54); return _accessor.mutate(testf, index: o) }
+ public var testf2: Float32 { let o = _accessor.offset(56); return o == 0 ? 3.0 : _accessor.readBuffer(of: Float32.self, at: o) }
+ public func mutate(testf2: Float32) -> Bool {let o = _accessor.offset(56); return _accessor.mutate(testf2, index: o) }
+ public var testf3: Float32 { let o = _accessor.offset(58); return o == 0 ? 0.0 : _accessor.readBuffer(of: Float32.self, at: o) }
+ public func mutate(testf3: Float32) -> Bool {let o = _accessor.offset(58); return _accessor.mutate(testf3, index: o) }
+ public var testarrayofstring2Count: Int32 { let o = _accessor.offset(60); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func testarrayofstring2(at index: Int32) -> String? { let o = _accessor.offset(60); return o == 0 ? nil : _accessor.directString(at: _accessor.vector(at: o) + index * 4) }
+ public var testarrayofsortedstructCount: Int32 { let o = _accessor.offset(62); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func testarrayofsortedstruct(at index: Int32) -> MyGame.Example.Ability? { let o = _accessor.offset(62); return o == 0 ? nil : MyGame.Example.Ability(_accessor.bb, o: _accessor.vector(at: o) + index * 8) }
+ public var flexCount: Int32 { let o = _accessor.offset(64); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func flex(at index: Int32) -> UInt8 { let o = _accessor.offset(64); return o == 0 ? 0 : _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1) }
+ public var flex: [UInt8] { return _accessor.getVector(at: 64) ?? [] }
+ public func mutate(flex: UInt8, at index: Int32) -> Bool { let o = _accessor.offset(64); return _accessor.directMutate(flex, index: _accessor.vector(at: o) + index * 1) }
+ public var test5Count: Int32 { let o = _accessor.offset(66); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func test5(at index: Int32) -> MyGame.Example.Test? { let o = _accessor.offset(66); return o == 0 ? nil : MyGame.Example.Test(_accessor.bb, o: _accessor.vector(at: o) + index * 4) }
+ public var vectorOfLongsCount: Int32 { let o = _accessor.offset(68); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vectorOfLongs(at index: Int32) -> Int64 { let o = _accessor.offset(68); return o == 0 ? 0 : _accessor.directRead(of: Int64.self, offset: _accessor.vector(at: o) + index * 8) }
+ public var vectorOfLongs: [Int64] { return _accessor.getVector(at: 68) ?? [] }
+ public func mutate(vectorOfLongs: Int64, at index: Int32) -> Bool { let o = _accessor.offset(68); return _accessor.directMutate(vectorOfLongs, index: _accessor.vector(at: o) + index * 8) }
+ public var vectorOfDoublesCount: Int32 { let o = _accessor.offset(70); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vectorOfDoubles(at index: Int32) -> Double { let o = _accessor.offset(70); return o == 0 ? 0 : _accessor.directRead(of: Double.self, offset: _accessor.vector(at: o) + index * 8) }
+ public var vectorOfDoubles: [Double] { return _accessor.getVector(at: 70) ?? [] }
+ public func mutate(vectorOfDoubles: Double, at index: Int32) -> Bool { let o = _accessor.offset(70); return _accessor.directMutate(vectorOfDoubles, index: _accessor.vector(at: o) + index * 8) }
+ public var parentNamespaceTest: MyGame.InParentNamespace? { let o = _accessor.offset(72); return o == 0 ? nil : MyGame.InParentNamespace(_accessor.bb, o: _accessor.indirect(o + _accessor.postion)) }
+ public var vectorOfReferrablesCount: Int32 { let o = _accessor.offset(74); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vectorOfReferrables(at index: Int32) -> MyGame.Example.Referrable? { let o = _accessor.offset(74); return o == 0 ? nil : MyGame.Example.Referrable(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
+ public func vectorOfReferrablesBy(key: UInt64) -> MyGame.Example.Referrable? { let o = _accessor.offset(74); return o == 0 ? nil : MyGame.Example.Referrable.lookupByKey(vector: _accessor.vector(at: o), key: key, fbb: _accessor.bb) }
+ public var singleWeakReference: UInt64 { let o = _accessor.offset(76); return o == 0 ? 0 : _accessor.readBuffer(of: UInt64.self, at: o) }
+ public func mutate(singleWeakReference: UInt64) -> Bool {let o = _accessor.offset(76); return _accessor.mutate(singleWeakReference, index: o) }
+ public var vectorOfWeakReferencesCount: Int32 { let o = _accessor.offset(78); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vectorOfWeakReferences(at index: Int32) -> UInt64 { let o = _accessor.offset(78); return o == 0 ? 0 : _accessor.directRead(of: UInt64.self, offset: _accessor.vector(at: o) + index * 8) }
+ public var vectorOfWeakReferences: [UInt64] { return _accessor.getVector(at: 78) ?? [] }
+ public func mutate(vectorOfWeakReferences: UInt64, at index: Int32) -> Bool { let o = _accessor.offset(78); return _accessor.directMutate(vectorOfWeakReferences, index: _accessor.vector(at: o) + index * 8) }
+ public var vectorOfStrongReferrablesCount: Int32 { let o = _accessor.offset(80); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vectorOfStrongReferrables(at index: Int32) -> MyGame.Example.Referrable? { let o = _accessor.offset(80); return o == 0 ? nil : MyGame.Example.Referrable(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
+ public func vectorOfStrongReferrablesBy(key: UInt64) -> MyGame.Example.Referrable? { let o = _accessor.offset(80); return o == 0 ? nil : MyGame.Example.Referrable.lookupByKey(vector: _accessor.vector(at: o), key: key, fbb: _accessor.bb) }
+ public var coOwningReference: UInt64 { let o = _accessor.offset(82); return o == 0 ? 0 : _accessor.readBuffer(of: UInt64.self, at: o) }
+ public func mutate(coOwningReference: UInt64) -> Bool {let o = _accessor.offset(82); return _accessor.mutate(coOwningReference, index: o) }
+ public var vectorOfCoOwningReferencesCount: Int32 { let o = _accessor.offset(84); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vectorOfCoOwningReferences(at index: Int32) -> UInt64 { let o = _accessor.offset(84); return o == 0 ? 0 : _accessor.directRead(of: UInt64.self, offset: _accessor.vector(at: o) + index * 8) }
+ public var vectorOfCoOwningReferences: [UInt64] { return _accessor.getVector(at: 84) ?? [] }
+ public func mutate(vectorOfCoOwningReferences: UInt64, at index: Int32) -> Bool { let o = _accessor.offset(84); return _accessor.directMutate(vectorOfCoOwningReferences, index: _accessor.vector(at: o) + index * 8) }
+ public var nonOwningReference: UInt64 { let o = _accessor.offset(86); return o == 0 ? 0 : _accessor.readBuffer(of: UInt64.self, at: o) }
+ public func mutate(nonOwningReference: UInt64) -> Bool {let o = _accessor.offset(86); return _accessor.mutate(nonOwningReference, index: o) }
+ public var vectorOfNonOwningReferencesCount: Int32 { let o = _accessor.offset(88); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vectorOfNonOwningReferences(at index: Int32) -> UInt64 { let o = _accessor.offset(88); return o == 0 ? 0 : _accessor.directRead(of: UInt64.self, offset: _accessor.vector(at: o) + index * 8) }
+ public var vectorOfNonOwningReferences: [UInt64] { return _accessor.getVector(at: 88) ?? [] }
+ public func mutate(vectorOfNonOwningReferences: UInt64, at index: Int32) -> Bool { let o = _accessor.offset(88); return _accessor.directMutate(vectorOfNonOwningReferences, index: _accessor.vector(at: o) + index * 8) }
+ public var anyUniqueType: MyGame.Example.AnyUniqueAliases { let o = _accessor.offset(90); return o == 0 ? .none : MyGame.Example.AnyUniqueAliases(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none }
+ public func anyUnique<T: FlatBufferObject>(type: T.Type) -> T? { let o = _accessor.offset(92); return o == 0 ? nil : _accessor.union(o) }
+ public var anyAmbiguousType: MyGame.Example.AnyAmbiguousAliases { let o = _accessor.offset(94); return o == 0 ? .none : MyGame.Example.AnyAmbiguousAliases(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none }
+ public func anyAmbiguous<T: FlatBufferObject>(type: T.Type) -> T? { let o = _accessor.offset(96); return o == 0 ? nil : _accessor.union(o) }
+ public var vectorOfEnumsCount: Int32 { let o = _accessor.offset(98); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vectorOfEnums(at index: Int32) -> MyGame.Example.Color? { let o = _accessor.offset(98); return o == 0 ? MyGame.Example.Color.red : MyGame.Example.Color(rawValue: _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1)) }
+ public var signedEnum: MyGame.Example.Race { let o = _accessor.offset(100); return o == 0 ? .none : MyGame.Example.Race(rawValue: _accessor.readBuffer(of: Int8.self, at: o)) ?? .none }
+ public func mutate(signedEnum: MyGame.Example.Race) -> Bool {let o = _accessor.offset(100); return _accessor.mutate(signedEnum.rawValue, index: o) }
+ public static func startMonster(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 49) }
+ public static func add(pos: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(structOffset: 0) }
+ public static func add(mana: Int16, _ fbb: FlatBufferBuilder) { fbb.add(element: mana, def: 150, at: 1) }
+ public static func add(hp: Int16, _ fbb: FlatBufferBuilder) { fbb.add(element: hp, def: 100, at: 2) }
+ public static func add(name: Offset<String>, _ fbb: FlatBufferBuilder) { fbb.add(offset: name, at: 3) }
+ public static func addVectorOf(inventory: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: inventory, at: 5) }
+ public static func add(color: MyGame.Example.Color, _ fbb: FlatBufferBuilder) { fbb.add(element: color.rawValue, def: 8, at: 6) }
+ public static func add(testType: MyGame.Example.Any_, _ fbb: FlatBufferBuilder) { fbb.add(element: testType.rawValue, def: 0, at: 7) }
+ public static func add(test: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: test, at: 8) }
+ public static func addVectorOf(test4: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: test4, at: 9) }
+ public static func addVectorOf(testarrayofstring: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: testarrayofstring, at: 10) }
+ public static func addVectorOf(testarrayoftables: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: testarrayoftables, at: 11) }
+ public static func add(enemy: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: enemy, at: 12) }
+ public static func addVectorOf(testnestedflatbuffer: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: testnestedflatbuffer, at: 13) }
+ public static func add(testempty: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: testempty, at: 14) }
+ public static func add(testbool: Bool, _ fbb: FlatBufferBuilder) { fbb.add(condition: testbool, def: false, at: 15) }
+ public static func add(testhashs32Fnv1: Int32, _ fbb: FlatBufferBuilder) { fbb.add(element: testhashs32Fnv1, def: 0, at: 16) }
+ public static func add(testhashu32Fnv1: UInt32, _ fbb: FlatBufferBuilder) { fbb.add(element: testhashu32Fnv1, def: 0, at: 17) }
+ public static func add(testhashs64Fnv1: Int64, _ fbb: FlatBufferBuilder) { fbb.add(element: testhashs64Fnv1, def: 0, at: 18) }
+ public static func add(testhashu64Fnv1: UInt64, _ fbb: FlatBufferBuilder) { fbb.add(element: testhashu64Fnv1, def: 0, at: 19) }
+ public static func add(testhashs32Fnv1a: Int32, _ fbb: FlatBufferBuilder) { fbb.add(element: testhashs32Fnv1a, def: 0, at: 20) }
+ public static func add(testhashu32Fnv1a: UInt32, _ fbb: FlatBufferBuilder) { fbb.add(element: testhashu32Fnv1a, def: 0, at: 21) }
+ public static func add(testhashs64Fnv1a: Int64, _ fbb: FlatBufferBuilder) { fbb.add(element: testhashs64Fnv1a, def: 0, at: 22) }
+ public static func add(testhashu64Fnv1a: UInt64, _ fbb: FlatBufferBuilder) { fbb.add(element: testhashu64Fnv1a, def: 0, at: 23) }
+ public static func addVectorOf(testarrayofbools: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: testarrayofbools, at: 24) }
+ public static func add(testf: Float32, _ fbb: FlatBufferBuilder) { fbb.add(element: testf, def: 3.14159, at: 25) }
+ public static func add(testf2: Float32, _ fbb: FlatBufferBuilder) { fbb.add(element: testf2, def: 3.0, at: 26) }
+ public static func add(testf3: Float32, _ fbb: FlatBufferBuilder) { fbb.add(element: testf3, def: 0.0, at: 27) }
+ public static func addVectorOf(testarrayofstring2: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: testarrayofstring2, at: 28) }
+ public static func addVectorOf(testarrayofsortedstruct: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: testarrayofsortedstruct, at: 29) }
+ public static func addVectorOf(flex: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: flex, at: 30) }
+ public static func addVectorOf(test5: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: test5, at: 31) }
+ public static func addVectorOf(vectorOfLongs: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vectorOfLongs, at: 32) }
+ public static func addVectorOf(vectorOfDoubles: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vectorOfDoubles, at: 33) }
+ public static func add(parentNamespaceTest: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: parentNamespaceTest, at: 34) }
+ public static func addVectorOf(vectorOfReferrables: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vectorOfReferrables, at: 35) }
+ public static func add(singleWeakReference: UInt64, _ fbb: FlatBufferBuilder) { fbb.add(element: singleWeakReference, def: 0, at: 36) }
+ public static func addVectorOf(vectorOfWeakReferences: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vectorOfWeakReferences, at: 37) }
+ public static func addVectorOf(vectorOfStrongReferrables: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vectorOfStrongReferrables, at: 38) }
+ public static func add(coOwningReference: UInt64, _ fbb: FlatBufferBuilder) { fbb.add(element: coOwningReference, def: 0, at: 39) }
+ public static func addVectorOf(vectorOfCoOwningReferences: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vectorOfCoOwningReferences, at: 40) }
+ public static func add(nonOwningReference: UInt64, _ fbb: FlatBufferBuilder) { fbb.add(element: nonOwningReference, def: 0, at: 41) }
+ public static func addVectorOf(vectorOfNonOwningReferences: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vectorOfNonOwningReferences, at: 42) }
+ public static func add(anyUniqueType: MyGame.Example.AnyUniqueAliases, _ fbb: FlatBufferBuilder) { fbb.add(element: anyUniqueType.rawValue, def: 0, at: 43) }
+ public static func add(anyUnique: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: anyUnique, at: 44) }
+ public static func add(anyAmbiguousType: MyGame.Example.AnyAmbiguousAliases, _ fbb: FlatBufferBuilder) { fbb.add(element: anyAmbiguousType.rawValue, def: 0, at: 45) }
+ public static func add(anyAmbiguous: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: anyAmbiguous, at: 46) }
+ public static func addVectorOf(vectorOfEnums: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vectorOfEnums, at: 47) }
+ public static func add(signedEnum: MyGame.Example.Race, _ fbb: FlatBufferBuilder) { fbb.add(element: signedEnum.rawValue, def: -1, at: 48) }
+ public static func endMonster(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); fbb.require(table: end, fields: [10]); return end }
+ public static func createMonster(_ fbb: FlatBufferBuilder,
+ offsetOfPos pos: Offset<UOffset> = Offset(),
+ mana: Int16 = 150,
+ hp: Int16 = 100,
+ offsetOfName name: Offset<String> = Offset(),
+ vectorOfInventory inventory: Offset<UOffset> = Offset(),
+ color: MyGame.Example.Color = .blue,
+ testType: MyGame.Example.Any_ = .none,
+ offsetOfTest test: Offset<UOffset> = Offset(),
+ vectorOfTest4 test4: Offset<UOffset> = Offset(),
+ vectorOfTestarrayofstring testarrayofstring: Offset<UOffset> = Offset(),
+ vectorOfTestarrayoftables testarrayoftables: Offset<UOffset> = Offset(),
+ offsetOfEnemy enemy: Offset<UOffset> = Offset(),
+ vectorOfTestnestedflatbuffer testnestedflatbuffer: Offset<UOffset> = Offset(),
+ offsetOfTestempty testempty: Offset<UOffset> = Offset(),
+ testbool: Bool = false,
+ testhashs32Fnv1: Int32 = 0,
+ testhashu32Fnv1: UInt32 = 0,
+ testhashs64Fnv1: Int64 = 0,
+ testhashu64Fnv1: UInt64 = 0,
+ testhashs32Fnv1a: Int32 = 0,
+ testhashu32Fnv1a: UInt32 = 0,
+ testhashs64Fnv1a: Int64 = 0,
+ testhashu64Fnv1a: UInt64 = 0,
+ vectorOfTestarrayofbools testarrayofbools: Offset<UOffset> = Offset(),
+ testf: Float32 = 3.14159,
+ testf2: Float32 = 3.0,
+ testf3: Float32 = 0.0,
+ vectorOfTestarrayofstring2 testarrayofstring2: Offset<UOffset> = Offset(),
+ vectorOfTestarrayofsortedstruct testarrayofsortedstruct: Offset<UOffset> = Offset(),
+ vectorOfFlex flex: Offset<UOffset> = Offset(),
+ vectorOfTest5 test5: Offset<UOffset> = Offset(),
+ vectorOfVectorOfLongs vectorOfLongs: Offset<UOffset> = Offset(),
+ vectorOfVectorOfDoubles vectorOfDoubles: Offset<UOffset> = Offset(),
+ offsetOfParentNamespaceTest parentNamespaceTest: Offset<UOffset> = Offset(),
+ vectorOfVectorOfReferrables vectorOfReferrables: Offset<UOffset> = Offset(),
+ singleWeakReference: UInt64 = 0,
+ vectorOfVectorOfWeakReferences vectorOfWeakReferences: Offset<UOffset> = Offset(),
+ vectorOfVectorOfStrongReferrables vectorOfStrongReferrables: Offset<UOffset> = Offset(),
+ coOwningReference: UInt64 = 0,
+ vectorOfVectorOfCoOwningReferences vectorOfCoOwningReferences: Offset<UOffset> = Offset(),
+ nonOwningReference: UInt64 = 0,
+ vectorOfVectorOfNonOwningReferences vectorOfNonOwningReferences: Offset<UOffset> = Offset(),
+ anyUniqueType: MyGame.Example.AnyUniqueAliases = .none,
+ offsetOfAnyUnique anyUnique: Offset<UOffset> = Offset(),
+ anyAmbiguousType: MyGame.Example.AnyAmbiguousAliases = .none,
+ offsetOfAnyAmbiguous anyAmbiguous: Offset<UOffset> = Offset(),
+ vectorOfVectorOfEnums vectorOfEnums: Offset<UOffset> = Offset(),
+ signedEnum: MyGame.Example.Race = .none) -> Offset<UOffset> {
+ let __start = Monster.startMonster(fbb)
+ Monster.add(pos: pos, fbb)
+ Monster.add(mana: mana, fbb)
+ Monster.add(hp: hp, fbb)
+ Monster.add(name: name, fbb)
+ Monster.addVectorOf(inventory: inventory, fbb)
+ Monster.add(color: color, fbb)
+ Monster.add(testType: testType, fbb)
+ Monster.add(test: test, fbb)
+ Monster.addVectorOf(test4: test4, fbb)
+ Monster.addVectorOf(testarrayofstring: testarrayofstring, fbb)
+ Monster.addVectorOf(testarrayoftables: testarrayoftables, fbb)
+ Monster.add(enemy: enemy, fbb)
+ Monster.addVectorOf(testnestedflatbuffer: testnestedflatbuffer, fbb)
+ Monster.add(testempty: testempty, fbb)
+ Monster.add(testbool: testbool, fbb)
+ Monster.add(testhashs32Fnv1: testhashs32Fnv1, fbb)
+ Monster.add(testhashu32Fnv1: testhashu32Fnv1, fbb)
+ Monster.add(testhashs64Fnv1: testhashs64Fnv1, fbb)
+ Monster.add(testhashu64Fnv1: testhashu64Fnv1, fbb)
+ Monster.add(testhashs32Fnv1a: testhashs32Fnv1a, fbb)
+ Monster.add(testhashu32Fnv1a: testhashu32Fnv1a, fbb)
+ Monster.add(testhashs64Fnv1a: testhashs64Fnv1a, fbb)
+ Monster.add(testhashu64Fnv1a: testhashu64Fnv1a, fbb)
+ Monster.addVectorOf(testarrayofbools: testarrayofbools, fbb)
+ Monster.add(testf: testf, fbb)
+ Monster.add(testf2: testf2, fbb)
+ Monster.add(testf3: testf3, fbb)
+ Monster.addVectorOf(testarrayofstring2: testarrayofstring2, fbb)
+ Monster.addVectorOf(testarrayofsortedstruct: testarrayofsortedstruct, fbb)
+ Monster.addVectorOf(flex: flex, fbb)
+ Monster.addVectorOf(test5: test5, fbb)
+ Monster.addVectorOf(vectorOfLongs: vectorOfLongs, fbb)
+ Monster.addVectorOf(vectorOfDoubles: vectorOfDoubles, fbb)
+ Monster.add(parentNamespaceTest: parentNamespaceTest, fbb)
+ Monster.addVectorOf(vectorOfReferrables: vectorOfReferrables, fbb)
+ Monster.add(singleWeakReference: singleWeakReference, fbb)
+ Monster.addVectorOf(vectorOfWeakReferences: vectorOfWeakReferences, fbb)
+ Monster.addVectorOf(vectorOfStrongReferrables: vectorOfStrongReferrables, fbb)
+ Monster.add(coOwningReference: coOwningReference, fbb)
+ Monster.addVectorOf(vectorOfCoOwningReferences: vectorOfCoOwningReferences, fbb)
+ Monster.add(nonOwningReference: nonOwningReference, fbb)
+ Monster.addVectorOf(vectorOfNonOwningReferences: vectorOfNonOwningReferences, fbb)
+ Monster.add(anyUniqueType: anyUniqueType, fbb)
+ Monster.add(anyUnique: anyUnique, fbb)
+ Monster.add(anyAmbiguousType: anyAmbiguousType, fbb)
+ Monster.add(anyAmbiguous: anyAmbiguous, fbb)
+ Monster.addVectorOf(vectorOfEnums: vectorOfEnums, fbb)
+ Monster.add(signedEnum: signedEnum, fbb)
+ return Monster.endMonster(fbb, start: __start)
+ }
+ public static func sortVectorOfMonster(offsets:[Offset<UOffset>], _ fbb: FlatBufferBuilder) -> Offset<UOffset> {
+ var off = offsets
+ off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: 10, fbb: fbb.buffer), Table.offset(Int32($0.o), vOffset: 10, fbb: fbb.buffer), fbb: fbb.buffer) < 0 }
+ return fbb.createVector(ofOffsets: off)
+ }
+ fileprivate static func lookupByKey(vector: Int32, key: String, fbb: ByteBuffer) -> Monster? {
+ let key = key.utf8.map { $0 }
+ var span = fbb.read(def: Int32.self, position: Int(vector - 4))
+ var start: Int32 = 0
+ while span != 0 {
+ var middle = span / 2
+ let tableOffset = Table.indirect(vector + 4 * (start + middle), fbb)
+ let comp = Table.compare(Table.offset(Int32(fbb.capacity) - tableOffset, vOffset: 10, fbb: fbb), key, fbb: fbb)
+ if comp > 0 {
+ span = middle
+ } else if comp < 0 {
+ middle += 1
+ start += middle
+ span -= middle
+ } else {
+ return Monster(fbb, o: tableOffset)
+ }
+ }
+ return nil
+ }
+}
+
+public struct TypeAliases: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MONS", addPrefix: prefix) }
+ public static func getRootAsTypeAliases(bb: ByteBuffer) -> TypeAliases { return TypeAliases(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var i8: Int8 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.readBuffer(of: Int8.self, at: o) }
+ public func mutate(i8: Int8) -> Bool {let o = _accessor.offset(4); return _accessor.mutate(i8, index: o) }
+ public var u8: UInt8 { let o = _accessor.offset(6); return o == 0 ? 0 : _accessor.readBuffer(of: UInt8.self, at: o) }
+ public func mutate(u8: UInt8) -> Bool {let o = _accessor.offset(6); return _accessor.mutate(u8, index: o) }
+ public var i16: Int16 { let o = _accessor.offset(8); return o == 0 ? 0 : _accessor.readBuffer(of: Int16.self, at: o) }
+ public func mutate(i16: Int16) -> Bool {let o = _accessor.offset(8); return _accessor.mutate(i16, index: o) }
+ public var u16: UInt16 { let o = _accessor.offset(10); return o == 0 ? 0 : _accessor.readBuffer(of: UInt16.self, at: o) }
+ public func mutate(u16: UInt16) -> Bool {let o = _accessor.offset(10); return _accessor.mutate(u16, index: o) }
+ public var i32: Int32 { let o = _accessor.offset(12); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
+ public func mutate(i32: Int32) -> Bool {let o = _accessor.offset(12); return _accessor.mutate(i32, index: o) }
+ public var u32: UInt32 { let o = _accessor.offset(14); return o == 0 ? 0 : _accessor.readBuffer(of: UInt32.self, at: o) }
+ public func mutate(u32: UInt32) -> Bool {let o = _accessor.offset(14); return _accessor.mutate(u32, index: o) }
+ public var i64: Int64 { let o = _accessor.offset(16); return o == 0 ? 0 : _accessor.readBuffer(of: Int64.self, at: o) }
+ public func mutate(i64: Int64) -> Bool {let o = _accessor.offset(16); return _accessor.mutate(i64, index: o) }
+ public var u64: UInt64 { let o = _accessor.offset(18); return o == 0 ? 0 : _accessor.readBuffer(of: UInt64.self, at: o) }
+ public func mutate(u64: UInt64) -> Bool {let o = _accessor.offset(18); return _accessor.mutate(u64, index: o) }
+ public var f32: Float32 { let o = _accessor.offset(20); return o == 0 ? 0.0 : _accessor.readBuffer(of: Float32.self, at: o) }
+ public func mutate(f32: Float32) -> Bool {let o = _accessor.offset(20); return _accessor.mutate(f32, index: o) }
+ public var f64: Double { let o = _accessor.offset(22); return o == 0 ? 0.0 : _accessor.readBuffer(of: Double.self, at: o) }
+ public func mutate(f64: Double) -> Bool {let o = _accessor.offset(22); return _accessor.mutate(f64, index: o) }
+ public var v8Count: Int32 { let o = _accessor.offset(24); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func v8(at index: Int32) -> Int8 { let o = _accessor.offset(24); return o == 0 ? 0 : _accessor.directRead(of: Int8.self, offset: _accessor.vector(at: o) + index * 1) }
+ public var v8: [Int8] { return _accessor.getVector(at: 24) ?? [] }
+ public func mutate(v8: Int8, at index: Int32) -> Bool { let o = _accessor.offset(24); return _accessor.directMutate(v8, index: _accessor.vector(at: o) + index * 1) }
+ public var vf64Count: Int32 { let o = _accessor.offset(26); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func vf64(at index: Int32) -> Double { let o = _accessor.offset(26); return o == 0 ? 0 : _accessor.directRead(of: Double.self, offset: _accessor.vector(at: o) + index * 8) }
+ public var vf64: [Double] { return _accessor.getVector(at: 26) ?? [] }
+ public func mutate(vf64: Double, at index: Int32) -> Bool { let o = _accessor.offset(26); return _accessor.directMutate(vf64, index: _accessor.vector(at: o) + index * 8) }
+ public static func startTypeAliases(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 12) }
+ public static func add(i8: Int8, _ fbb: FlatBufferBuilder) { fbb.add(element: i8, def: 0, at: 0) }
+ public static func add(u8: UInt8, _ fbb: FlatBufferBuilder) { fbb.add(element: u8, def: 0, at: 1) }
+ public static func add(i16: Int16, _ fbb: FlatBufferBuilder) { fbb.add(element: i16, def: 0, at: 2) }
+ public static func add(u16: UInt16, _ fbb: FlatBufferBuilder) { fbb.add(element: u16, def: 0, at: 3) }
+ public static func add(i32: Int32, _ fbb: FlatBufferBuilder) { fbb.add(element: i32, def: 0, at: 4) }
+ public static func add(u32: UInt32, _ fbb: FlatBufferBuilder) { fbb.add(element: u32, def: 0, at: 5) }
+ public static func add(i64: Int64, _ fbb: FlatBufferBuilder) { fbb.add(element: i64, def: 0, at: 6) }
+ public static func add(u64: UInt64, _ fbb: FlatBufferBuilder) { fbb.add(element: u64, def: 0, at: 7) }
+ public static func add(f32: Float32, _ fbb: FlatBufferBuilder) { fbb.add(element: f32, def: 0.0, at: 8) }
+ public static func add(f64: Double, _ fbb: FlatBufferBuilder) { fbb.add(element: f64, def: 0.0, at: 9) }
+ public static func addVectorOf(v8: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: v8, at: 10) }
+ public static func addVectorOf(vf64: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: vf64, at: 11) }
+ public static func endTypeAliases(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createTypeAliases(_ fbb: FlatBufferBuilder,
+ i8: Int8 = 0,
+ u8: UInt8 = 0,
+ i16: Int16 = 0,
+ u16: UInt16 = 0,
+ i32: Int32 = 0,
+ u32: UInt32 = 0,
+ i64: Int64 = 0,
+ u64: UInt64 = 0,
+ f32: Float32 = 0.0,
+ f64: Double = 0.0,
+ vectorOfV8 v8: Offset<UOffset> = Offset(),
+ vectorOfVf64 vf64: Offset<UOffset> = Offset()) -> Offset<UOffset> {
+ let __start = TypeAliases.startTypeAliases(fbb)
+ TypeAliases.add(i8: i8, fbb)
+ TypeAliases.add(u8: u8, fbb)
+ TypeAliases.add(i16: i16, fbb)
+ TypeAliases.add(u16: u16, fbb)
+ TypeAliases.add(i32: i32, fbb)
+ TypeAliases.add(u32: u32, fbb)
+ TypeAliases.add(i64: i64, fbb)
+ TypeAliases.add(u64: u64, fbb)
+ TypeAliases.add(f32: f32, fbb)
+ TypeAliases.add(f64: f64, fbb)
+ TypeAliases.addVectorOf(v8: v8, fbb)
+ TypeAliases.addVectorOf(vf64: vf64, fbb)
+ return TypeAliases.endTypeAliases(fbb, start: __start)
+ }
+}
+
+}
+
+// MARK: - Example
+
+
+// MARK: - MyGame
+
+
diff --git a/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift
new file mode 100644
index 00000000..00d84cd9
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/union_vector_generated.swift
@@ -0,0 +1,126 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import FlatBuffers
+
+public enum Character: UInt8, Enum {
+ public typealias T = UInt8
+ public static var byteSize: Int { return MemoryLayout<UInt8>.size }
+ public var value: UInt8 { return self.rawValue }
+ case none = 0
+ case mulan = 1
+ case rapunzel = 2
+ case belle = 3
+ case bookfan = 4
+ case other = 5
+ case unused = 6
+
+
+ public static var max: Character { return .unused }
+ public static var min: Character { return .none }
+}
+
+public struct Rapunzel: Readable {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Struct
+ public static var size = 4
+ public static var alignment = 4
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
+
+ public var hairLength: Int32 { return _accessor.readBuffer(of: Int32.self, at: 0) }
+ public func mutate(hairLength: Int32) -> Bool { return _accessor.mutate(hairLength, index: 0) }
+}
+
+public struct BookReader: Readable {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Struct
+ public static var size = 4
+ public static var alignment = 4
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Struct(bb: bb, position: o) }
+
+ public var booksRead: Int32 { return _accessor.readBuffer(of: Int32.self, at: 0) }
+ public func mutate(booksRead: Int32) -> Bool { return _accessor.mutate(booksRead, index: 0) }
+}
+
+public func createRapunzel(hairLength: Int32) -> UnsafeMutableRawPointer {
+ let memory = UnsafeMutableRawPointer.allocate(byteCount: Rapunzel.size, alignment: Rapunzel.alignment)
+ memory.initializeMemory(as: UInt8.self, repeating: 0, count: Rapunzel.size)
+ memory.storeBytes(of: hairLength, toByteOffset: 0, as: Int32.self)
+ return memory
+}
+
+public func createBookReader(booksRead: Int32) -> UnsafeMutableRawPointer {
+ let memory = UnsafeMutableRawPointer.allocate(byteCount: BookReader.size, alignment: BookReader.alignment)
+ memory.initializeMemory(as: UInt8.self, repeating: 0, count: BookReader.size)
+ memory.storeBytes(of: booksRead, toByteOffset: 0, as: Int32.self)
+ return memory
+}
+
+public struct Attacker: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MOVI", addPrefix: prefix) }
+ public static func getRootAsAttacker(bb: ByteBuffer) -> Attacker { return Attacker(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var swordAttackDamage: Int32 { let o = _accessor.offset(4); return o == 0 ? 0 : _accessor.readBuffer(of: Int32.self, at: o) }
+ public func mutate(swordAttackDamage: Int32) -> Bool {let o = _accessor.offset(4); return _accessor.mutate(swordAttackDamage, index: o) }
+ public static func startAttacker(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
+ public static func add(swordAttackDamage: Int32, _ fbb: FlatBufferBuilder) { fbb.add(element: swordAttackDamage, def: 0, at: 0) }
+ public static func endAttacker(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createAttacker(_ fbb: FlatBufferBuilder,
+ swordAttackDamage: Int32 = 0) -> Offset<UOffset> {
+ let __start = Attacker.startAttacker(fbb)
+ Attacker.add(swordAttackDamage: swordAttackDamage, fbb)
+ return Attacker.endAttacker(fbb, start: __start)
+ }
+}
+
+public struct Movie: FlatBufferObject {
+
+ static func validateVersion() { FlatBuffersVersion_1_12_0() }
+ public var __buffer: ByteBuffer! { return _accessor.bb }
+
+ private var _accessor: Table
+ public static func finish(_ fbb: FlatBufferBuilder, end: Offset<UOffset>, prefix: Bool = false) { fbb.finish(offset: end, fileId: "MOVI", addPrefix: prefix) }
+ public static func getRootAsMovie(bb: ByteBuffer) -> Movie { return Movie(Table(bb: bb, position: Int32(bb.read(def: UOffset.self, position: bb.reader)) + Int32(bb.reader))) }
+
+ private init(_ t: Table) { _accessor = t }
+ public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
+
+ public var mainCharacterType: Character { let o = _accessor.offset(4); return o == 0 ? .none : Character(rawValue: _accessor.readBuffer(of: UInt8.self, at: o)) ?? .none }
+ public func mainCharacter<T: FlatBufferObject>(type: T.Type) -> T? { let o = _accessor.offset(6); return o == 0 ? nil : _accessor.union(o) }
+ public var charactersTypeCount: Int32 { let o = _accessor.offset(8); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func charactersType(at index: Int32) -> Character? { let o = _accessor.offset(8); return o == 0 ? Character.none : Character(rawValue: _accessor.directRead(of: UInt8.self, offset: _accessor.vector(at: o) + index * 1)) }
+ public var charactersCount: Int32 { let o = _accessor.offset(10); return o == 0 ? 0 : _accessor.vector(count: o) }
+ public func characters<T: FlatBufferObject>(at index: Int32, type: T.Type) -> T? { let o = _accessor.offset(10); return o == 0 ? nil : _accessor.directUnion(_accessor.vector(at: o) + index * 4) }
+ public static func startMovie(_ fbb: FlatBufferBuilder) -> UOffset { fbb.startTable(with: 4) }
+ public static func add(mainCharacterType: Character, _ fbb: FlatBufferBuilder) { fbb.add(element: mainCharacterType.rawValue, def: 0, at: 0) }
+ public static func add(mainCharacter: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: mainCharacter, at: 1) }
+ public static func addVectorOf(charactersType: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: charactersType, at: 2) }
+ public static func addVectorOf(characters: Offset<UOffset>, _ fbb: FlatBufferBuilder) { fbb.add(offset: characters, at: 3) }
+ public static func endMovie(_ fbb: FlatBufferBuilder, start: UOffset) -> Offset<UOffset> { let end = Offset<UOffset>(offset: fbb.endTable(at: start)); return end }
+ public static func createMovie(_ fbb: FlatBufferBuilder,
+ mainCharacterType: Character = .none,
+ offsetOfMainCharacter mainCharacter: Offset<UOffset> = Offset(),
+ vectorOfCharactersType charactersType: Offset<UOffset> = Offset(),
+ vectorOfCharacters characters: Offset<UOffset> = Offset()) -> Offset<UOffset> {
+ let __start = Movie.startMovie(fbb)
+ Movie.add(mainCharacterType: mainCharacterType, fbb)
+ Movie.add(mainCharacter: mainCharacter, fbb)
+ Movie.addVectorOf(charactersType: charactersType, fbb)
+ Movie.addVectorOf(characters: characters, fbb)
+ return Movie.endMovie(fbb, start: __start)
+ }
+}
+
diff --git a/tests/FlatBuffers.Test.Swift/Tests/LinuxMain.swift b/tests/FlatBuffers.Test.Swift/Tests/LinuxMain.swift
new file mode 100644
index 00000000..1b16a78e
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/Tests/LinuxMain.swift
@@ -0,0 +1,8 @@
+import XCTest
+
+import FlatBuffers_Test_SwiftTests
+
+var tests = [XCTestCaseEntry]()
+tests += FlatBuffers_Test_SwiftTests.__allTests()
+
+XCTMain(tests)
diff --git a/tests/FlatBuffers.Test.Swift/monsterdata_test.mon b/tests/FlatBuffers.Test.Swift/monsterdata_test.mon
new file mode 100644
index 00000000..ba6cf278
--- /dev/null
+++ b/tests/FlatBuffers.Test.Swift/monsterdata_test.mon
Binary files differ
diff --git a/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs b/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
index 4ddd9a8c..d2f49f7b 100644
--- a/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
+++ b/tests/FlatBuffers.Test/FlatBufferBuilderTests.cs
@@ -24,7 +24,7 @@ namespace FlatBuffers.Test
private FlatBufferBuilder CreateBuffer(bool forceDefaults = true)
{
var fbb = new FlatBufferBuilder(16) {ForceDefaults = forceDefaults};
- fbb.StartObject(1);
+ fbb.StartTable(1);
return fbb;
}
diff --git a/tests/FlatBuffers.Test/FlatBuffers.Test.csproj b/tests/FlatBuffers.Test/FlatBuffers.Test.csproj
index bbba231a..c917d2f1 100644
--- a/tests/FlatBuffers.Test/FlatBuffers.Test.csproj
+++ b/tests/FlatBuffers.Test/FlatBuffers.Test.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -9,6 +9,7 @@
<RootNamespace>FlatBuffers.Test</RootNamespace>
<AssemblyName>FlatBuffers.Test</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <LangVersion>4</LangVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -16,7 +17,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@@ -36,6 +37,9 @@
<DefineConstants>$(DefineConstants);UNSAFE_BYTEBUFFER</DefineConstants>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>packages\Newtonsoft.Json.12.0.3\lib\net35\Newtonsoft.Json.dll</HintPath>
+ </Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -66,6 +70,9 @@
<Compile Include="..\..\net\FlatBuffers\Table.cs">
<Link>FlatBuffers\Table.cs</Link>
</Compile>
+ <Compile Include="..\MyGame\Example2\Monster.cs">
+ <Link>MyGame\Example2\Monster.cs</Link>
+ </Compile>
<Compile Include="..\MyGame\Example\Any.cs">
<Link>MyGame\Example\Any.cs</Link>
</Compile>
@@ -78,6 +85,9 @@
<Compile Include="..\MyGame\Example\Color.cs">
<Link>MyGame\Example\Color.cs</Link>
</Compile>
+ <Compile Include="..\MyGame\Example\Race.cs">
+ <Link>MyGame\Example\Race.cs</Link>
+ </Compile>
<Compile Include="..\MyGame\Example\Monster.cs">
<Link>MyGame\Example\Monster.cs</Link>
</Compile>
@@ -93,12 +103,27 @@
<Compile Include="..\MyGame\Example\TestSimpleTableWithEnum.cs">
<Link>MyGame\Example\TestSimpleTableWithEnum.cs</Link>
</Compile>
+ <Compile Include="..\MyGame\Example\TypeAliases.cs">
+ <Link>MyGame\Example\TypeAliases.cs</Link>
+ </Compile>
<Compile Include="..\MyGame\Example\Vec3.cs">
<Link>MyGame\Example\Vec3.cs</Link>
</Compile>
<Compile Include="..\MyGame\Example\Ability.cs">
<Link>MyGame\Example\Ability.cs</Link>
</Compile>
+ <Compile Include="..\MyGame\Example\ArrayTable.cs">
+ <Link>MyGame\Example\ArrayTable.cs</Link>
+ </Compile>
+ <Compile Include="..\MyGame\Example\ArrayStruct.cs">
+ <Link>MyGame\Example\ArrayStruct.cs</Link>
+ </Compile>
+ <Compile Include="..\MyGame\Example\NestedStruct.cs">
+ <Link>MyGame\Example\NestedStruct.cs</Link>
+ </Compile>
+ <Compile Include="..\MyGame\Example\TestEnum.cs">
+ <Link>MyGame\Example\TestEnum.cs</Link>
+ </Compile>
<Compile Include="..\MyGame\InParentNamespace.cs">
<Link>MyGame\InParentNamespace.cs</Link>
</Compile>
@@ -114,6 +139,21 @@
<Compile Include="..\namespace_test\NamespaceA\TableInFirstNS.cs">
<Link>NamespaceA\TableInFirstNS.cs</Link>
</Compile>
+ <Compile Include="..\union_vector\Attacker.cs">
+ <Link>union_vector\Attacker.cs</Link>
+ </Compile>
+ <Compile Include="..\union_vector\BookReader.cs">
+ <Link>union_vector\BookReader.cs</Link>
+ </Compile>
+ <Compile Include="..\union_vector\Character.cs">
+ <Link>union_vector\Character.cs</Link>
+ </Compile>
+ <Compile Include="..\union_vector\Movie.cs">
+ <Link>union_vector\Movie.cs</Link>
+ </Compile>
+ <Compile Include="..\union_vector\Rapunzel.cs">
+ <Link>union_vector\Rapunzel.cs</Link>
+ </Compile>
<Compile Include="Assert.cs" />
<Compile Include="ByteBufferTests.cs" />
<Compile Include="FlatBufferBuilderTests.cs" />
@@ -132,6 +172,13 @@
<Link>Resources\monsterdata_test.mon</Link>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="..\monsterdata_test.json">
+ <Link>Resources\monsterdata_test.json</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -141,4 +188,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+</Project> \ No newline at end of file
diff --git a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
index a670b194..8e42ca6b 100644
--- a/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
+++ b/tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
@@ -111,18 +111,18 @@ namespace FlatBuffers.Test
}
// Dump to output directory so we can inspect later, if needed
-#if ENABLE_SPAN_T
+ #if ENABLE_SPAN_T
var data = fbb.DataBuffer.ToSizedArray();
string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
File.WriteAllBytes(filename, data);
-#else
+ #else
using (var ms = fbb.DataBuffer.ToMemoryStream(fbb.DataBuffer.Position, fbb.Offset))
{
var data = ms.ToArray();
string filename = @"Resources/monsterdata_cstest" + (sizePrefix ? "_sp" : "") + ".mon";
File.WriteAllBytes(filename, data);
}
-#endif
+ #endif
// Remove the size prefix if necessary for further testing
ByteBuffer dataBuffer = fbb.DataBuffer;
@@ -156,11 +156,7 @@ namespace FlatBuffers.Test
Assert.IsTrue(monster.TestarrayoftablesByKey("Barney") != null);
Assert.IsTrue(monster.TestarrayoftablesByKey("Wilma") != null);
- // testType is an existing field and mutating it should succeed
- Assert.AreEqual(monster.TestType, Any.Monster);
- Assert.AreEqual(monster.MutateTestType(Any.NONE), true);
- Assert.AreEqual(monster.TestType, Any.NONE);
- Assert.AreEqual(monster.MutateTestType(Any.Monster), true);
+ // testType is an existing field
Assert.AreEqual(monster.TestType, Any.Monster);
//mutate the inventory vector
@@ -191,6 +187,7 @@ namespace FlatBuffers.Test
Assert.AreEqual(pos.X, 1.0f);
TestBuffer(dataBuffer);
+ TestObjectAPI(Monster.GetRootAsMonster(dataBuffer));
}
private void TestBuffer(ByteBuffer bb)
@@ -248,7 +245,7 @@ namespace FlatBuffers.Test
Assert.AreEqual(true, monster.Testbool);
-#if ENABLE_SPAN_T
+ #if ENABLE_SPAN_T
var nameBytes = monster.GetNameBytes();
Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.ToArray(), 0, nameBytes.Length));
@@ -260,7 +257,13 @@ namespace FlatBuffers.Test
{
Assert.IsTrue(monster.GetTestarrayofboolsBytes().Length != 0);
}
-#else
+
+ var longArrayBytes = monster.GetVectorOfLongsBytes();
+ Assert.IsTrue(monster.VectorOfLongsLength * 8 == longArrayBytes.Length);
+
+ var doubleArrayBytes = monster.GetVectorOfDoublesBytes();
+ Assert.IsTrue(monster.VectorOfDoublesLength * 8 == doubleArrayBytes.Length);
+ #else
var nameBytes = monster.GetNameBytes().Value;
Assert.AreEqual("MyMonster", Encoding.UTF8.GetString(nameBytes.Array, nameBytes.Offset, nameBytes.Count));
@@ -272,7 +275,7 @@ namespace FlatBuffers.Test
{
Assert.IsTrue(monster.GetTestarrayofboolsBytes().HasValue);
}
-#endif
+ #endif
}
[FlatBuffersTestMethod]
@@ -281,6 +284,17 @@ namespace FlatBuffers.Test
var data = File.ReadAllBytes(@"Resources/monsterdata_test.mon");
var bb = new ByteBuffer(data);
TestBuffer(bb);
+ TestObjectAPI(Monster.GetRootAsMonster(bb));
+ }
+
+ [FlatBuffersTestMethod]
+ public void CanReadJsonFile()
+ {
+ var jsonText = File.ReadAllText(@"Resources/monsterdata_test.json");
+ var mon = MonsterT.DeserializeFromJson(jsonText);
+ var fbb = new FlatBufferBuilder(1);
+ fbb.Finish(Monster.Pack(fbb, mon).Value);
+ TestBuffer(fbb.DataBuffer);
}
[FlatBuffersTestMethod]
@@ -293,6 +307,27 @@ 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);
+
+ TestObjectAPI(mons);
+ }
+
+ [FlatBuffersTestMethod]
public void TestNestedFlatBuffer()
{
const string nestedMonsterName = "NestedMonsterName";
@@ -329,6 +364,469 @@ namespace FlatBuffers.Test
Assert.AreEqual(nestedMonsterMana, nestedMonster.Mana);
Assert.AreEqual(nestedMonsterHp, nestedMonster.Hp);
Assert.AreEqual(nestedMonsterName, nestedMonster.Name);
+
+ TestObjectAPI(mons);
+ TestObjectAPI(nestedMonster);
+ }
+
+ [FlatBuffersTestMethod]
+ public void TestFixedLenghtArrays()
+ {
+ FlatBufferBuilder builder = new FlatBufferBuilder(100);
+
+ float a;
+ int[] b = new int[15];
+ sbyte c;
+ int[,] d_a = new int[2, 2];
+ TestEnum[] d_b = new TestEnum[2];
+ TestEnum[,] d_c = new TestEnum[2, 2];
+ long[,] d_d = new long[2, 2];
+ int e;
+ long[] f = new long[2];
+
+ a = 0.5f;
+ for (int i = 0; i < 15; i++) b[i] = i;
+ c = 1;
+ d_a[0, 0] = 1;
+ d_a[0, 1] = 2;
+ d_a[1, 0] = 3;
+ d_a[1, 1] = 4;
+ d_b[0] = TestEnum.B;
+ d_b[1] = TestEnum.C;
+ d_c[0, 0] = TestEnum.A;
+ d_c[0, 1] = TestEnum.B;
+ d_c[1, 0] = TestEnum.C;
+ d_c[1, 1] = TestEnum.B;
+ d_d[0, 0] = -1;
+ d_d[0, 1] = 1;
+ d_d[1, 0] = -2;
+ d_d[1, 1] = 2;
+ e = 2;
+ f[0] = -1;
+ f[1] = 1;
+
+ Offset<ArrayStruct> arrayOffset = ArrayStruct.CreateArrayStruct(
+ builder, a, b, c, d_a, d_b, d_c, d_d, e, f);
+
+ // Create a table with the ArrayStruct.
+ ArrayTable.StartArrayTable(builder);
+ ArrayTable.AddA(builder, arrayOffset);
+ Offset<ArrayTable> tableOffset = ArrayTable.EndArrayTable(builder);
+
+ ArrayTable.FinishArrayTableBuffer(builder, tableOffset);
+
+ ArrayTable table = ArrayTable.GetRootAsArrayTable(builder.DataBuffer);
+
+ Assert.AreEqual(table.A.Value.A, 0.5f);
+ for (int i = 0; i < 15; i++) Assert.AreEqual(table.A.Value.B(i), i);
+ Assert.AreEqual(table.A.Value.C, (sbyte)1);
+ Assert.AreEqual(table.A.Value.D(0).A(0), 1);
+ Assert.AreEqual(table.A.Value.D(0).A(1), 2);
+ Assert.AreEqual(table.A.Value.D(1).A(0), 3);
+ Assert.AreEqual(table.A.Value.D(1).A(1), 4);
+ Assert.AreEqual(table.A.Value.D(0).B, TestEnum.B);
+ Assert.AreEqual(table.A.Value.D(1).B, TestEnum.C);
+ Assert.AreEqual(table.A.Value.D(0).C(0), TestEnum.A);
+ Assert.AreEqual(table.A.Value.D(0).C(1), TestEnum.B);
+ Assert.AreEqual(table.A.Value.D(1).C(0), TestEnum.C);
+ Assert.AreEqual(table.A.Value.D(1).C(1), TestEnum.B);
+ Assert.AreEqual(table.A.Value.D(0).D(0), -1);
+ Assert.AreEqual(table.A.Value.D(0).D(1), 1);
+ Assert.AreEqual(table.A.Value.D(1).D(0), -2);
+ Assert.AreEqual(table.A.Value.D(1).D(1), 2);
+ Assert.AreEqual(table.A.Value.E, 2);
+ Assert.AreEqual(table.A.Value.F(0), -1);
+ Assert.AreEqual(table.A.Value.F(1), 1);
+
+ TestObjectAPI(table);
+ }
+
+ [FlatBuffersTestMethod]
+ public void TestUnionVector()
+ {
+ var fbb = new FlatBufferBuilder(100);
+ var rapunzel = Rapunzel.CreateRapunzel(fbb, 40).Value;
+
+ var characterTypes = new[]
+ {
+ Character.MuLan,
+ Character.Belle,
+ Character.Other,
+ };
+ var characterTypesOffset = Movie.CreateCharactersTypeVector(fbb, characterTypes);
+
+ var characters = new[]
+ {
+ Attacker.CreateAttacker(fbb, 10).Value,
+ BookReader.CreateBookReader(fbb, 20).Value,
+ fbb.CreateSharedString("Chip").Value,
+ };
+ var charactersOffset = Movie.CreateCharactersVector(fbb, characters);
+
+ var movieOffset = Movie.CreateMovie(
+ fbb,
+ Character.Rapunzel,
+ rapunzel,
+ characterTypesOffset,
+ charactersOffset);
+ Movie.FinishMovieBuffer(fbb, movieOffset);
+
+ var movie = Movie.GetRootAsMovie(fbb.DataBuffer);
+ Assert.AreEqual(Character.Rapunzel, movie.MainCharacterType);
+ Assert.AreEqual(40, movie.MainCharacter<Rapunzel>().Value.HairLength);
+
+ Assert.AreEqual(3, movie.CharactersLength);
+ Assert.AreEqual(Character.MuLan, movie.CharactersType(0));
+ Assert.AreEqual(10, movie.Characters<Attacker>(0).Value.SwordAttackDamage);
+ Assert.AreEqual(Character.Belle, movie.CharactersType(1));
+ Assert.AreEqual(20, movie.Characters<BookReader>(1).Value.BooksRead);
+ Assert.AreEqual(Character.Other, movie.CharactersType(2));
+ Assert.AreEqual("Chip", movie.CharactersAsString(2));
+
+ TestObjectAPI(movie);
+ }
+
+ private void AreEqual(Monster a, MonsterT b)
+ {
+ Assert.AreEqual(a.Hp, b.Hp);
+ Assert.AreEqual(a.Mana, b.Mana);
+ Assert.AreEqual(a.Name, b.Name);
+
+ var posA = a.Pos;
+ var posB = b.Pos;
+ if (posA != null)
+ {
+ Assert.AreEqual(posA.Value.X, posB.X);
+ Assert.AreEqual(posA.Value.Y, posB.Y);
+ Assert.AreEqual(posA.Value.Z, posB.Z);
+
+ Assert.AreEqual(posA.Value.Test1, posB.Test1);
+ Assert.AreEqual(posA.Value.Test2, posB.Test2);
+ var tA = posA.Value.Test3;
+ var tB = posB.Test3;
+ Assert.AreEqual(tA.A, tB.A);
+ Assert.AreEqual(tA.B, tB.B);
+ }
+
+ Assert.AreEqual(a.TestType, b.Test.Type);
+ if (a.TestType == Any.Monster)
+ {
+ var monster2A = a.Test<Monster>().Value;
+ var monster2B = b.Test.AsMonster();
+ Assert.AreEqual(monster2A.Name, monster2B.Name);
+ }
+
+ Assert.AreEqual(a.InventoryLength, b.Inventory.Count);
+ for (var i = 0; i < a.InventoryLength; ++i)
+ {
+ Assert.AreEqual(a.Inventory(i), b.Inventory[i]);
+ }
+
+ var inventoryArray = a.GetInventoryArray();
+ var inventoryArrayLength = inventoryArray == null ? 0 : inventoryArray.Length;
+ Assert.AreEqual(inventoryArrayLength, b.Inventory.Count);
+ for (var i = 0; i < inventoryArrayLength; ++i)
+ {
+ Assert.AreEqual(inventoryArray[i], b.Inventory[i]);
+ }
+
+ Assert.AreEqual(a.Test4Length, b.Test4.Count);
+ for (var i = 0; i < a.Test4Length; ++i)
+ {
+ var t4A = a.Test4(i);
+ var t4B = b.Test4[i];
+ Assert.AreEqual(t4A.Value.A, t4B.A);
+ Assert.AreEqual(t4A.Value.B, t4B.B);
+ }
+
+ Assert.AreEqual(a.TestarrayofstringLength, b.Testarrayofstring.Count);
+ for (var i = 0; i < a.TestarrayofstringLength; ++i)
+ {
+ Assert.AreEqual(a.Testarrayofstring(i), b.Testarrayofstring[i]);
+ }
+
+ Assert.AreEqual(a.Testbool, b.Testbool);
+
+ Assert.AreEqual(a.TestarrayofboolsLength, b.Testarrayofbools.Count);
+ for (var i = 0; i < a.TestarrayofboolsLength; ++i)
+ {
+ Assert.AreEqual(a.Testarrayofbools(i), b.Testarrayofbools[i]);
+ }
+
+ Assert.AreEqual(a.VectorOfLongsLength, b.VectorOfLongs.Count);
+ for (var i = 0; i < a.VectorOfLongsLength; ++i)
+ {
+ Assert.AreEqual(a.VectorOfLongs(i), b.VectorOfLongs[i]);
+ }
+
+ Assert.AreEqual(a.VectorOfDoublesLength, b.VectorOfDoubles.Count);
+ for (var i = 0; i < a.VectorOfDoublesLength; ++i)
+ {
+ Assert.AreEqual(a.VectorOfDoubles(i), b.VectorOfDoubles[i]);
+ }
+
+ Assert.AreEqual(a.VectorOfEnumsLength, b.VectorOfEnums.Count);
+ for (var i = 0; i < a.VectorOfEnumsLength; ++i)
+ {
+ Assert.AreEqual(a.VectorOfEnums(i), b.VectorOfEnums[i]);
+ }
+ }
+
+ private void AreEqual(Monster a, Monster b)
+ {
+ Assert.AreEqual(a.Hp, b.Hp);
+ Assert.AreEqual(a.Mana, b.Mana);
+ Assert.AreEqual(a.Name, b.Name);
+
+ var posA = a.Pos;
+ var posB = b.Pos;
+ if (posA != null)
+ {
+ Assert.AreEqual(posA.Value.X, posB.Value.X);
+ Assert.AreEqual(posA.Value.Y, posB.Value.Y);
+ Assert.AreEqual(posA.Value.Z, posB.Value.Z);
+
+ Assert.AreEqual(posA.Value.Test1, posB.Value.Test1);
+ Assert.AreEqual(posA.Value.Test2, posB.Value.Test2);
+ var tA = posA.Value.Test3;
+ var tB = posB.Value.Test3;
+ Assert.AreEqual(tA.A, tB.A);
+ Assert.AreEqual(tA.B, tB.B);
+ }
+
+ Assert.AreEqual(a.TestType, b.TestType);
+ if (a.TestType == Any.Monster)
+ {
+ var monster2A = a.Test<Monster>().Value;
+ var monster2B = b.Test<Monster>().Value;
+ Assert.AreEqual(monster2A.Name, monster2B.Name);
+ }
+
+ Assert.AreEqual(a.InventoryLength, b.InventoryLength);
+ for (var i = 0; i < a.InventoryLength; ++i)
+ {
+ Assert.AreEqual(a.Inventory(i), b.Inventory(i));
+ }
+
+ var inventoryArrayA = a.GetInventoryArray();
+ var inventoryArrayALength = inventoryArrayA == null ? 0 : inventoryArrayA.Length;
+ var inventoryArrayB = b.GetInventoryArray();
+ var inventoryArrayBLength = inventoryArrayB == null ? 0 : inventoryArrayB.Length;
+ Assert.AreEqual(inventoryArrayALength, inventoryArrayBLength);
+ for (var i = 0; i < inventoryArrayALength; ++i)
+ {
+ Assert.AreEqual(inventoryArrayA[i], inventoryArrayB[i]);
+ }
+
+ Assert.AreEqual(a.Test4Length, b.Test4Length);
+ for (var i = 0; i < a.Test4Length; ++i)
+ {
+ var t4A = a.Test4(i);
+ var t4B = b.Test4(i);
+ Assert.AreEqual(t4A.Value.A, t4B.Value.A);
+ Assert.AreEqual(t4A.Value.B, t4B.Value.B);
+ }
+
+ Assert.AreEqual(a.TestarrayofstringLength, b.TestarrayofstringLength);
+ for (var i = 0; i < a.TestarrayofstringLength; ++i)
+ {
+ Assert.AreEqual(a.Testarrayofstring(i), b.Testarrayofstring(i));
+ }
+
+ Assert.AreEqual(a.Testbool, b.Testbool);
+
+ Assert.AreEqual(a.TestarrayofboolsLength, b.TestarrayofboolsLength);
+ for (var i = 0; i < a.TestarrayofboolsLength; ++i)
+ {
+ Assert.AreEqual(a.Testarrayofbools(i), b.Testarrayofbools(i));
+ }
+
+ Assert.AreEqual(a.VectorOfLongsLength, b.VectorOfLongsLength);
+ for (var i = 0; i < a.VectorOfLongsLength; ++i)
+ {
+ Assert.AreEqual(a.VectorOfLongs(i), b.VectorOfLongs(i));
+ }
+
+ Assert.AreEqual(a.VectorOfDoublesLength, b.VectorOfDoublesLength);
+ for (var i = 0; i < a.VectorOfDoublesLength; ++i)
+ {
+ Assert.AreEqual(a.VectorOfDoubles(i), b.VectorOfDoubles(i));
+ }
+
+ Assert.AreEqual(a.VectorOfEnumsLength, b.VectorOfEnumsLength);
+ for (var i = 0; i < a.VectorOfEnumsLength; ++i)
+ {
+ Assert.AreEqual(a.VectorOfEnums(i), b.VectorOfEnums(i));
+ }
+ }
+
+ private void TestObjectAPI(Monster a)
+ {
+ var b = a.UnPack();
+ AreEqual(a, b);
+
+ var fbb = new FlatBufferBuilder(1);
+ fbb.Finish(Monster.Pack(fbb, b).Value);
+ var c = Monster.GetRootAsMonster(fbb.DataBuffer);
+ AreEqual(a, c);
+
+ var jsonText = b.SerializeToJson();
+ var d = MonsterT.DeserializeFromJson(jsonText);
+ AreEqual(a, d);
+
+ var fbBuffer = b.SerializeToBinary();
+ var e = MonsterT.DeserializeFromBinary(fbBuffer);
+ AreEqual(a, e);
+ }
+
+ private void AreEqual(ArrayTable a, ArrayTableT b)
+ {
+ Assert.AreEqual(a.A.Value.A, b.A.A);
+
+ for (int i = 0; i < 15; ++i)
+ {
+ Assert.AreEqual(a.A.Value.B(i), b.A.B[i]);
+ }
+
+ Assert.AreEqual(a.A.Value.C, b.A.C);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ var ad = a.A.Value.D(i);
+ var bd = b.A.D[i];
+
+ for (int j = 0; j < 2; ++j)
+ {
+ Assert.AreEqual(ad.A(j), bd.A[j]);
+ }
+
+ Assert.AreEqual(ad.B, bd.B);
+
+ for (int j = 0; j < 2; ++j)
+ {
+ Assert.AreEqual(ad.C(j), bd.C[j]);
+ }
+
+ for (int j = 0; j < 2; ++j)
+ {
+ Assert.AreEqual(ad.D(j), bd.D[j]);
+ }
+ }
+
+ Assert.AreEqual(a.A.Value.E, b.A.E);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ Assert.AreEqual(a.A.Value.F(i), b.A.F[i]);
+ }
+ }
+
+ private void AreEqual(ArrayTable a, ArrayTable b)
+ {
+ Assert.AreEqual(a.A.Value.A, b.A.Value.A);
+
+ for (int i = 0; i < 15; ++i)
+ {
+ Assert.AreEqual(a.A.Value.B(i), b.A.Value.B(i));
+ }
+
+ Assert.AreEqual(a.A.Value.C, b.A.Value.C);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ var ad = a.A.Value.D(i);
+ var bd = b.A.Value.D(i);
+
+ for (int j = 0; j < 2; ++j)
+ {
+ Assert.AreEqual(ad.A(j), bd.A(j));
+ }
+
+ Assert.AreEqual(ad.B, bd.B);
+
+ for (int j = 0; j < 2; ++j)
+ {
+ Assert.AreEqual(ad.C(j), bd.C(j));
+ }
+
+ for (int j = 0; j < 2; ++j)
+ {
+ Assert.AreEqual(ad.D(j), bd.D(j));
+ }
+ }
+
+ Assert.AreEqual(a.A.Value.E, b.A.Value.E);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ Assert.AreEqual(a.A.Value.F(i), b.A.Value.F(i));
+ }
+ }
+
+ private void TestObjectAPI(ArrayTable a)
+ {
+ var b = a.UnPack();
+ AreEqual(a, b);
+
+ var fbb = new FlatBufferBuilder(1);
+ fbb.Finish(ArrayTable.Pack(fbb, b).Value);
+ var c = ArrayTable.GetRootAsArrayTable(fbb.DataBuffer);
+ AreEqual(a, c);
+
+ var jsonText = b.SerializeToJson();
+ var d = ArrayTableT.DeserializeFromJson(jsonText);
+ AreEqual(a, d);
+
+ var fbBuffer = b.SerializeToBinary();
+ var e = ArrayTableT.DeserializeFromBinary(fbBuffer);
+ AreEqual(a, e);
+ }
+
+ private void AreEqual(Movie a, MovieT b)
+ {
+ Assert.AreEqual(a.MainCharacterType, b.MainCharacter.Type);
+ Assert.AreEqual(a.MainCharacter<Rapunzel>().Value.HairLength, b.MainCharacter.AsRapunzel().HairLength);
+
+ Assert.AreEqual(a.CharactersLength, b.Characters.Count);
+ Assert.AreEqual(a.CharactersType(0), b.Characters[0].Type);
+ Assert.AreEqual(a.Characters<Attacker>(0).Value.SwordAttackDamage, b.Characters[0].AsMuLan().SwordAttackDamage);
+ Assert.AreEqual(a.CharactersType(1), b.Characters[1].Type);
+ Assert.AreEqual(a.Characters<BookReader>(1).Value.BooksRead, b.Characters[1].AsBelle().BooksRead);
+ Assert.AreEqual(a.CharactersType(2), b.Characters[2].Type);
+ Assert.AreEqual(a.CharactersAsString(2), b.Characters[2].AsOther());
+ }
+
+ private void AreEqual(Movie a, Movie b)
+ {
+ Assert.AreEqual(a.MainCharacterType, b.MainCharacterType);
+ Assert.AreEqual(a.MainCharacter<Rapunzel>().Value.HairLength, b.MainCharacter<Rapunzel>().Value.HairLength);
+
+ Assert.AreEqual(a.CharactersLength, b.CharactersLength);
+ Assert.AreEqual(a.CharactersType(0), b.CharactersType(0));
+ Assert.AreEqual(a.Characters<Attacker>(0).Value.SwordAttackDamage, b.Characters<Attacker>(0).Value.SwordAttackDamage);
+ Assert.AreEqual(a.CharactersType(1), b.CharactersType(1));
+ Assert.AreEqual(a.Characters<BookReader>(1).Value.BooksRead, b.Characters<BookReader>(1).Value.BooksRead);
+ Assert.AreEqual(a.CharactersType(2), b.CharactersType(2));
+ Assert.AreEqual(a.CharactersAsString(2), b.CharactersAsString(2));
+ }
+
+ private void TestObjectAPI(Movie a)
+ {
+ var b = a.UnPack();
+ AreEqual(a, b);
+
+ var fbb = new FlatBufferBuilder(1);
+ fbb.Finish(Movie.Pack(fbb, b).Value);
+ var c = Movie.GetRootAsMovie(fbb.DataBuffer);
+ AreEqual(a, c);
+
+ var jsonText = b.SerializeToJson();
+ var d = MovieT.DeserializeFromJson(jsonText);
+ AreEqual(a, d);
+
+ var fbBuffer = b.SerializeToBinary();
+ var e = MovieT.DeserializeFromBinary(fbBuffer);
+ AreEqual(a, e);
}
}
}
diff --git a/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs b/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
index 2d411a2b..b6c60ea6 100644
--- a/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
+++ b/tests/FlatBuffers.Test/FlatBuffersFuzzTests.cs
@@ -136,6 +136,17 @@ namespace FlatBuffers.Test
}
[FlatBuffersTestMethod]
+ public void TestCreateSharedAsciiString()
+ {
+ var builder = new FlatBufferBuilder(1);
+ builder.CreateSharedString("foo");
+ Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
+
+ builder.CreateSharedString("foo");
+ Assert.ArrayEqual(new byte[] { 3, 0, 0, 0, (byte)'f', (byte)'o', (byte)'o', 0 }, builder.DataBuffer.ToFullArray());
+ }
+
+ [FlatBuffersTestMethod]
public void TestCreateArbitarytring()
{
var builder = new FlatBufferBuilder(1);
@@ -163,9 +174,9 @@ namespace FlatBuffers.Test
public void TestEmptyVTable()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(0);
+ builder.StartTable(0);
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
4, 0, 4, 0,
@@ -178,10 +189,10 @@ namespace FlatBuffers.Test
public void TestVTableWithOneBool()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(1);
+ builder.StartTable(1);
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
builder.AddBool(0, true, false);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
0, 0, // padding to 16 bytes
@@ -199,10 +210,10 @@ namespace FlatBuffers.Test
public void TestVTableWithOneBool_DefaultValue()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(1);
+ builder.StartTable(1);
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
builder.AddBool(0, false, false);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
// No padding.
@@ -218,10 +229,10 @@ namespace FlatBuffers.Test
public void TestVTableWithOneInt16()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(1);
+ builder.StartTable(1);
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
builder.AddShort(0, 0x789A, 0);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
0, 0, // padding to 16 bytes
@@ -239,11 +250,11 @@ namespace FlatBuffers.Test
public void TestVTableWithTwoInt16()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(2);
+ builder.StartTable(2);
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
builder.AddShort(0, 0x3456, 0);
builder.AddShort(1, 0x789A, 0);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
8, 0, // vtable bytes
@@ -261,11 +272,11 @@ namespace FlatBuffers.Test
public void TestVTableWithInt16AndBool()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(2);
+ builder.StartTable(2);
Assert.ArrayEqual(new byte[] { 0 }, builder.DataBuffer.ToFullArray());
builder.AddShort(0, 0x3456, 0);
builder.AddBool(1, true, false);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
8, 0, // vtable bytes
@@ -286,10 +297,10 @@ namespace FlatBuffers.Test
builder.StartVector(sizeof(byte), 0, 1);
var vecEnd = builder.EndVector();
- builder.StartObject(1);
+ builder.StartTable(1);
builder.AddOffset(0, vecEnd.Value, 0);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
0, 0, 0, 0,
@@ -313,10 +324,10 @@ namespace FlatBuffers.Test
builder.StartVector(sizeof(byte), 0, 1);
var vecEnd = builder.EndVector();
- builder.StartObject(2);
+ builder.StartTable(2);
builder.AddShort(0, 55, 0);
builder.AddOffset(1, vecEnd.Value, 0);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
0, 0, 0, 0,
@@ -343,10 +354,10 @@ namespace FlatBuffers.Test
builder.AddShort(0x5678);
var vecEnd = builder.EndVector();
- builder.StartObject(2);
+ builder.StartTable(2);
builder.AddOffset(1, vecEnd.Value, 0);
builder.AddShort(0, 55, 0);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
0, 0, 0, 0, // Padding to 32 bytes
@@ -368,7 +379,7 @@ namespace FlatBuffers.Test
public void TestVTableWithAStruct_of_int8_int16_int32()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(1);
+ builder.StartTable(1);
builder.Prep(4+4+4, 0);
builder.AddSbyte(55);
builder.Pad(3);
@@ -377,7 +388,7 @@ namespace FlatBuffers.Test
builder.AddInt(0x12345678);
var structStart = builder.Offset;
builder.AddStruct(0, structStart, 0);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
0, 0, 0, 0,
@@ -405,9 +416,9 @@ namespace FlatBuffers.Test
builder.AddByte(66);
var vecEnd = builder.EndVector();
- builder.StartObject(1);
+ builder.StartTable(1);
builder.AddOffset(0, vecEnd.Value, 0);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
{
@@ -432,10 +443,10 @@ namespace FlatBuffers.Test
public void TestVTableWithSomeElements()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(2);
+ builder.StartTable(2);
builder.AddByte(0, 33, 0);
builder.AddShort(1, 66, 0);
- var off = builder.EndObject();
+ var off = builder.EndTable();
builder.Finish(off);
byte[] padded = new byte[]
@@ -465,17 +476,17 @@ namespace FlatBuffers.Test
public void TestTwoFinishTable()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(2);
+ builder.StartTable(2);
builder.AddByte(0, 33, 0);
builder.AddByte(1, 44, 0);
- var off0 = builder.EndObject();
+ var off0 = builder.EndTable();
builder.Finish(off0);
- builder.StartObject(3);
+ builder.StartTable(3);
builder.AddByte(0, 55, 0);
builder.AddByte(1, 66, 0);
builder.AddByte(2, 77, 0);
- var off1 = builder.EndObject();
+ var off1 = builder.EndTable();
builder.Finish(off1);
Assert.ArrayEqual(new byte[]
@@ -516,12 +527,12 @@ namespace FlatBuffers.Test
public void TestBunchOfBools()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(8);
+ builder.StartTable(8);
for (var i = 0; i < 8; i++)
{
builder.AddBool(i, true, false);
}
- var off = builder.EndObject();
+ var off = builder.EndTable();
builder.Finish(off);
byte[] padded = new byte[]
@@ -564,12 +575,12 @@ namespace FlatBuffers.Test
public void TestBunchOfBoolsSizePrefixed()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(8);
+ builder.StartTable(8);
for (var i = 0; i < 8; i++)
{
builder.AddBool(i, true, false);
}
- var off = builder.EndObject();
+ var off = builder.EndTable();
builder.FinishSizePrefixed(off);
byte[] padded = new byte[]
@@ -612,9 +623,9 @@ namespace FlatBuffers.Test
public void TestWithFloat()
{
var builder = new FlatBufferBuilder(1);
- builder.StartObject(1);
+ builder.StartTable(1);
builder.AddFloat(0, 1, 0);
- builder.EndObject();
+ builder.EndTable();
Assert.ArrayEqual(new byte[]
@@ -642,7 +653,7 @@ namespace FlatBuffers.Test
for (var i = 0; i < objectCount; ++i)
{
- builder.StartObject(fieldCount);
+ builder.StartTable(fieldCount);
for (var j = 0; j < fieldCount; ++j)
{
@@ -711,7 +722,7 @@ namespace FlatBuffers.Test
}
- var offset = builder.EndObject();
+ var offset = builder.EndTable();
// Store the object offset
objects[i] = offset;
diff --git a/tests/FlatBuffers.Test/NetTest.sh b/tests/FlatBuffers.Test/NetTest.sh
index 3822b493..10d5cddf 100644
--- a/tests/FlatBuffers.Test/NetTest.sh
+++ b/tests/FlatBuffers.Test/NetTest.sh
@@ -1,23 +1,41 @@
#!/bin/sh
+# Restore nuget packages
+mkdir dotnet_tmp
+curl -OL https://dot.net/v1/dotnet-install.sh
+chmod +x dotnet-install.sh
+./dotnet-install.sh --version 3.1.101 --install-dir dotnet_tmp
+dotnet_tmp/dotnet new sln
+dotnet_tmp/dotnet sln add FlatBuffers.Test.csproj
+curl -OL https://dist.nuget.org/win-x86-commandline/v5.4.0/nuget.exe
+mono nuget.exe restore
+
+# Copy Test Files
+cp ../monsterdata_test.mon Resources/
+cp ../monsterdata_test.json Resources/
+
# Testing C# on Linux using Mono.
-mcs -debug -out:./fbnettest.exe \
- ../../net/FlatBuffers/*.cs ../MyGame/Example/*.cs ../MyGame/*.cs ../union_vector/*.cs \
- FlatBuffersTestClassAttribute.cs FlatBuffersTestMethodAttribute.cs Assert.cs FlatBuffersExampleTests.cs Program.cs ByteBufferTests.cs FlatBufferBuilderTests.cs FlatBuffersFuzzTests.cs FuzzTestData.cs Lcg.cs TestTable.cs
-mono --debug ./fbnettest.exe
-rm fbnettest.exe
+msbuild -property:Configuration=Release,OutputPath=tempcs -verbosity:minimal FlatBuffers.Test.csproj
+mono tempcs/FlatBuffers.Test.exe
+rm -fr tempcs
rm Resources/monsterdata_cstest.mon
rm Resources/monsterdata_cstest_sp.mon
# Repeat with unsafe versions
-mcs -debug -out:./fbnettest.exe \
- -unsafe -d:UNSAFE_BYTEBUFFER \
- ../../net/FlatBuffers/*.cs ../MyGame/Example/*.cs ../MyGame/*.cs ../union_vector/*.cs\
- FlatBuffersTestClassAttribute.cs FlatBuffersTestMethodAttribute.cs Assert.cs FlatBuffersExampleTests.cs Program.cs ByteBufferTests.cs FlatBufferBuilderTests.cs FlatBuffersFuzzTests.cs FuzzTestData.cs Lcg.cs TestTable.cs
-mono --debug ./fbnettest.exe
-rm fbnettest.exe
+msbuild -property:Configuration=Release,UnsafeByteBuffer=true,OutputPath=tempcsUnsafe -verbosity:minimal FlatBuffers.Test.csproj
+mono tempcsUnsafe/FlatBuffers.Test.exe
+rm -fr tempcsUnsafe
rm Resources/monsterdata_cstest.mon
rm Resources/monsterdata_cstest_sp.mon
+# Remove Temp Files
+rm -fr dotnet_tmp
+rm -fr packages
+rm dotnet-install.sh
+rm nuget.exe
+rm FlatBuffers.Test.sln
+rm Resources/monsterdata_test.mon
+rm Resources/monsterdata_test.json
+
diff --git a/tests/FlatBuffers.Test/Resources/.gitkeep b/tests/FlatBuffers.Test/Resources/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/FlatBuffers.Test/Resources/.gitkeep
diff --git a/tests/FlatBuffers.Test/Resources/monsterdata_test.mon b/tests/FlatBuffers.Test/Resources/monsterdata_test.mon
deleted file mode 100644
index 3f839723..00000000
--- a/tests/FlatBuffers.Test/Resources/monsterdata_test.mon
+++ /dev/null
Binary files differ
diff --git a/tests/FlatBuffers.Test/TestTable.cs b/tests/FlatBuffers.Test/TestTable.cs
index 2b506b65..4f663f01 100644
--- a/tests/FlatBuffers.Test/TestTable.cs
+++ b/tests/FlatBuffers.Test/TestTable.cs
@@ -25,8 +25,7 @@ namespace FlatBuffers.Test
public TestTable(ByteBuffer bb, int pos)
{
- t.bb = bb;
- t.bb_pos = pos;
+ t = new Table(pos, bb);
}
public bool GetSlot(int slot, bool def)
diff --git a/tests/FlatBuffers.Test/packages.config b/tests/FlatBuffers.Test/packages.config
new file mode 100644
index 00000000..d766d047
--- /dev/null
+++ b/tests/FlatBuffers.Test/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net35" />
+</packages> \ No newline at end of file
diff --git a/tests/GoTest.sh b/tests/GoTest.sh
index f50b91df..60ef9277 100755
--- a/tests/GoTest.sh
+++ b/tests/GoTest.sh
@@ -20,7 +20,7 @@ go_path=${test_dir}/go_gen
go_src=${go_path}/src
# Emit Go code for the example schema in the test dir:
-../flatc -g -I include_test monster_test.fbs
+../flatc -g --gen-object-api -I include_test monster_test.fbs
# Go requires a particular layout of files in order to link multiple packages.
# Copy flatbuffer Go files to their own package directories to compile the
@@ -67,7 +67,9 @@ fi
NOT_FMT_FILES=$(gofmt -l MyGame)
if [[ ${NOT_FMT_FILES} != "" ]]; then
- echo "These files are not well gofmt'ed:\n\n${NOT_FMT_FILES}"
+ echo "These files are not well gofmt'ed:"
+ echo
+ echo "${NOT_FMT_FILES}"
# enable this when enums are properly formated
# exit 1
fi
diff --git a/tests/JavaScriptTest.js b/tests/JavaScriptTest.js
index f581b1d1..7116daaf 100644
--- a/tests/JavaScriptTest.js
+++ b/tests/JavaScriptTest.js
@@ -246,8 +246,10 @@ function testUnicode() {
MyGame.Example.Monster.addTestarrayofstring(fbb, testarrayofstringOffset);
MyGame.Example.Monster.addTestarrayoftables(fbb, testarrayoftablesOffset);
MyGame.Example.Monster.addName(fbb, name);
- MyGame.Example.Monster.finishMonsterBuffer(fbb, MyGame.Example.Monster.endMonster(fbb));
- testReadingUnicode(new flatbuffers.ByteBuffer(fbb.asUint8Array()));
+ MyGame.Example.Monster.finishSizePrefixedMonsterBuffer(fbb, MyGame.Example.Monster.endMonster(fbb));
+ var bb = new flatbuffers.ByteBuffer(fbb.asUint8Array())
+ bb.setPosition(4);
+ testReadingUnicode(bb);
}
var __imul = Math.imul ? Math.imul : function(a, b) {
diff --git a/tests/JavaTest.java b/tests/JavaTest.java
index 1a9b7018..5ea9baad 100644
--- a/tests/JavaTest.java
+++ b/tests/JavaTest.java
@@ -1,3 +1,31 @@
+
+import static com.google.flatbuffers.Constants.*;
+
+import MyGame.Example.*;
+import MyGame.MonsterExtra;
+import NamespaceA.*;
+import NamespaceA.NamespaceB.*;
+import com.google.flatbuffers.ByteBufferUtil;
+import com.google.flatbuffers.ByteVector;
+import com.google.flatbuffers.FlatBufferBuilder;
+import com.google.flatbuffers.FlexBuffers;
+import com.google.flatbuffers.FlexBuffersBuilder;
+import com.google.flatbuffers.StringVector;
+import com.google.flatbuffers.UnionVector;
+import com.google.flatbuffers.FlexBuffers.FlexBufferException;
+import com.google.flatbuffers.FlexBuffers.Reference;
+import com.google.flatbuffers.FlexBuffers.Vector;
+import com.google.flatbuffers.ArrayReadWriteBuf;
+
+import java.io.*;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
/*
* Copyright 2014 Google Inc. All rights reserved.
*
@@ -14,17 +42,7 @@
* limitations under the License.
*/
-import java.io.*;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
-import MyGame.Example.*;
-import NamespaceA.*;
-import NamespaceA.NamespaceB.*;
-import com.google.flatbuffers.ByteBufferUtil;
-import static com.google.flatbuffers.Constants.*;
-import com.google.flatbuffers.FlatBufferBuilder;
-import MyGame.MonsterExtra;
+
class JavaTest {
public static void main(String[] args) {
@@ -75,6 +93,12 @@ class JavaTest {
TestVectorOfUnions();
+ TestFixedLengthArrays();
+
+ TestFlexBuffers();
+
+ TestVectorOfBytes();
+
System.out.println("FlatBuffers test: completed successfully");
}
@@ -101,7 +125,8 @@ class JavaTest {
TestEq(pos.y(), 2.0f);
TestEq(pos.z(), 3.0f);
TestEq(pos.test1(), 3.0);
- TestEq(pos.test2(), Color.Green);
+ // issue: int != byte
+ TestEq(pos.test2(), (int) Color.Green);
Test t = pos.test3();
TestEq(t.a(), (short)5);
TestEq(t.b(), (byte)6);
@@ -117,6 +142,14 @@ class JavaTest {
invsum += monster.inventory(i);
TestEq(invsum, 10);
+ // Method using a vector access object:
+ ByteVector inventoryVector = monster.inventoryVector();
+ TestEq(inventoryVector.length(), 5);
+ invsum = 0;
+ for (int i = 0; i < inventoryVector.length(); i++)
+ invsum += inventoryVector.getAsUnsigned(i);
+ TestEq(invsum, 10);
+
// Alternative way of accessing a vector:
ByteBuffer ibb = monster.inventoryAsByteBuffer();
invsum = 0;
@@ -129,10 +162,22 @@ class JavaTest {
TestEq(monster.test4Length(), 2);
TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
+ Test.Vector test4Vector = monster.test4Vector();
+ test_0 = test4Vector.get(0);
+ test_1 = test4Vector.get(1);
+ TestEq(test4Vector.length(), 2);
+ TestEq(test_0.a() + test_0.b() + test_1.a() + test_1.b(), 100);
+
TestEq(monster.testarrayofstringLength(), 2);
TestEq(monster.testarrayofstring(0),"test1");
TestEq(monster.testarrayofstring(1),"test2");
+ // Method using a vector access object:
+ StringVector testarrayofstringVector = monster.testarrayofstringVector();
+ TestEq(testarrayofstringVector.length(), 2);
+ TestEq(testarrayofstringVector.get(0),"test1");
+ TestEq(testarrayofstringVector.get(1),"test2");
+
TestEq(monster.testbool(), true);
}
@@ -209,6 +254,10 @@ class JavaTest {
TestEq(monsterObject.inventory(1), (int)inventory[1]);
TestEq(monsterObject.inventoryLength(), inventory.length);
+ ByteVector inventoryVector = monsterObject.inventoryVector();
+ TestEq(inventoryVector.getAsUnsigned(1), (int)inventory[1]);
+ TestEq(inventoryVector.length(), inventory.length);
+
TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
}
@@ -230,6 +279,9 @@ class JavaTest {
TestEq(monsterObject.inventory(1), (int)inventory[1]);
TestEq(monsterObject.inventoryLength(), inventory.length);
+ ByteVector inventoryVector = monsterObject.inventoryVector();
+ TestEq(inventoryVector.getAsUnsigned(1), (int)inventory[1]);
+ TestEq(inventoryVector.length(), inventory.length);
TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
}
@@ -239,7 +291,9 @@ class JavaTest {
public ByteBuffer newByteBuffer(int capacity) {
ByteBuffer bb;
try {
- bb = new RandomAccessFile("javatest.bin", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN);
+ RandomAccessFile f = new RandomAccessFile("javatest.bin", "rw");
+ bb = f.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN);
+ f.close();
} catch(Throwable e) {
System.out.println("FlatBuffers test: couldn't map ByteBuffer to a file");
bb = null;
@@ -377,18 +431,21 @@ class JavaTest {
TestEq(monster.testarrayoftables(0).name(), "Barney");
TestEq(monster.testarrayoftables(1).name(), "Frodo");
TestEq(monster.testarrayoftables(2).name(), "Wilma");
+ Monster.Vector testarrayoftablesVector = monster.testarrayoftablesVector();
+ TestEq(testarrayoftablesVector.get(0).name(), "Barney");
+ TestEq(testarrayoftablesVector.get(1).name(), "Frodo");
+ TestEq(testarrayoftablesVector.get(2).name(), "Wilma");
// Example of searching for a table by the key
TestEq(monster.testarrayoftablesByKey("Frodo").name(), "Frodo");
TestEq(monster.testarrayoftablesByKey("Barney").name(), "Barney");
TestEq(monster.testarrayoftablesByKey("Wilma").name(), "Wilma");
+ TestEq(testarrayoftablesVector.getByKey("Frodo").name(), "Frodo");
+ TestEq(testarrayoftablesVector.getByKey("Barney").name(), "Barney");
+ TestEq(testarrayoftablesVector.getByKey("Wilma").name(), "Wilma");
// testType is an existing field and mutating it should succeed
TestEq(monster.testType(), (byte)Any.Monster);
- TestEq(monster.mutateTestType(Any.NONE), true);
- TestEq(monster.testType(), (byte)Any.NONE);
- TestEq(monster.mutateTestType(Any.Monster), true);
- TestEq(monster.testType(), (byte)Any.Monster);
//mutate the inventory vector
TestEq(monster.mutateInventory(0, 1), true);
@@ -400,6 +457,10 @@ class JavaTest {
for (int i = 0; i < monster.inventoryLength(); i++) {
TestEq(monster.inventory(i), i + 1);
}
+ ByteVector inventoryVector = monster.inventoryVector();
+ for (int i = 0; i < inventoryVector.length(); i++) {
+ TestEq((int)inventoryVector.get(i), i + 1);
+ }
//reverse mutation
TestEq(monster.mutateInventory(0, 0), true);
@@ -442,19 +503,675 @@ class JavaTest {
);
final Movie movie = Movie.getRootAsMovie(fbb.dataBuffer());
+ ByteVector charactersTypeByteVector = movie.charactersTypeVector();
+ UnionVector charactersVector = movie.charactersVector();
TestEq(movie.charactersTypeLength(), characterTypeVector.length);
+ TestEq(charactersTypeByteVector.length(), characterTypeVector.length);
TestEq(movie.charactersLength(), characterVector.length);
+ TestEq(charactersVector.length(), characterVector.length);
TestEq(movie.charactersType(0), characterTypeVector[0]);
+ TestEq(charactersTypeByteVector.get(0), characterTypeVector[0]);
TestEq(((Attacker)movie.characters(new Attacker(), 0)).swordAttackDamage(), swordAttackDamage);
}
+ static void TestFixedLengthArrays() {
+ FlatBufferBuilder builder = new FlatBufferBuilder(0);
+
+ float a;
+ int[] b = new int[15];
+ byte c;
+ int[][] d_a = new int[2][2];
+ byte[] d_b = new byte[2];
+ byte[][] d_c = new byte[2][2];
+ long[][] d_d = new long[2][2];
+ int e;
+ long[] f = new long[2];
+
+ a = 0.5f;
+ for (int i = 0; i < 15; i++) b[i] = i;
+ c = 1;
+ d_a[0][0] = 1;
+ d_a[0][1] = 2;
+ d_a[1][0] = 3;
+ d_a[1][1] = 4;
+ d_b[0] = TestEnum.B;
+ d_b[1] = TestEnum.C;
+ d_c[0][0] = TestEnum.A;
+ d_c[0][1] = TestEnum.B;
+ d_c[1][0] = TestEnum.C;
+ d_c[1][1] = TestEnum.B;
+ d_d[0][0] = -1;
+ d_d[0][1] = 1;
+ d_d[1][0] = -2;
+ d_d[1][1] = 2;
+ e = 2;
+ f[0] = -1;
+ f[1] = 1;
+
+ int arrayOffset = ArrayStruct.createArrayStruct(builder,
+ a, b, c, d_a, d_b, d_c, d_d, e, f);
+
+ // Create a table with the ArrayStruct.
+ ArrayTable.startArrayTable(builder);
+ ArrayTable.addA(builder, arrayOffset);
+ int tableOffset = ArrayTable.endArrayTable(builder);
+
+ ArrayTable.finishArrayTableBuffer(builder, tableOffset);
+
+ ArrayTable table = ArrayTable.getRootAsArrayTable(builder.dataBuffer());
+ NestedStruct nested = new NestedStruct();
+
+ TestEq(table.a().a(), 0.5f);
+ for (int i = 0; i < 15; i++) TestEq(table.a().b(i), i);
+ TestEq(table.a().c(), (byte)1);
+ TestEq(table.a().d(nested, 0).a(0), 1);
+ TestEq(table.a().d(nested, 0).a(1), 2);
+ TestEq(table.a().d(nested, 1).a(0), 3);
+ TestEq(table.a().d(nested, 1).a(1), 4);
+ TestEq(table.a().d(nested, 0).b(), TestEnum.B);
+ TestEq(table.a().d(nested, 1).b(), TestEnum.C);
+ TestEq(table.a().d(nested, 0).c(0), TestEnum.A);
+ TestEq(table.a().d(nested, 0).c(1), TestEnum.B);
+ TestEq(table.a().d(nested, 1).c(0), TestEnum.C);
+ TestEq(table.a().d(nested, 1).c(1), TestEnum.B);
+ TestEq(table.a().d(nested, 0).d(0), (long)-1);
+ TestEq(table.a().d(nested, 0).d(1), (long)1);
+ TestEq(table.a().d(nested, 1).d(0), (long)-2);
+ TestEq(table.a().d(nested, 1).d(1), (long)2);
+ TestEq(table.a().e(), 2);
+ TestEq(table.a().f(0), (long)-1);
+ TestEq(table.a().f(1), (long)1);
+ }
+
+ public static void testFlexBuffersTest() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
+ FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
+
+ // Write the equivalent of:
+ // { vec: [ -100, "Fred", 4.0, false ], bar: [ 1, 2, 3 ], bar3: [ 1, 2, 3 ],
+ // foo: 100, bool: true, mymap: { foo: "Fred" } }
+ // It's possible to do this without std::function support as well.
+ int map1 = builder.startMap();
+
+ int vec1 = builder.startVector();
+ builder.putInt(-100);
+ builder.putString("Fred");
+ builder.putBlob(new byte[]{(byte) 77});
+ builder.putBoolean(false);
+ builder.putInt(Long.MAX_VALUE);
+
+ int map2 = builder.startMap();
+ builder.putInt("test", 200);
+ builder.endMap(null, map2);
+
+ builder.putFloat(150.9);
+ builder.putFloat(150.9999998);
+ builder.endVector("vec", vec1, false, false);
+
+ vec1 = builder.startVector();
+ builder.putInt(1);
+ builder.putInt(2);
+ builder.putInt(3);
+ builder.endVector("bar", vec1, true, false);
+
+ vec1 = builder.startVector();
+ builder.putBoolean(true);
+ builder.putBoolean(false);
+ builder.putBoolean(true);
+ builder.putBoolean(false);
+ builder.endVector("bools", vec1, true, false);
+
+ builder.putBoolean("bool", true);
+ builder.putFloat("foo", 100);
+
+ map2 = builder.startMap();
+ builder.putString("bar", "Fred"); // Testing key and string reuse.
+ builder.putInt("int", -120);
+ builder.putFloat("float", -123.0f);
+ builder.putBlob("blob", new byte[]{ 65, 67 });
+ builder.endMap("mymap", map2);
+
+ builder.endMap(null, map1);
+ builder.finish();
+
+ FlexBuffers.Map m = FlexBuffers.getRoot(builder.getBuffer()).asMap();
+
+ TestEq(m.size(), 6);
+
+ // test empty (an null)
+ TestEq(m.get("no_key").asString(), ""); // empty if fail
+ TestEq(m.get("no_key").asMap(), FlexBuffers.Map.empty()); // empty if fail
+ TestEq(m.get("no_key").asKey(), FlexBuffers.Key.empty()); // empty if fail
+ TestEq(m.get("no_key").asVector(), FlexBuffers.Vector.empty()); // empty if fail
+ TestEq(m.get("no_key").asBlob(), FlexBuffers.Blob.empty()); // empty if fail
+ assert(m.get("no_key").asVector().isEmpty()); // empty if fail
+
+ // testing "vec" field
+ FlexBuffers.Vector vec = m.get("vec").asVector();
+ TestEq(vec.size(), 8);
+ TestEq(vec.get(0).asLong(), (long) -100);
+ TestEq(vec.get(1).asString(), "Fred");
+ TestEq(vec.get(2).isBlob(), true);
+ TestEq(vec.get(2).asBlob().size(), 1);
+ TestEq(vec.get(2).asBlob().data().get(0), (byte) 77);
+ TestEq(vec.get(3).isBoolean(), true); // Check if type is a bool
+ TestEq(vec.get(3).asBoolean(), false); // Check if value is false
+ TestEq(vec.get(4).asLong(), Long.MAX_VALUE);
+ TestEq(vec.get(5).isMap(), true);
+ TestEq(vec.get(5).asMap().get("test").asInt(), 200);
+ TestEq(Float.compare((float)vec.get(6).asFloat(), 150.9f), 0);
+ TestEq(Double.compare(vec.get(7).asFloat(), 150.9999998), 0);
+ TestEq((long)0, (long)vec.get(1).asLong()); //conversion fail returns 0 as C++
+
+ // bar vector
+ FlexBuffers.Vector tvec = m.get("bar").asVector();
+ TestEq(tvec.size(), 3);
+ TestEq(tvec.get(0).asInt(), 1);
+ TestEq(tvec.get(1).asInt(), 2);
+ TestEq(tvec.get(2).asInt(), 3);
+ TestEq(((FlexBuffers.TypedVector) tvec).getElemType(), FlexBuffers.FBT_INT);
+
+ // bools vector
+ FlexBuffers.Vector bvec = m.get("bools").asVector();
+ TestEq(bvec.size(), 4);
+ TestEq(bvec.get(0).asBoolean(), true);
+ TestEq(bvec.get(1).asBoolean(), false);
+ TestEq(bvec.get(2).asBoolean(), true);
+ TestEq(bvec.get(3).asBoolean(), false);
+ TestEq(((FlexBuffers.TypedVector) bvec).getElemType(), FlexBuffers.FBT_BOOL);
+
+
+ TestEq((float)m.get("foo").asFloat(), (float) 100);
+ TestEq(m.get("unknown").isNull(), true);
+
+ // mymap vector
+ FlexBuffers.Map mymap = m.get("mymap").asMap();
+ TestEq(mymap.keys().get(0), m.keys().get(0)); // These should be equal by pointer equality, since key and value are shared.
+ TestEq(mymap.keys().get(0).toString(), "bar");
+ TestEq(mymap.values().get(0).asString(), vec.get(1).asString());
+ TestEq(mymap.get("int").asInt(), -120);
+ TestEq((float)mymap.get("float").asFloat(), -123.0f);
+ TestEq(Arrays.equals(mymap.get("blob").asBlob().getBytes(), new byte[]{ 65, 67 }), true);
+ TestEq(mymap.get("blob").asBlob().toString(), "AC");
+ TestEq(mymap.get("blob").toString(), "\"AC\"");
+ }
+
+ public static void testFlexBufferVectorStrings() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000000));
+
+ int size = 3000;
+ StringBuilder sb = new StringBuilder();
+ for (int i=0; i< size; i++) {
+ sb.append("a");
+ }
+
+ String text = sb.toString();
+ TestEq(text.length(), size);
+
+ int pos = builder.startVector();
+
+ for (int i=0; i<size; i++) {
+ builder.putString(text);
+ }
+
+ try {
+ builder.endVector(null, pos, true, false);
+ // this should raise an exception as
+ // typed vector of string was deprecated
+ assert false;
+ } catch(FlexBufferException fb) {
+ // no op
+ }
+ // we finish the vector again as non-typed
+ builder.endVector(null, pos, false, false);
+
+ ByteBuffer b = builder.finish();
+ Vector v = FlexBuffers.getRoot(b).asVector();
+
+ TestEq(v.size(), size);
+ for (int i=0; i<size; i++) {
+ TestEq(v.get(i).asString().length(), size);
+ TestEq(v.get(i).asString(), text);
+ }
+ }
+
+ public static void testDeprecatedTypedVectorString() {
+ // tests whether we are able to support reading deprecated typed vector string
+ // data is equivalent to [ "abc", "abc", "abc", "abc"]
+ byte[] data = new byte[] {0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00,
+ 0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00, 0x04, 0x14, 0x10,
+ 0x0c, 0x08, 0x04, 0x3c, 0x01};
+ Reference ref = FlexBuffers.getRoot(ByteBuffer.wrap(data));
+ TestEq(ref.getType(), FlexBuffers.FBT_VECTOR_STRING_DEPRECATED);
+ TestEq(ref.isTypedVector(), true);
+ Vector vec = ref.asVector();
+ for (int i=0; i< vec.size(); i++) {
+ TestEq("abc", vec.get(i).asString());
+ }
+ }
+
+ public static void testSingleElementBoolean() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(100));
+ builder.putBoolean(true);
+ ByteBuffer b = builder.finish();
+ assert(FlexBuffers.getRoot(b).asBoolean());
+ }
+
+ public static void testSingleElementByte() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putInt(10);
+ ByteBuffer b = builder.finish();
+ TestEq(10, FlexBuffers.getRoot(b).asInt());
+ }
+
+ public static void testSingleElementShort() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putInt(Short.MAX_VALUE);
+ ByteBuffer b = builder.finish();
+ TestEq(Short.MAX_VALUE, (short)FlexBuffers.getRoot(b).asInt());
+ }
+
+ public static void testSingleElementInt() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putInt(Integer.MIN_VALUE);
+ ByteBuffer b = builder.finish();
+ TestEq(Integer.MIN_VALUE, FlexBuffers.getRoot(b).asInt());
+ }
+
+ public static void testSingleElementLong() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putInt(Long.MAX_VALUE);
+ ByteBuffer b = builder.finish();
+ TestEq(Long.MAX_VALUE, FlexBuffers.getRoot(b).asLong());
+ }
+
+ public static void testSingleElementFloat() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putFloat(Float.MAX_VALUE);
+ ByteBuffer b = builder.finish();
+ TestEq(Float.compare(Float.MAX_VALUE, (float) FlexBuffers.getRoot(b).asFloat()), 0);
+ }
+
+ public static void testSingleElementDouble() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putFloat(Double.MAX_VALUE);
+ ByteBuffer b = builder.finish();
+ TestEq(Double.compare(Double.MAX_VALUE, FlexBuffers.getRoot(b).asFloat()), 0);
+ }
+
+ public static void testSingleElementBigString() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
+ StringBuilder sb = new StringBuilder();
+
+ for (int i=0; i< 3000; i++) {
+ sb.append("a");
+ }
+
+ builder.putString(sb.toString());
+ ByteBuffer b = builder.finish();
+
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+
+ TestEq(FlexBuffers.FBT_STRING, r.getType());
+ TestEq(sb.toString(), r.asString());
+ }
+
+ public static void testSingleElementSmallString() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(10000));
+
+ builder.putString("aa");
+ ByteBuffer b = builder.finish();
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+
+ TestEq(FlexBuffers.FBT_STRING, r.getType());
+ TestEq("aa", r.asString());
+ }
+
+ public static void testSingleElementBlob() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putBlob(new byte[]{5, 124, 118, -1});
+ ByteBuffer b = builder.finish();
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+ byte[] result = r.asBlob().getBytes();
+ TestEq((byte)5, result[0]);
+ TestEq((byte)124, result[1]);
+ TestEq((byte)118, result[2]);
+ TestEq((byte)-1, result[3]);
+ }
+
+ public static void testSingleElementUByte() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putUInt(0xFF);
+ ByteBuffer b = builder.finish();
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+ TestEq(255, (int)r.asUInt());
+ }
+
+ public static void testSingleElementUShort() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putUInt(0xFFFF);
+ ByteBuffer b = builder.finish();
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+ TestEq(65535, (int)r.asUInt());
+ }
+
+ public static void testSingleElementUInt() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putUInt(0xFFFF_FFFFL);
+ ByteBuffer b = builder.finish();
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+ TestEq(4294967295L, r.asUInt());
+ }
+
+ public static void testSingleFixedTypeVector() {
+
+ int[] ints = new int[]{5, 124, 118, -1};
+ float[] floats = new float[]{5.5f, 124.124f, 118.118f, -1.1f};
+ String[] strings = new String[]{"This", "is", "a", "typed", "array"};
+ boolean[] booleans = new boolean[]{false, true, true, false};
+
+
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
+ FlexBuffersBuilder.BUILDER_FLAG_NONE);
+
+ int mapPos = builder.startMap();
+
+ int vecPos = builder.startVector();
+ for (final int i : ints) {
+ builder.putInt(i);
+ }
+ builder.endVector("ints", vecPos, true, false);
+
+ vecPos = builder.startVector();
+ for (final float i : floats) {
+ builder.putFloat(i);
+ }
+ builder.endVector("floats", vecPos, true, false);
+
+ vecPos = builder.startVector();
+ for (final boolean i : booleans) {
+ builder.putBoolean(i);
+ }
+ builder.endVector("booleans", vecPos, true, false);
+
+ builder.endMap(null, mapPos);
+
+
+ ByteBuffer b = builder.finish();
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b);
+ assert(r.asMap().get("ints").isTypedVector());
+ assert(r.asMap().get("floats").isTypedVector());
+ assert(r.asMap().get("booleans").isTypedVector());
+ }
+
+ public static void testSingleElementVector() {
+ FlexBuffersBuilder b = new FlexBuffersBuilder();
+
+ int vecPos = b.startVector();
+ b.putInt(99);
+ b.putString("wow");
+ int vecpos2 = b.startVector();
+ b.putInt(99);
+ b.putString("wow");
+ b.endVector(null, vecpos2, false, false);
+ b.endVector(null, vecPos, false, false);
+ b.finish();
+
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
+ TestEq(FlexBuffers.FBT_VECTOR, r.getType());
+ FlexBuffers.Vector vec = FlexBuffers.getRoot(b.getBuffer()).asVector();
+ TestEq(3, vec.size());
+ TestEq(99, vec.get(0).asInt());
+ TestEq("wow", vec.get(1).asString());
+ TestEq("[ 99, \"wow\" ]", vec.get(2).toString());
+ TestEq("[ 99, \"wow\", [ 99, \"wow\" ] ]", FlexBuffers.getRoot(b.getBuffer()).toString());
+ }
+
+ public static void testSingleElementMap() {
+ FlexBuffersBuilder b = new FlexBuffersBuilder();
+
+ int mapPost = b.startMap();
+ b.putInt("myInt", 0x7fffffbbbfffffffL);
+ b.putString("myString", "wow");
+ b.putString("myString2", "incredible");
+ int start = b.startVector();
+ b.putInt(99);
+ b.putString("wow");
+ b.endVector("myVec", start, false, false);
+
+ b.putFloat("double", 0x1.ffffbbbffffffP+1023);
+ b.endMap(null, mapPost);
+ b.finish();
+
+ FlexBuffers.Reference r = FlexBuffers.getRoot(b.getBuffer());
+ TestEq(FlexBuffers.FBT_MAP, r.getType());
+ FlexBuffers.Map map = FlexBuffers.getRoot(b.getBuffer()).asMap();
+ TestEq(5, map.size());
+ TestEq(0x7fffffbbbfffffffL, map.get("myInt").asLong());
+ TestEq("wow", map.get("myString").asString());
+ TestEq("incredible", map.get("myString2").asString());
+ TestEq(99, map.get("myVec").asVector().get(0).asInt());
+ TestEq("wow", map.get("myVec").asVector().get(1).asString());
+ TestEq(Double.compare(0x1.ffffbbbffffffP+1023, map.get("double").asFloat()), 0);
+ TestEq("{ \"double\" : 1.7976894783391937E308, \"myInt\" : 9223371743723257855, \"myString\" : \"wow\", \"myString2\" : \"incredible\", \"myVec\" : [ 99, \"wow\" ] }",
+ FlexBuffers.getRoot(b.getBuffer()).toString());
+ }
+
+ public static void testFlexBuferEmpty() {
+ FlexBuffers.Blob blob = FlexBuffers.Blob.empty();
+ FlexBuffers.Map ary = FlexBuffers.Map.empty();
+ FlexBuffers.Vector map = FlexBuffers.Vector.empty();
+ FlexBuffers.TypedVector typedAry = FlexBuffers.TypedVector.empty();
+ TestEq(blob.size(), 0);
+ TestEq(map.size(), 0);
+ TestEq(ary.size(), 0);
+ TestEq(typedAry.size(), 0);
+ }
+
+ public static void testHashMapToMap() {
+ int entriesCount = 12;
+
+ HashMap<String, String> source = new HashMap<>();
+ for (int i = 0; i < entriesCount; i++) {
+ source.put("foo_param_" + i, "foo_value_" + i);
+ }
+
+ FlexBuffersBuilder builder = new FlexBuffersBuilder(1000);
+ int mapStart = builder.startMap();
+ for (Map.Entry<String, String> entry : source.entrySet()) {
+ builder.putString(entry.getKey(), entry.getValue());
+ }
+ builder.endMap(null, mapStart);
+ ByteBuffer bb = builder.finish();
+ bb.rewind();
+
+ FlexBuffers.Reference rootReference = FlexBuffers.getRoot(bb);
+
+ TestEq(rootReference.isMap(), true);
+
+ FlexBuffers.Map flexMap = rootReference.asMap();
+
+ FlexBuffers.KeyVector keys = flexMap.keys();
+ FlexBuffers.Vector values = flexMap.values();
+
+ TestEq(entriesCount, keys.size());
+ TestEq(entriesCount, values.size());
+
+ HashMap<String, String> result = new HashMap<>();
+ for (int i = 0; i < keys.size(); i++) {
+ result.put(keys.get(i).toString(), values.get(i).asString());
+ }
+
+ TestEq(source, result);
+ }
+
+ public static void testBuilderGrowth() {
+ FlexBuffersBuilder builder = new FlexBuffersBuilder();
+ builder.putString("This is a small string");
+ ByteBuffer b = builder.finish();
+ TestEq("This is a small string", FlexBuffers.getRoot(b).asString());
+
+ FlexBuffersBuilder failBuilder = new FlexBuffersBuilder(ByteBuffer.allocate(1));
+ try {
+ failBuilder.putString("This is a small string");
+ // This should never be reached, it should throw an exception
+ // since ByteBuffers do not grow
+ assert(false);
+ } catch (java.lang.ArrayIndexOutOfBoundsException exception) {
+ // It should throw exception
+ }
+ }
+
+ public static void TestFlexBuffers() {
+ testSingleElementByte();
+ testSingleElementShort();
+ testSingleElementInt();
+ testSingleElementLong();
+ testSingleElementFloat();
+ testSingleElementDouble();
+ testSingleElementSmallString();
+ testSingleElementBigString();
+ testSingleElementBlob();
+ testSingleElementVector();
+ testSingleFixedTypeVector();
+ testSingleElementUShort();
+ testSingleElementUInt();
+ testSingleElementUByte();
+ testSingleElementMap();
+ testFlexBuffersTest();
+ testHashMapToMap();
+ testFlexBuferEmpty();
+ testFlexBufferVectorStrings();
+ testDeprecatedTypedVectorString();
+ testBuilderGrowth();
+ }
+
+ static void TestVectorOfBytes() {
+ FlatBufferBuilder fbb = new FlatBufferBuilder(16);
+ int str = fbb.createString("ByteMonster");
+ byte[] data = new byte[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ int offset = Monster.createInventoryVector(fbb, data);
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, offset);
+ int monster1 = Monster.endMonster(fbb);
+ Monster.finishMonsterBuffer(fbb, monster1);
+ Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ TestEq(monsterObject.inventoryLength(), data.length);
+ TestEq(monsterObject.inventory(4), (int) data[4]);
+ TestEq(ByteBuffer.wrap(data), monsterObject.inventoryAsByteBuffer());
+
+ fbb.clear();
+ ByteBuffer bb = ByteBuffer.wrap(data);
+ offset = fbb.createByteVector(bb);
+ str = fbb.createString("ByteMonster");
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, offset);
+ monster1 = Monster.endMonster(fbb);
+ Monster.finishMonsterBuffer(fbb, monster1);
+ Monster monsterObject2 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ TestEq(monsterObject2.inventoryLength(), data.length);
+ for (int i = 0; i < data.length; i++) {
+ TestEq(monsterObject2.inventory(i), (int) bb.get(i));
+ }
+
+ fbb.clear();
+ offset = fbb.createByteVector(data, 3, 4);
+ str = fbb.createString("ByteMonster");
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, offset);
+ monster1 = Monster.endMonster(fbb);
+ Monster.finishMonsterBuffer(fbb, monster1);
+ Monster monsterObject3 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ TestEq(monsterObject3.inventoryLength(), 4);
+ TestEq(monsterObject3.inventory(0), (int) data[3]);
+
+ fbb.clear();
+ bb = ByteBuffer.wrap(data);
+ offset = Monster.createInventoryVector(fbb, bb);
+ str = fbb.createString("ByteMonster");
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, offset);
+ monster1 = Monster.endMonster(fbb);
+ Monster.finishMonsterBuffer(fbb, monster1);
+ Monster monsterObject4 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ TestEq(monsterObject4.inventoryLength(), data.length);
+ TestEq(monsterObject4.inventory(8), (int) 8);
+
+ fbb.clear();
+ byte[] largeData = new byte[1024];
+ offset = fbb.createByteVector(largeData);
+ str = fbb.createString("ByteMonster");
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, offset);
+ monster1 = Monster.endMonster(fbb);
+ Monster.finishMonsterBuffer(fbb, monster1);
+ Monster monsterObject5 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ TestEq(monsterObject5.inventoryLength(), largeData.length);
+ TestEq(monsterObject5.inventory(25), (int) largeData[25]);
+
+ fbb.clear();
+ bb = ByteBuffer.wrap(largeData);
+ bb.position(512);
+ ByteBuffer bb2 = bb.slice();
+ TestEq(bb2.arrayOffset(), 512);
+ offset = fbb.createByteVector(bb2);
+ str = fbb.createString("ByteMonster");
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, offset);
+ monster1 = Monster.endMonster(fbb);
+ Monster.finishMonsterBuffer(fbb, monster1);
+ Monster monsterObject6 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ TestEq(monsterObject6.inventoryLength(), 512);
+ TestEq(monsterObject6.inventory(0), (int) largeData[512]);
+
+ fbb.clear();
+ bb = ByteBuffer.wrap(largeData);
+ bb.limit(256);
+ offset = fbb.createByteVector(bb);
+ str = fbb.createString("ByteMonster");
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, offset);
+ monster1 = Monster.endMonster(fbb);
+ Monster.finishMonsterBuffer(fbb, monster1);
+ Monster monsterObject7 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ TestEq(monsterObject7.inventoryLength(), 256);
+
+ fbb.clear();
+ bb = ByteBuffer.allocateDirect(2048);
+ offset = fbb.createByteVector(bb);
+ str = fbb.createString("ByteMonster");
+ Monster.startMonster(fbb);
+ Monster.addName(fbb, str);
+ Monster.addInventory(fbb, offset);
+ monster1 = Monster.endMonster(fbb);
+ Monster.finishMonsterBuffer(fbb, monster1);
+ Monster monsterObject8 = Monster.getRootAsMonster(fbb.dataBuffer());
+
+ TestEq(monsterObject8.inventoryLength(), 2048);
+ }
+
static <T> void TestEq(T a, T b) {
if (!a.equals(b)) {
System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
System.out.println("FlatBuffers test FAILED: \'" + a + "\' != \'" + b + "\'");
+ new Throwable().printStackTrace();
assert false;
System.exit(1);
}
diff --git a/tests/JavaTest.sh b/tests/JavaTest.sh
index 58d84429..9ec6933c 100755
--- a/tests/JavaTest.sh
+++ b/tests/JavaTest.sh
@@ -20,7 +20,7 @@ echo Compile then run the Java test.
java -version
-testdir="$(readlink -fn "$(dirname "$0")")"
+testdir=$(dirname $0)
targetdir="${testdir}/target"
diff --git a/tests/KotlinTest.kt b/tests/KotlinTest.kt
new file mode 100644
index 00000000..07f0465a
--- /dev/null
+++ b/tests/KotlinTest.kt
@@ -0,0 +1,460 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import MyGame.Example.*
+import com.google.flatbuffers.ByteBufferUtil
+import com.google.flatbuffers.FlatBufferBuilder
+import NamespaceA.*
+import NamespaceA.NamespaceB.*
+import NamespaceA.NamespaceB.TableInNestedNS
+import java.io.File
+import java.io.FileOutputStream
+import java.io.InputStream
+import java.io.RandomAccessFile
+import java.nio.ByteBuffer
+import java.nio.ByteOrder
+import java.nio.channels.FileChannel
+
+import com.google.flatbuffers.Constants.SIZE_PREFIX_LENGTH
+
+@kotlin.ExperimentalUnsignedTypes
+class KotlinTest {
+
+ companion object {
+ @JvmStatic
+ fun main(args: Array<String>) {
+
+ // First, let's test reading a FlatBuffer generated by C++ code:
+ // This file was generated from monsterdata_test.json
+
+ val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
+ val temp = ByteArray(it.length().toInt())
+ it.readFully(temp)
+ temp
+ }
+
+ // Now test it:
+
+ val bb = ByteBuffer.wrap(data)
+ TestBuffer(bb)
+
+ // Second, let's create a FlatBuffer from scratch in Java, and test it also.
+ // We use an initial size of 1 to exercise the reallocation algorithm,
+ // normally a size larger than the typical FlatBuffer you generate would be
+ // better for performance.
+ val fbb = FlatBufferBuilder(1)
+
+ TestBuilderBasics(fbb, true)
+ TestBuilderBasics(fbb, false)
+
+ TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer())
+
+ TestNamespaceNesting()
+
+ TestNestedFlatBuffer()
+
+ TestCreateByteVector()
+
+ TestCreateUninitializedVector()
+
+ TestByteBufferFactory()
+
+ TestSizedInputStream()
+
+ TestVectorOfUnions()
+
+ println("FlatBuffers test: completed successfully")
+ }
+
+ fun TestEnums() {
+ assert(Color.name(Color.Red.toInt()) == "Red")
+ assert(Color.name(Color.Blue.toInt()) == "Blue")
+ assert(Any_.name(Any_.NONE.toInt()) == "NONE")
+ assert(Any_.name(Any_.Monster.toInt()) == "Monster")
+ }
+
+ fun TestBuffer(bb: ByteBuffer) {
+ assert(Monster.MonsterBufferHasIdentifier(bb) == true)
+
+ val monster = Monster.getRootAsMonster(bb)
+
+ assert(monster.hp == 80.toShort())
+ assert(monster.mana == 150.toShort()) // default
+
+ assert(monster.name == "MyMonster")
+ // monster.friendly() // can't access, deprecated
+
+ val pos = monster.pos!!
+ assert(pos.x == 1.0f)
+ assert(pos.y == 2.0f)
+ assert(pos.z == 3.0f)
+ assert(pos.test1 == 3.0)
+ // issue: int != byte
+ assert(pos.test2 == Color.Green)
+ val t = pos.test3!!
+ assert(t.a == 5.toShort())
+ assert(t.b == 6.toByte())
+
+ assert(monster.testType == Any_.Monster)
+ val monster2 = Monster()
+ assert(monster.test(monster2) != null == true)
+ assert(monster2.name == "Fred")
+
+ assert(monster.inventoryLength == 5)
+ var invsum = 0u
+ for (i in 0 until monster.inventoryLength)
+ invsum += monster.inventory(i)
+ assert(invsum == 10u)
+
+ // Alternative way of accessing a vector:
+ val ibb = monster.inventoryAsByteBuffer
+ invsum = 0u
+ while (ibb.position() < ibb.limit())
+ invsum += ibb.get().toUInt()
+ assert(invsum == 10u)
+
+
+ val test_0 = monster.test4(0)!!
+ val test_1 = monster.test4(1)!!
+ assert(monster.test4Length == 2)
+ assert(test_0.a + test_0.b + test_1.a + test_1.b == 100)
+
+ assert(monster.testarrayofstringLength == 2)
+ assert(monster.testarrayofstring(0) == "test1")
+ assert(monster.testarrayofstring(1) == "test2")
+
+ assert(monster.testbool == true)
+ }
+
+ // this method checks additional fields not present in the binary buffer read from file
+ // these new tests are performed on top of the regular tests
+ fun TestExtendedBuffer(bb: ByteBuffer) {
+ TestBuffer(bb)
+
+ val monster = Monster.getRootAsMonster(bb)
+
+ assert(monster.testhashu32Fnv1 == (1u + Integer.MAX_VALUE.toUInt()))
+ }
+
+ fun TestNamespaceNesting() {
+ // reference / manipulate these to verify compilation
+ val fbb = FlatBufferBuilder(1)
+
+ TableInNestedNS.startTableInNestedNS(fbb)
+ TableInNestedNS.addFoo(fbb, 1234)
+ val nestedTableOff = TableInNestedNS.endTableInNestedNS(fbb)
+
+ TableInFirstNS.startTableInFirstNS(fbb)
+ TableInFirstNS.addFooTable(fbb, nestedTableOff)
+ }
+
+ fun TestNestedFlatBuffer() {
+ val nestedMonsterName = "NestedMonsterName"
+ val nestedMonsterHp: Short = 600
+ val nestedMonsterMana: Short = 1024
+
+ var fbb1: FlatBufferBuilder? = FlatBufferBuilder(16)
+ val str1 = fbb1!!.createString(nestedMonsterName)
+ Monster.startMonster(fbb1)
+ Monster.addName(fbb1, str1)
+ Monster.addHp(fbb1, nestedMonsterHp)
+ Monster.addMana(fbb1, nestedMonsterMana)
+ val monster1 = Monster.endMonster(fbb1)
+ Monster.finishMonsterBuffer(fbb1, monster1)
+ val fbb1Bytes = fbb1.sizedByteArray()
+
+ val fbb2 = FlatBufferBuilder(16)
+ val str2 = fbb2.createString("My Monster")
+ val nestedBuffer = Monster.createTestnestedflatbufferVector(fbb2, fbb1Bytes.asUByteArray())
+ Monster.startMonster(fbb2)
+ Monster.addName(fbb2, str2)
+ Monster.addHp(fbb2, 50.toShort())
+ Monster.addMana(fbb2, 32.toShort())
+ Monster.addTestnestedflatbuffer(fbb2, nestedBuffer)
+ val monster = Monster.endMonster(fbb2)
+ Monster.finishMonsterBuffer(fbb2, monster)
+
+ // Now test the data extracted from the nested buffer
+ val mons = Monster.getRootAsMonster(fbb2.dataBuffer())
+ val nestedMonster = mons.testnestedflatbufferAsMonster!!
+
+ assert(nestedMonsterMana == nestedMonster.mana)
+ assert(nestedMonsterHp == nestedMonster.hp)
+ assert(nestedMonsterName == nestedMonster.name)
+ }
+
+ fun TestCreateByteVector() {
+ val fbb = FlatBufferBuilder(16)
+ val str = fbb.createString("MyMonster")
+ val inventory = byteArrayOf(0, 1, 2, 3, 4)
+ val vec = fbb.createByteVector(inventory)
+ Monster.startMonster(fbb)
+ Monster.addInventory(fbb, vec)
+ Monster.addName(fbb, str)
+ val monster1 = Monster.endMonster(fbb)
+ Monster.finishMonsterBuffer(fbb, monster1)
+ val monsterObject = Monster.getRootAsMonster(fbb.dataBuffer())
+
+ assert(monsterObject.inventory(1) == inventory[1].toUByte())
+ assert(monsterObject.inventoryLength == inventory.size)
+ assert(ByteBuffer.wrap(inventory) == monsterObject.inventoryAsByteBuffer)
+ }
+
+ fun TestCreateUninitializedVector() {
+ val fbb = FlatBufferBuilder(16)
+ val str = fbb.createString("MyMonster")
+ val inventory = byteArrayOf(0, 1, 2, 3, 4)
+ val bb = fbb.createUnintializedVector(1, inventory.size, 1)
+ for (i in inventory) {
+ bb.put(i)
+ }
+ val vec = fbb.endVector()
+ Monster.startMonster(fbb)
+ Monster.addInventory(fbb, vec)
+ Monster.addName(fbb, str)
+ val monster1 = Monster.endMonster(fbb)
+ Monster.finishMonsterBuffer(fbb, monster1)
+ val monsterObject = Monster.getRootAsMonster(fbb.dataBuffer())
+
+ assert(monsterObject.inventory(1) == inventory[1].toUByte())
+ assert(monsterObject.inventoryLength == inventory.size)
+ assert(ByteBuffer.wrap(inventory) == monsterObject.inventoryAsByteBuffer)
+ }
+
+ fun TestByteBufferFactory() {
+ class MappedByteBufferFactory : FlatBufferBuilder.ByteBufferFactory() {
+ override fun newByteBuffer(capacity: Int): ByteBuffer? {
+ var bb: ByteBuffer?
+ try {
+ bb = RandomAccessFile("javatest.bin", "rw").channel.map(
+ FileChannel.MapMode.READ_WRITE,
+ 0,
+ capacity.toLong()
+ ).order(ByteOrder.LITTLE_ENDIAN)
+ } catch (e: Throwable) {
+ println("FlatBuffers test: couldn't map ByteBuffer to a file")
+ bb = null
+ }
+
+ return bb
+ }
+ }
+
+ val fbb = FlatBufferBuilder(1, MappedByteBufferFactory())
+
+ TestBuilderBasics(fbb, false)
+ }
+
+ fun TestSizedInputStream() {
+ // Test on default FlatBufferBuilder that uses HeapByteBuffer
+ val fbb = FlatBufferBuilder(1)
+
+ TestBuilderBasics(fbb, false)
+
+ val `in` = fbb.sizedInputStream()
+ val array = fbb.sizedByteArray()
+ var count = 0
+ var currentVal = 0
+
+ while (currentVal != -1 && count < array.size) {
+ try {
+ currentVal = `in`.read()
+ } catch (e: java.io.IOException) {
+ println("FlatBuffers test: couldn't read from InputStream")
+ return
+ }
+
+ assert(currentVal.toByte() == array[count])
+ count++
+ }
+ assert(count == array.size)
+ }
+
+ fun TestBuilderBasics(fbb: FlatBufferBuilder, sizePrefix: Boolean) {
+ val names = intArrayOf(fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma"))
+ val off = IntArray(3)
+ Monster.startMonster(fbb)
+ Monster.addName(fbb, names[0])
+ off[0] = Monster.endMonster(fbb)
+ Monster.startMonster(fbb)
+ Monster.addName(fbb, names[1])
+ off[1] = Monster.endMonster(fbb)
+ Monster.startMonster(fbb)
+ Monster.addName(fbb, names[2])
+ off[2] = Monster.endMonster(fbb)
+ val sortMons = fbb.createSortedVectorOfTables(Monster(), off)
+
+ // We set up the same values as monsterdata.json:
+
+ val str = fbb.createString("MyMonster")
+
+ val inv = Monster.createInventoryVector(fbb, byteArrayOf(0, 1, 2, 3, 4).asUByteArray())
+
+ val fred = fbb.createString("Fred")
+ Monster.startMonster(fbb)
+ Monster.addName(fbb, fred)
+ val mon2 = Monster.endMonster(fbb)
+
+ Monster.startTest4Vector(fbb, 2)
+ Test.createTest(fbb, 10.toShort(), 20.toByte())
+ Test.createTest(fbb, 30.toShort(), 40.toByte())
+ val test4 = fbb.endVector()
+
+ val testArrayOfString =
+ Monster.createTestarrayofstringVector(fbb, intArrayOf(fbb.createString("test1"), fbb.createString("test2")))
+
+ Monster.startMonster(fbb)
+ Monster.addPos(
+ fbb, Vec3.createVec3(
+ fbb, 1.0f, 2.0f, 3.0f, 3.0,
+ Color.Green, 5.toShort(), 6.toByte()
+ )
+ )
+ Monster.addHp(fbb, 80.toShort())
+ Monster.addName(fbb, str)
+ Monster.addInventory(fbb, inv)
+ Monster.addTestType(fbb, Any_.Monster)
+ Monster.addTest(fbb, mon2)
+ Monster.addTest4(fbb, test4)
+ Monster.addTestarrayofstring(fbb, testArrayOfString)
+ Monster.addTestbool(fbb, true)
+ Monster.addTesthashu32Fnv1(fbb, UInt.MAX_VALUE + 1u)
+ Monster.addTestarrayoftables(fbb, sortMons)
+ val mon = Monster.endMonster(fbb)
+
+ if (sizePrefix) {
+ Monster.finishSizePrefixedMonsterBuffer(fbb, mon)
+ } else {
+ Monster.finishMonsterBuffer(fbb, mon)
+ }
+
+ // Write the result to a file for debugging purposes:
+ // Note that the binaries are not necessarily identical, since the JSON
+ // parser may serialize in a slightly different order than the above
+ // Java code. They are functionally equivalent though.
+
+ try {
+ val filename = "monsterdata_java_wire" + (if (sizePrefix) "_sp" else "") + ".mon"
+ val fc = FileOutputStream(filename).channel
+ fc.write(fbb.dataBuffer().duplicate())
+ fc.close()
+ } catch (e: java.io.IOException) {
+ println("FlatBuffers test: couldn't write file")
+ return
+ }
+
+ // Test it:
+ var dataBuffer = fbb.dataBuffer()
+ if (sizePrefix) {
+ assert(
+ ByteBufferUtil.getSizePrefix(dataBuffer) + SIZE_PREFIX_LENGTH ==
+ dataBuffer.remaining()
+ )
+ dataBuffer = ByteBufferUtil.removeSizePrefix(dataBuffer)
+ }
+ TestExtendedBuffer(dataBuffer)
+
+ // Make sure it also works with read only ByteBuffers. This is slower,
+ // since creating strings incurs an additional copy
+ // (see Table.__string).
+ TestExtendedBuffer(dataBuffer.asReadOnlyBuffer())
+
+ TestEnums()
+
+ //Attempt to mutate Monster fields and check whether the buffer has been mutated properly
+ // revert to original values after testing
+ val monster = Monster.getRootAsMonster(dataBuffer)
+
+ // mana is optional and does not exist in the buffer so the mutation should fail
+ // the mana field should retain its default value
+ assert(monster.mutateMana(10.toShort()) == false)
+ assert(monster.mana == 150.toShort())
+
+ // Accessing a vector of sorted by the key tables
+ assert(monster.testarrayoftables(0)!!.name == "Barney")
+ assert(monster.testarrayoftables(1)!!.name == "Frodo")
+ assert(monster.testarrayoftables(2)!!.name == "Wilma")
+
+ // Example of searching for a table by the key
+ assert(monster.testarrayoftablesByKey("Frodo")!!.name == "Frodo")
+ assert(monster.testarrayoftablesByKey("Barney")!!.name == "Barney")
+ assert(monster.testarrayoftablesByKey("Wilma")!!.name == "Wilma")
+
+ // testType is an existing field and mutating it should succeed
+ assert(monster.testType == Any_.Monster)
+ assert(monster.mutateTestType(Any_.NONE) == true)
+ assert(monster.testType == Any_.NONE)
+ assert(monster.mutateTestType(Any_.Monster) == true)
+ assert(monster.testType == Any_.Monster)
+
+ //mutate the inventory vector
+ assert(monster.mutateInventory(0, 1u) == true)
+ assert(monster.mutateInventory(1, 2u) == true)
+ assert(monster.mutateInventory(2, 3u) == true)
+ assert(monster.mutateInventory(3, 4u) == true)
+ assert(monster.mutateInventory(4, 5u) == true)
+
+ for (i in 0 until monster.inventoryLength) {
+ assert(monster.inventory(i) == (i.toUByte() + 1u).toUByte())
+ }
+
+ //reverse mutation
+ assert(monster.mutateInventory(0, 0u) == true)
+ assert(monster.mutateInventory(1, 1u) == true)
+ assert(monster.mutateInventory(2, 2u) == true)
+ assert(monster.mutateInventory(3, 3u) == true)
+ assert(monster.mutateInventory(4, 4u) == true)
+
+ // get a struct field and edit one of its fields
+ val pos = monster.pos!!
+ assert(pos.x == 1.0f)
+ pos.mutateX(55.0f)
+ assert(pos.x == 55.0f)
+ pos.mutateX(1.0f)
+ assert(pos.x == 1.0f)
+ }
+
+ fun TestVectorOfUnions() {
+ val fbb = FlatBufferBuilder()
+
+ val swordAttackDamage = 1
+
+ val characterVector = intArrayOf(Attacker.createAttacker(fbb, swordAttackDamage))
+
+ val characterTypeVector = ubyteArrayOf(Character_.MuLan)
+
+ Movie.finishMovieBuffer(
+ fbb,
+ Movie.createMovie(
+ fbb,
+ 0u,
+ 0,
+ Movie.createCharactersTypeVector(fbb, characterTypeVector),
+ Movie.createCharactersVector(fbb, characterVector)
+ )
+ )
+
+ val movie = Movie.getRootAsMovie(fbb.dataBuffer())
+
+ assert(movie.charactersTypeLength == characterTypeVector.size)
+ assert(movie.charactersLength == characterVector.size)
+
+ assert(movie.charactersType(0) == characterTypeVector[0])
+
+ assert((movie.characters(Attacker(), 0) as Attacker).swordAttackDamage == swordAttackDamage)
+ }
+}
+ }
diff --git a/tests/KotlinTest.sh b/tests/KotlinTest.sh
new file mode 100755
index 00000000..709e68c6
--- /dev/null
+++ b/tests/KotlinTest.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# Copyright 2014 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+echo Compile then run the Kotlin test.
+
+testdir=$(dirname $0)
+targetdir="${testdir}/kotlin"
+
+if [[ -e "${targetdir}" ]]; then
+ echo "cleaning target"
+ rm -rf "${targetdir}"
+fi
+
+mkdir -v "${targetdir}"
+
+if ! find "${testdir}/../java" -type f -name "*.class" -delete; then
+ echo "failed to clean .class files from java directory" >&2
+ exit 1
+fi
+
+all_kt_files=`find . -name "*.kt" -print`
+
+# Compile java FlatBuffer library
+javac ${testdir}/../java/com/google/flatbuffers/*.java -d $targetdir
+# Compile Kotlin files
+kotlinc $all_kt_files -classpath $targetdir -include-runtime -d $targetdir
+# Make jar
+jar cvf ${testdir}/kotlin_test.jar -C $targetdir . > /dev/null
+# Run test
+kotlin -cp ${testdir}/kotlin_test.jar KotlinTest
+# clean up
+rm -rf $targetdir
+rm ${testdir}/kotlin_test.jar
diff --git a/tests/LuaTest.sh b/tests/LuaTest.sh
new file mode 100755
index 00000000..eb70e8a1
--- /dev/null
+++ b/tests/LuaTest.sh
@@ -0,0 +1,22 @@
+#!/bin/bash -eu
+#
+# Copyright 2019 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+pushd "$(dirname $0)" >/dev/null
+test_dir="$(pwd)"
+
+${test_dir}/../flatc --lua -I include_test monster_test.fbs
+
+lua5.3 luatest.lua
diff --git a/tests/MyGame/Example/Ability.cs b/tests/MyGame/Example/Ability.cs
index 17dce4ef..bd49ccd9 100644
--- a/tests/MyGame/Example/Ability.cs
+++ b/tests/MyGame/Example/Ability.cs
@@ -6,13 +6,14 @@ namespace MyGame.Example
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Ability : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
public Ability __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public uint Id { get { return __p.bb.GetUint(__p.bb_pos + 0); } }
@@ -20,13 +21,42 @@ public struct Ability : IFlatbufferObject
public uint Distance { get { return __p.bb.GetUint(__p.bb_pos + 4); } }
public void MutateDistance(uint distance) { __p.bb.PutUint(__p.bb_pos + 4, distance); }
- public static Offset<Ability> CreateAbility(FlatBufferBuilder builder, uint Id, uint Distance) {
+ public static Offset<MyGame.Example.Ability> CreateAbility(FlatBufferBuilder builder, uint Id, uint Distance) {
builder.Prep(4, 8);
builder.PutUint(Distance);
builder.PutUint(Id);
- return new Offset<Ability>(builder.Offset);
+ return new Offset<MyGame.Example.Ability>(builder.Offset);
+ }
+ public AbilityT UnPack() {
+ var _o = new AbilityT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(AbilityT _o) {
+ _o.Id = this.Id;
+ _o.Distance = this.Distance;
+ }
+ public static Offset<MyGame.Example.Ability> Pack(FlatBufferBuilder builder, AbilityT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.Ability>);
+ return CreateAbility(
+ builder,
+ _o.Id,
+ _o.Distance);
}
};
+public class AbilityT
+{
+ [Newtonsoft.Json.JsonProperty("id")]
+ public uint Id { get; set; }
+ [Newtonsoft.Json.JsonProperty("distance")]
+ public uint Distance { get; set; }
+
+ public AbilityT() {
+ this.Id = 0;
+ this.Distance = 0;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Ability.go b/tests/MyGame/Example/Ability.go
index a56b4452..9852a755 100644
--- a/tests/MyGame/Example/Ability.go
+++ b/tests/MyGame/Example/Ability.go
@@ -6,6 +6,27 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type AbilityT struct {
+ Id uint32
+ Distance uint32
+}
+
+func (t *AbilityT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ return CreateAbility(builder, t.Id, t.Distance)
+}
+func (rcv *Ability) UnPackTo(t *AbilityT) {
+ t.Id = rcv.Id()
+ t.Distance = rcv.Distance()
+}
+
+func (rcv *Ability) UnPack() *AbilityT {
+ if rcv == nil { return nil }
+ t := &AbilityT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type Ability struct {
_tab flatbuffers.Struct
}
diff --git a/tests/MyGame/Example/Ability.java b/tests/MyGame/Example/Ability.java
index 5e1c90e0..df5fe714 100644
--- a/tests/MyGame/Example/Ability.java
+++ b/tests/MyGame/Example/Ability.java
@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Ability extends Struct {
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Ability __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public long id() { return (long)bb.getInt(bb_pos + 0) & 0xFFFFFFFFL; }
@@ -23,5 +23,12 @@ public final class Ability extends Struct {
builder.putInt((int)id);
return builder.offset();
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Ability get(int j) { return get(new Ability(), j); }
+ public Ability get(Ability obj, int j) { return obj.__assign(__element(j), bb); }
+ }
}
diff --git a/tests/MyGame/Example/Ability.kt b/tests/MyGame/Example/Ability.kt
new file mode 100644
index 00000000..1b644d6e
--- /dev/null
+++ b/tests/MyGame/Example/Ability.kt
@@ -0,0 +1,32 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Ability : Struct() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Ability {
+ __init(_i, _bb)
+ return this
+ }
+ val id : UInt get() = bb.getInt(bb_pos + 0).toUInt()
+ fun mutateId(id: UInt) : ByteBuffer = bb.putInt(bb_pos + 0, id.toInt())
+ val distance : UInt get() = bb.getInt(bb_pos + 4).toUInt()
+ fun mutateDistance(distance: UInt) : ByteBuffer = bb.putInt(bb_pos + 4, distance.toInt())
+ companion object {
+ fun createAbility(builder: FlatBufferBuilder, id: UInt, distance: UInt) : Int {
+ builder.prep(4, 8)
+ builder.putInt(distance.toInt())
+ builder.putInt(id.toInt())
+ return builder.offset()
+ }
+ }
+}
diff --git a/tests/MyGame/Example/Ability.py b/tests/MyGame/Example/Ability.py
index 3c4776ef..2cc916bd 100644
--- a/tests/MyGame/Example/Ability.py
+++ b/tests/MyGame/Example/Ability.py
@@ -3,6 +3,8 @@
# namespace: Example
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class Ability(object):
__slots__ = ['_tab']
@@ -21,3 +23,34 @@ def CreateAbility(builder, id, distance):
builder.PrependUint32(distance)
builder.PrependUint32(id)
return builder.Offset()
+
+
+class AbilityT(object):
+
+ # AbilityT
+ def __init__(self):
+ self.id = 0 # type: int
+ self.distance = 0 # type: int
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ ability = Ability()
+ ability.Init(buf, pos)
+ return cls.InitFromObj(ability)
+
+ @classmethod
+ def InitFromObj(cls, ability):
+ x = AbilityT()
+ x._UnPack(ability)
+ return x
+
+ # AbilityT
+ def _UnPack(self, ability):
+ if ability is None:
+ return
+ self.id = ability.Id()
+ self.distance = ability.Distance()
+
+ # AbilityT
+ def Pack(self, builder):
+ return CreateAbility(builder, self.id, self.distance)
diff --git a/tests/MyGame/Example/Any.cs b/tests/MyGame/Example/Any.cs
index 8393853b..edf98ef5 100644
--- a/tests/MyGame/Example/Any.cs
+++ b/tests/MyGame/Example/Any.cs
@@ -5,13 +5,81 @@
namespace MyGame.Example
{
+[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Any : byte
{
- NONE = 0,
- Monster = 1,
- TestSimpleTableWithEnum = 2,
- MyGame_Example2_Monster = 3,
+ NONE = 0,
+ Monster = 1,
+ TestSimpleTableWithEnum = 2,
+ MyGame_Example2_Monster = 3,
};
+public class AnyUnion {
+ public Any Type { get; set; }
+ public object Value { get; set; }
+
+ public AnyUnion() {
+ this.Type = Any.NONE;
+ this.Value = null;
+ }
+
+ public T As<T>() where T : class { return this.Value as T; }
+ public MyGame.Example.MonsterT AsMonster() { return this.As<MyGame.Example.MonsterT>(); }
+ internal MyGame.Example.TestSimpleTableWithEnumT AsTestSimpleTableWithEnum() { return this.As<MyGame.Example.TestSimpleTableWithEnumT>(); }
+ public MyGame.Example2.MonsterT AsMyGame_Example2_Monster() { return this.As<MyGame.Example2.MonsterT>(); }
+
+ public static int Pack(FlatBuffers.FlatBufferBuilder builder, AnyUnion _o) {
+ switch (_o.Type) {
+ default: return 0;
+ case Any.Monster: return MyGame.Example.Monster.Pack(builder, _o.AsMonster()).Value;
+ case Any.TestSimpleTableWithEnum: return MyGame.Example.TestSimpleTableWithEnum.Pack(builder, _o.AsTestSimpleTableWithEnum()).Value;
+ case Any.MyGame_Example2_Monster: return MyGame.Example2.Monster.Pack(builder, _o.AsMyGame_Example2_Monster()).Value;
+ }
+ }
+}
+
+public class AnyUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
+ public override bool CanConvert(System.Type objectType) {
+ return objectType == typeof(AnyUnion) || objectType == typeof(System.Collections.Generic.List<AnyUnion>);
+ }
+ public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) {
+ var _olist = value as System.Collections.Generic.List<AnyUnion>;
+ if (_olist != null) {
+ writer.WriteStartArray();
+ foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); }
+ writer.WriteEndArray();
+ } else {
+ this.WriteJson(writer, value as AnyUnion, serializer);
+ }
+ }
+ public void WriteJson(Newtonsoft.Json.JsonWriter writer, AnyUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
+ if (_o == null) return;
+ serializer.Serialize(writer, _o.Value);
+ }
+ public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) {
+ var _olist = existingValue as System.Collections.Generic.List<AnyUnion>;
+ if (_olist != null) {
+ for (var _j = 0; _j < _olist.Count; ++_j) {
+ reader.Read();
+ _olist[_j] = this.ReadJson(reader, _olist[_j], serializer);
+ }
+ reader.Read();
+ return _olist;
+ } else {
+ return this.ReadJson(reader, existingValue as AnyUnion, serializer);
+ }
+ }
+ public AnyUnion ReadJson(Newtonsoft.Json.JsonReader reader, AnyUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
+ if (_o == null) return null;
+ switch (_o.Type) {
+ default: break;
+ case Any.Monster: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break;
+ case Any.TestSimpleTableWithEnum: _o.Value = serializer.Deserialize<MyGame.Example.TestSimpleTableWithEnumT>(reader); break;
+ case Any.MyGame_Example2_Monster: _o.Value = serializer.Deserialize<MyGame.Example2.MonsterT>(reader); break;
+ }
+ return _o;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Any.go b/tests/MyGame/Example/Any.go
index 39b89a79..14b66b5b 100644
--- a/tests/MyGame/Example/Any.go
+++ b/tests/MyGame/Example/Any.go
@@ -2,18 +2,75 @@
package Example
-type Any = byte
+import (
+ "strconv"
+
+ flatbuffers "github.com/google/flatbuffers/go"
+
+ MyGame__Example2 "MyGame/Example2"
+)
+
+type Any byte
+
const (
- AnyNONE Any = 0
- AnyMonster Any = 1
+ AnyNONE Any = 0
+ AnyMonster Any = 1
AnyTestSimpleTableWithEnum Any = 2
AnyMyGame_Example2_Monster Any = 3
)
var EnumNamesAny = map[Any]string{
- AnyNONE:"NONE",
- AnyMonster:"Monster",
- AnyTestSimpleTableWithEnum:"TestSimpleTableWithEnum",
- AnyMyGame_Example2_Monster:"MyGame_Example2_Monster",
+ AnyNONE: "NONE",
+ AnyMonster: "Monster",
+ AnyTestSimpleTableWithEnum: "TestSimpleTableWithEnum",
+ AnyMyGame_Example2_Monster: "MyGame_Example2_Monster",
+}
+
+var EnumValuesAny = map[string]Any{
+ "NONE": AnyNONE,
+ "Monster": AnyMonster,
+ "TestSimpleTableWithEnum": AnyTestSimpleTableWithEnum,
+ "MyGame_Example2_Monster": AnyMyGame_Example2_Monster,
}
+func (v Any) String() string {
+ if s, ok := EnumNamesAny[v]; ok {
+ return s
+ }
+ return "Any(" + strconv.FormatInt(int64(v), 10) + ")"
+}
+
+type AnyT struct {
+ Type Any
+ Value interface{}
+}
+
+func (t *AnyT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil {
+ return 0
+ }
+ switch t.Type {
+ case AnyMonster:
+ return t.Value.(*MonsterT).Pack(builder)
+ case AnyTestSimpleTableWithEnum:
+ return t.Value.(*TestSimpleTableWithEnumT).Pack(builder)
+ case AnyMyGame_Example2_Monster:
+ return t.Value.(*MyGame__Example2.MonsterT).Pack(builder)
+ }
+ return 0
+}
+
+func (rcv Any) UnPack(table flatbuffers.Table) *AnyT {
+ switch rcv {
+ case AnyMonster:
+ x := Monster{_tab: table}
+ return &AnyT{ Type: AnyMonster, Value: x.UnPack() }
+ case AnyTestSimpleTableWithEnum:
+ x := TestSimpleTableWithEnum{_tab: table}
+ return &AnyT{ Type: AnyTestSimpleTableWithEnum, Value: x.UnPack() }
+ case AnyMyGame_Example2_Monster:
+ x := Monster{_tab: table}
+ return &AnyT{ Type: AnyMyGame_Example2_Monster, Value: x.UnPack() }
+ }
+ return nil
+}
diff --git a/tests/MyGame/Example/Any.kt b/tests/MyGame/Example/Any.kt
new file mode 100644
index 00000000..f1a4dfed
--- /dev/null
+++ b/tests/MyGame/Example/Any.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Any_ private constructor() {
+ companion object {
+ const val NONE: UByte = 0u
+ const val Monster: UByte = 1u
+ const val TestSimpleTableWithEnum: UByte = 2u
+ const val MyGameExample2Monster: UByte = 3u
+ val names : Array<String> = arrayOf("NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster")
+ fun name(e: Int) : String = names[e]
+ }
+}
diff --git a/tests/MyGame/Example/Any.py b/tests/MyGame/Example/Any.py
index f1b8d519..b10d35df 100644
--- a/tests/MyGame/Example/Any.py
+++ b/tests/MyGame/Example/Any.py
@@ -8,3 +8,18 @@ class Any(object):
TestSimpleTableWithEnum = 2
MyGame_Example2_Monster = 3
+
+def AnyCreator(unionType, table):
+ from flatbuffers.table import Table
+ if not isinstance(table, Table):
+ return None
+ if unionType == Any().Monster:
+ import MyGame.Example.Monster
+ return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+ if unionType == Any().TestSimpleTableWithEnum:
+ import MyGame.Example.TestSimpleTableWithEnum
+ return MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
+ if unionType == Any().MyGame_Example2_Monster:
+ import MyGame.Example2.Monster
+ return MyGame.Example2.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+ return None
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.cs b/tests/MyGame/Example/AnyAmbiguousAliases.cs
index e841518b..07deadc2 100644
--- a/tests/MyGame/Example/AnyAmbiguousAliases.cs
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.cs
@@ -5,13 +5,81 @@
namespace MyGame.Example
{
+[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum AnyAmbiguousAliases : byte
{
- NONE = 0,
- M1 = 1,
- M2 = 2,
- M3 = 3,
+ NONE = 0,
+ M1 = 1,
+ M2 = 2,
+ M3 = 3,
};
+public class AnyAmbiguousAliasesUnion {
+ public AnyAmbiguousAliases Type { get; set; }
+ public object Value { get; set; }
+
+ public AnyAmbiguousAliasesUnion() {
+ this.Type = AnyAmbiguousAliases.NONE;
+ this.Value = null;
+ }
+
+ public T As<T>() where T : class { return this.Value as T; }
+ public MyGame.Example.MonsterT AsM1() { return this.As<MyGame.Example.MonsterT>(); }
+ public MyGame.Example.MonsterT AsM2() { return this.As<MyGame.Example.MonsterT>(); }
+ public MyGame.Example.MonsterT AsM3() { return this.As<MyGame.Example.MonsterT>(); }
+
+ public static int Pack(FlatBuffers.FlatBufferBuilder builder, AnyAmbiguousAliasesUnion _o) {
+ switch (_o.Type) {
+ default: return 0;
+ case AnyAmbiguousAliases.M1: return MyGame.Example.Monster.Pack(builder, _o.AsM1()).Value;
+ case AnyAmbiguousAliases.M2: return MyGame.Example.Monster.Pack(builder, _o.AsM2()).Value;
+ case AnyAmbiguousAliases.M3: return MyGame.Example.Monster.Pack(builder, _o.AsM3()).Value;
+ }
+ }
+}
+
+public class AnyAmbiguousAliasesUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
+ public override bool CanConvert(System.Type objectType) {
+ return objectType == typeof(AnyAmbiguousAliasesUnion) || objectType == typeof(System.Collections.Generic.List<AnyAmbiguousAliasesUnion>);
+ }
+ public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) {
+ var _olist = value as System.Collections.Generic.List<AnyAmbiguousAliasesUnion>;
+ if (_olist != null) {
+ writer.WriteStartArray();
+ foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); }
+ writer.WriteEndArray();
+ } else {
+ this.WriteJson(writer, value as AnyAmbiguousAliasesUnion, serializer);
+ }
+ }
+ public void WriteJson(Newtonsoft.Json.JsonWriter writer, AnyAmbiguousAliasesUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
+ if (_o == null) return;
+ serializer.Serialize(writer, _o.Value);
+ }
+ public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) {
+ var _olist = existingValue as System.Collections.Generic.List<AnyAmbiguousAliasesUnion>;
+ if (_olist != null) {
+ for (var _j = 0; _j < _olist.Count; ++_j) {
+ reader.Read();
+ _olist[_j] = this.ReadJson(reader, _olist[_j], serializer);
+ }
+ reader.Read();
+ return _olist;
+ } else {
+ return this.ReadJson(reader, existingValue as AnyAmbiguousAliasesUnion, serializer);
+ }
+ }
+ public AnyAmbiguousAliasesUnion ReadJson(Newtonsoft.Json.JsonReader reader, AnyAmbiguousAliasesUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
+ if (_o == null) return null;
+ switch (_o.Type) {
+ default: break;
+ case AnyAmbiguousAliases.M1: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break;
+ case AnyAmbiguousAliases.M2: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break;
+ case AnyAmbiguousAliases.M3: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break;
+ }
+ return _o;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.go b/tests/MyGame/Example/AnyAmbiguousAliases.go
index b5eacde4..8a088dbb 100644
--- a/tests/MyGame/Example/AnyAmbiguousAliases.go
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.go
@@ -2,18 +2,73 @@
package Example
-type AnyAmbiguousAliases = byte
+import (
+ "strconv"
+
+ flatbuffers "github.com/google/flatbuffers/go"
+)
+
+type AnyAmbiguousAliases byte
+
const (
AnyAmbiguousAliasesNONE AnyAmbiguousAliases = 0
- AnyAmbiguousAliasesM1 AnyAmbiguousAliases = 1
- AnyAmbiguousAliasesM2 AnyAmbiguousAliases = 2
- AnyAmbiguousAliasesM3 AnyAmbiguousAliases = 3
+ AnyAmbiguousAliasesM1 AnyAmbiguousAliases = 1
+ AnyAmbiguousAliasesM2 AnyAmbiguousAliases = 2
+ AnyAmbiguousAliasesM3 AnyAmbiguousAliases = 3
)
var EnumNamesAnyAmbiguousAliases = map[AnyAmbiguousAliases]string{
- AnyAmbiguousAliasesNONE:"NONE",
- AnyAmbiguousAliasesM1:"M1",
- AnyAmbiguousAliasesM2:"M2",
- AnyAmbiguousAliasesM3:"M3",
+ AnyAmbiguousAliasesNONE: "NONE",
+ AnyAmbiguousAliasesM1: "M1",
+ AnyAmbiguousAliasesM2: "M2",
+ AnyAmbiguousAliasesM3: "M3",
}
+var EnumValuesAnyAmbiguousAliases = map[string]AnyAmbiguousAliases{
+ "NONE": AnyAmbiguousAliasesNONE,
+ "M1": AnyAmbiguousAliasesM1,
+ "M2": AnyAmbiguousAliasesM2,
+ "M3": AnyAmbiguousAliasesM3,
+}
+
+func (v AnyAmbiguousAliases) String() string {
+ if s, ok := EnumNamesAnyAmbiguousAliases[v]; ok {
+ return s
+ }
+ return "AnyAmbiguousAliases(" + strconv.FormatInt(int64(v), 10) + ")"
+}
+
+type AnyAmbiguousAliasesT struct {
+ Type AnyAmbiguousAliases
+ Value interface{}
+}
+
+func (t *AnyAmbiguousAliasesT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil {
+ return 0
+ }
+ switch t.Type {
+ case AnyAmbiguousAliasesM1:
+ return t.Value.(*MonsterT).Pack(builder)
+ case AnyAmbiguousAliasesM2:
+ return t.Value.(*MonsterT).Pack(builder)
+ case AnyAmbiguousAliasesM3:
+ return t.Value.(*MonsterT).Pack(builder)
+ }
+ return 0
+}
+
+func (rcv AnyAmbiguousAliases) UnPack(table flatbuffers.Table) *AnyAmbiguousAliasesT {
+ switch rcv {
+ case AnyAmbiguousAliasesM1:
+ x := Monster{_tab: table}
+ return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM1, Value: x.UnPack() }
+ case AnyAmbiguousAliasesM2:
+ x := Monster{_tab: table}
+ return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM2, Value: x.UnPack() }
+ case AnyAmbiguousAliasesM3:
+ x := Monster{_tab: table}
+ return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM3, Value: x.UnPack() }
+ }
+ return nil
+}
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.kt b/tests/MyGame/Example/AnyAmbiguousAliases.kt
new file mode 100644
index 00000000..cee13c51
--- /dev/null
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class AnyAmbiguousAliases private constructor() {
+ companion object {
+ const val NONE: UByte = 0u
+ const val M1: UByte = 1u
+ const val M2: UByte = 2u
+ const val M3: UByte = 3u
+ val names : Array<String> = arrayOf("NONE", "M1", "M2", "M3")
+ fun name(e: Int) : String = names[e]
+ }
+}
diff --git a/tests/MyGame/Example/AnyAmbiguousAliases.py b/tests/MyGame/Example/AnyAmbiguousAliases.py
index de6e9d0e..3fb4830f 100644
--- a/tests/MyGame/Example/AnyAmbiguousAliases.py
+++ b/tests/MyGame/Example/AnyAmbiguousAliases.py
@@ -8,3 +8,18 @@ class AnyAmbiguousAliases(object):
M2 = 2
M3 = 3
+
+def AnyAmbiguousAliasesCreator(unionType, table):
+ from flatbuffers.table import Table
+ if not isinstance(table, Table):
+ return None
+ if unionType == AnyAmbiguousAliases().M1:
+ import MyGame.Example.Monster
+ return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+ if unionType == AnyAmbiguousAliases().M2:
+ import MyGame.Example.Monster
+ return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+ if unionType == AnyAmbiguousAliases().M3:
+ import MyGame.Example.Monster
+ return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+ return None
diff --git a/tests/MyGame/Example/AnyUniqueAliases.cs b/tests/MyGame/Example/AnyUniqueAliases.cs
index aa508e3e..35949528 100644
--- a/tests/MyGame/Example/AnyUniqueAliases.cs
+++ b/tests/MyGame/Example/AnyUniqueAliases.cs
@@ -5,13 +5,81 @@
namespace MyGame.Example
{
+[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum AnyUniqueAliases : byte
{
- NONE = 0,
- M = 1,
- T = 2,
- M2 = 3,
+ NONE = 0,
+ M = 1,
+ TS = 2,
+ M2 = 3,
};
+public class AnyUniqueAliasesUnion {
+ public AnyUniqueAliases Type { get; set; }
+ public object Value { get; set; }
+
+ public AnyUniqueAliasesUnion() {
+ this.Type = AnyUniqueAliases.NONE;
+ this.Value = null;
+ }
+
+ public T As<T>() where T : class { return this.Value as T; }
+ public MyGame.Example.MonsterT AsM() { return this.As<MyGame.Example.MonsterT>(); }
+ internal MyGame.Example.TestSimpleTableWithEnumT AsTS() { return this.As<MyGame.Example.TestSimpleTableWithEnumT>(); }
+ public MyGame.Example2.MonsterT AsM2() { return this.As<MyGame.Example2.MonsterT>(); }
+
+ public static int Pack(FlatBuffers.FlatBufferBuilder builder, AnyUniqueAliasesUnion _o) {
+ switch (_o.Type) {
+ default: return 0;
+ case AnyUniqueAliases.M: return MyGame.Example.Monster.Pack(builder, _o.AsM()).Value;
+ case AnyUniqueAliases.TS: return MyGame.Example.TestSimpleTableWithEnum.Pack(builder, _o.AsTS()).Value;
+ case AnyUniqueAliases.M2: return MyGame.Example2.Monster.Pack(builder, _o.AsM2()).Value;
+ }
+ }
+}
+
+public class AnyUniqueAliasesUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
+ public override bool CanConvert(System.Type objectType) {
+ return objectType == typeof(AnyUniqueAliasesUnion) || objectType == typeof(System.Collections.Generic.List<AnyUniqueAliasesUnion>);
+ }
+ public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) {
+ var _olist = value as System.Collections.Generic.List<AnyUniqueAliasesUnion>;
+ if (_olist != null) {
+ writer.WriteStartArray();
+ foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); }
+ writer.WriteEndArray();
+ } else {
+ this.WriteJson(writer, value as AnyUniqueAliasesUnion, serializer);
+ }
+ }
+ public void WriteJson(Newtonsoft.Json.JsonWriter writer, AnyUniqueAliasesUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
+ if (_o == null) return;
+ serializer.Serialize(writer, _o.Value);
+ }
+ public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) {
+ var _olist = existingValue as System.Collections.Generic.List<AnyUniqueAliasesUnion>;
+ if (_olist != null) {
+ for (var _j = 0; _j < _olist.Count; ++_j) {
+ reader.Read();
+ _olist[_j] = this.ReadJson(reader, _olist[_j], serializer);
+ }
+ reader.Read();
+ return _olist;
+ } else {
+ return this.ReadJson(reader, existingValue as AnyUniqueAliasesUnion, serializer);
+ }
+ }
+ public AnyUniqueAliasesUnion ReadJson(Newtonsoft.Json.JsonReader reader, AnyUniqueAliasesUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
+ if (_o == null) return null;
+ switch (_o.Type) {
+ default: break;
+ case AnyUniqueAliases.M: _o.Value = serializer.Deserialize<MyGame.Example.MonsterT>(reader); break;
+ case AnyUniqueAliases.TS: _o.Value = serializer.Deserialize<MyGame.Example.TestSimpleTableWithEnumT>(reader); break;
+ case AnyUniqueAliases.M2: _o.Value = serializer.Deserialize<MyGame.Example2.MonsterT>(reader); break;
+ }
+ return _o;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.go b/tests/MyGame/Example/AnyUniqueAliases.go
index 14a2694a..2a52ebec 100644
--- a/tests/MyGame/Example/AnyUniqueAliases.go
+++ b/tests/MyGame/Example/AnyUniqueAliases.go
@@ -2,18 +2,75 @@
package Example
-type AnyUniqueAliases = byte
+import (
+ "strconv"
+
+ flatbuffers "github.com/google/flatbuffers/go"
+
+ MyGame__Example2 "MyGame/Example2"
+)
+
+type AnyUniqueAliases byte
+
const (
AnyUniqueAliasesNONE AnyUniqueAliases = 0
- AnyUniqueAliasesM AnyUniqueAliases = 1
- AnyUniqueAliasesT AnyUniqueAliases = 2
- AnyUniqueAliasesM2 AnyUniqueAliases = 3
+ AnyUniqueAliasesM AnyUniqueAliases = 1
+ AnyUniqueAliasesTS AnyUniqueAliases = 2
+ AnyUniqueAliasesM2 AnyUniqueAliases = 3
)
var EnumNamesAnyUniqueAliases = map[AnyUniqueAliases]string{
- AnyUniqueAliasesNONE:"NONE",
- AnyUniqueAliasesM:"M",
- AnyUniqueAliasesT:"T",
- AnyUniqueAliasesM2:"M2",
+ AnyUniqueAliasesNONE: "NONE",
+ AnyUniqueAliasesM: "M",
+ AnyUniqueAliasesTS: "TS",
+ AnyUniqueAliasesM2: "M2",
+}
+
+var EnumValuesAnyUniqueAliases = map[string]AnyUniqueAliases{
+ "NONE": AnyUniqueAliasesNONE,
+ "M": AnyUniqueAliasesM,
+ "TS": AnyUniqueAliasesTS,
+ "M2": AnyUniqueAliasesM2,
}
+func (v AnyUniqueAliases) String() string {
+ if s, ok := EnumNamesAnyUniqueAliases[v]; ok {
+ return s
+ }
+ return "AnyUniqueAliases(" + strconv.FormatInt(int64(v), 10) + ")"
+}
+
+type AnyUniqueAliasesT struct {
+ Type AnyUniqueAliases
+ Value interface{}
+}
+
+func (t *AnyUniqueAliasesT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil {
+ return 0
+ }
+ switch t.Type {
+ case AnyUniqueAliasesM:
+ return t.Value.(*MonsterT).Pack(builder)
+ case AnyUniqueAliasesTS:
+ return t.Value.(*TestSimpleTableWithEnumT).Pack(builder)
+ case AnyUniqueAliasesM2:
+ return t.Value.(*MyGame__Example2.MonsterT).Pack(builder)
+ }
+ return 0
+}
+
+func (rcv AnyUniqueAliases) UnPack(table flatbuffers.Table) *AnyUniqueAliasesT {
+ switch rcv {
+ case AnyUniqueAliasesM:
+ x := Monster{_tab: table}
+ return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesM, Value: x.UnPack() }
+ case AnyUniqueAliasesTS:
+ x := TestSimpleTableWithEnum{_tab: table}
+ return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesTS, Value: x.UnPack() }
+ case AnyUniqueAliasesM2:
+ x := Monster{_tab: table}
+ return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesM2, Value: x.UnPack() }
+ }
+ return nil
+}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.java b/tests/MyGame/Example/AnyUniqueAliases.java
index 8c1633a6..1f329450 100644
--- a/tests/MyGame/Example/AnyUniqueAliases.java
+++ b/tests/MyGame/Example/AnyUniqueAliases.java
@@ -6,10 +6,10 @@ public final class AnyUniqueAliases {
private AnyUniqueAliases() { }
public static final byte NONE = 0;
public static final byte M = 1;
- public static final byte T = 2;
+ public static final byte TS = 2;
public static final byte M2 = 3;
- public static final String[] names = { "NONE", "M", "T", "M2", };
+ public static final String[] names = { "NONE", "M", "TS", "M2", };
public static String name(int e) { return names[e]; }
}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.kt b/tests/MyGame/Example/AnyUniqueAliases.kt
new file mode 100644
index 00000000..1902d5d6
--- /dev/null
+++ b/tests/MyGame/Example/AnyUniqueAliases.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class AnyUniqueAliases private constructor() {
+ companion object {
+ const val NONE: UByte = 0u
+ const val M: UByte = 1u
+ const val TS: UByte = 2u
+ const val M2: UByte = 3u
+ val names : Array<String> = arrayOf("NONE", "M", "TS", "M2")
+ fun name(e: Int) : String = names[e]
+ }
+}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.lua b/tests/MyGame/Example/AnyUniqueAliases.lua
index b4ffc747..9bfeb800 100644
--- a/tests/MyGame/Example/AnyUniqueAliases.lua
+++ b/tests/MyGame/Example/AnyUniqueAliases.lua
@@ -5,7 +5,7 @@
local AnyUniqueAliases = {
NONE = 0,
M = 1,
- T = 2,
+ TS = 2,
M2 = 3,
}
diff --git a/tests/MyGame/Example/AnyUniqueAliases.php b/tests/MyGame/Example/AnyUniqueAliases.php
index fe551cce..830d8b52 100644
--- a/tests/MyGame/Example/AnyUniqueAliases.php
+++ b/tests/MyGame/Example/AnyUniqueAliases.php
@@ -7,13 +7,13 @@ class AnyUniqueAliases
{
const NONE = 0;
const M = 1;
- const T = 2;
+ const TS = 2;
const M2 = 3;
private static $names = array(
AnyUniqueAliases::NONE=>"NONE",
AnyUniqueAliases::M=>"M",
- AnyUniqueAliases::T=>"T",
+ AnyUniqueAliases::TS=>"TS",
AnyUniqueAliases::M2=>"M2",
);
diff --git a/tests/MyGame/Example/AnyUniqueAliases.py b/tests/MyGame/Example/AnyUniqueAliases.py
index 0de89d9b..cf89fc29 100644
--- a/tests/MyGame/Example/AnyUniqueAliases.py
+++ b/tests/MyGame/Example/AnyUniqueAliases.py
@@ -5,6 +5,21 @@
class AnyUniqueAliases(object):
NONE = 0
M = 1
- T = 2
+ TS = 2
M2 = 3
+
+def AnyUniqueAliasesCreator(unionType, table):
+ from flatbuffers.table import Table
+ if not isinstance(table, Table):
+ return None
+ if unionType == AnyUniqueAliases().M:
+ import MyGame.Example.Monster
+ return MyGame.Example.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+ if unionType == AnyUniqueAliases().TS:
+ import MyGame.Example.TestSimpleTableWithEnum
+ return MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT.InitFromBuf(table.Bytes, table.Pos)
+ if unionType == AnyUniqueAliases().M2:
+ import MyGame.Example2.Monster
+ return MyGame.Example2.Monster.MonsterT.InitFromBuf(table.Bytes, table.Pos)
+ return None
diff --git a/tests/MyGame/Example/ArrayStruct.cs b/tests/MyGame/Example/ArrayStruct.cs
new file mode 100644
index 00000000..41c088db
--- /dev/null
+++ b/tests/MyGame/Example/ArrayStruct.cs
@@ -0,0 +1,128 @@
+// <auto-generated>
+// automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::System.Collections.Generic;
+using global::FlatBuffers;
+
+public struct ArrayStruct : IFlatbufferObject
+{
+ private Struct __p;
+ public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+ public ArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+ public float A { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
+ public void MutateA(float a) { __p.bb.PutFloat(__p.bb_pos + 0, a); }
+ public int B(int j) { return __p.bb.GetInt(__p.bb_pos + 4 + j * 4); }
+ public void MutateB(int j, int b) { __p.bb.PutInt(__p.bb_pos + 4 + j * 4, b); }
+ public sbyte C { get { return __p.bb.GetSbyte(__p.bb_pos + 64); } }
+ public void MutateC(sbyte c) { __p.bb.PutSbyte(__p.bb_pos + 64, c); }
+ public MyGame.Example.NestedStruct D(int j) { return (new MyGame.Example.NestedStruct()).__assign(__p.bb_pos + 72 + j * 32, __p.bb); }
+ public int E { get { return __p.bb.GetInt(__p.bb_pos + 136); } }
+ public void MutateE(int e) { __p.bb.PutInt(__p.bb_pos + 136, e); }
+ public long F(int j) { return __p.bb.GetLong(__p.bb_pos + 144 + j * 8); }
+ public void MutateF(int j, long f) { __p.bb.PutLong(__p.bb_pos + 144 + j * 8, f); }
+
+ public static Offset<MyGame.Example.ArrayStruct> CreateArrayStruct(FlatBufferBuilder builder, float A, int[] B, sbyte C, int[,] d_A, MyGame.Example.TestEnum[] d_B, MyGame.Example.TestEnum[,] d_C, long[,] d_D, int E, long[] F) {
+ builder.Prep(8, 160);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.PutLong(F[_idx0-1]);
+ }
+ builder.Pad(4);
+ builder.PutInt(E);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.Prep(8, 32);
+ for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+ builder.PutLong(d_D[_idx0-1,_idx1-1]);
+ }
+ builder.Pad(5);
+ for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+ builder.PutSbyte((sbyte)d_C[_idx0-1,_idx1-1]);
+ }
+ builder.PutSbyte((sbyte)d_B[_idx0-1]);
+ for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+ builder.PutInt(d_A[_idx0-1,_idx1-1]);
+ }
+ }
+ builder.Pad(7);
+ builder.PutSbyte(C);
+ for (int _idx0 = 15; _idx0 > 0; _idx0--) {
+ builder.PutInt(B[_idx0-1]);
+ }
+ builder.PutFloat(A);
+ return new Offset<MyGame.Example.ArrayStruct>(builder.Offset);
+ }
+ public ArrayStructT UnPack() {
+ var _o = new ArrayStructT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(ArrayStructT _o) {
+ _o.A = this.A;
+ _o.B = new int[15];
+ for (var _j = 0; _j < 15; ++_j) { _o.B[_j] = this.B(_j); }
+ _o.C = this.C;
+ _o.D = new MyGame.Example.NestedStructT[2];
+ for (var _j = 0; _j < 2; ++_j) { _o.D[_j] = this.D(_j).UnPack(); }
+ _o.E = this.E;
+ _o.F = new long[2];
+ for (var _j = 0; _j < 2; ++_j) { _o.F[_j] = this.F(_j); }
+ }
+ public static Offset<MyGame.Example.ArrayStruct> Pack(FlatBufferBuilder builder, ArrayStructT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.ArrayStruct>);
+ var _b = _o.B;
+ var _d_a = new int[2,2];
+ for (var idx0 = 0; idx0 < 2; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_d_a[idx0,idx1] = _o.D[idx0].A[idx1];}}
+ var _d_b = new MyGame.Example.TestEnum[2];
+ for (var idx0 = 0; idx0 < 2; ++idx0) {_d_b[idx0] = _o.D[idx0].B;}
+ var _d_c = new MyGame.Example.TestEnum[2,2];
+ for (var idx0 = 0; idx0 < 2; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_d_c[idx0,idx1] = _o.D[idx0].C[idx1];}}
+ var _d_d = new long[2,2];
+ for (var idx0 = 0; idx0 < 2; ++idx0) {for (var idx1 = 0; idx1 < 2; ++idx1) {_d_d[idx0,idx1] = _o.D[idx0].D[idx1];}}
+ var _f = _o.F;
+ return CreateArrayStruct(
+ builder,
+ _o.A,
+ _b,
+ _o.C,
+ _d_a,
+ _d_b,
+ _d_c,
+ _d_d,
+ _o.E,
+ _f);
+ }
+};
+
+public class ArrayStructT
+{
+ [Newtonsoft.Json.JsonProperty("a")]
+ public float A { get; set; }
+ [Newtonsoft.Json.JsonProperty("b")]
+ public int[] B { get; set; }
+ [Newtonsoft.Json.JsonProperty("c")]
+ public sbyte C { get; set; }
+ [Newtonsoft.Json.JsonProperty("d")]
+ public MyGame.Example.NestedStructT[] D { get; set; }
+ [Newtonsoft.Json.JsonProperty("e")]
+ public int E { get; set; }
+ [Newtonsoft.Json.JsonProperty("f")]
+ public long[] F { get; set; }
+
+ public ArrayStructT() {
+ this.A = 0.0f;
+ this.B = new int[15];
+ this.C = 0;
+ this.D = new MyGame.Example.NestedStructT[2];
+ this.E = 0;
+ this.F = new long[2];
+ }
+}
+
+
+}
diff --git a/tests/MyGame/Example/ArrayStruct.java b/tests/MyGame/Example/ArrayStruct.java
new file mode 100644
index 00000000..5c5b3f67
--- /dev/null
+++ b/tests/MyGame/Example/ArrayStruct.java
@@ -0,0 +1,64 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class ArrayStruct extends Struct {
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+ public ArrayStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+ public float a() { return bb.getFloat(bb_pos + 0); }
+ public void mutateA(float a) { bb.putFloat(bb_pos + 0, a); }
+ public int b(int j) { return bb.getInt(bb_pos + 4 + j * 4); }
+ public void mutateB(int j, int b) { bb.putInt(bb_pos + 4 + j * 4, b); }
+ public byte c() { return bb.get(bb_pos + 64); }
+ public void mutateC(byte c) { bb.put(bb_pos + 64, c); }
+ public MyGame.Example.NestedStruct d(MyGame.Example.NestedStruct obj, int j) { return obj.__assign(bb_pos + 72 + j * 32, bb); }
+ public int e() { return bb.getInt(bb_pos + 136); }
+ public void mutateE(int e) { bb.putInt(bb_pos + 136, e); }
+ public long f(int j) { return bb.getLong(bb_pos + 144 + j * 8); }
+ public void mutateF(int j, long f) { bb.putLong(bb_pos + 144 + j * 8, f); }
+
+ public static int createArrayStruct(FlatBufferBuilder builder, float a, int[] b, byte c, int[][] d_a, byte[] d_b, byte[][] d_c, long[][] d_d, int e, long[] f) {
+ builder.prep(8, 160);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.putLong(f[_idx0-1]);
+ }
+ builder.pad(4);
+ builder.putInt(e);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.prep(8, 32);
+ for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+ builder.putLong(d_d[_idx0-1][_idx1-1]);
+ }
+ builder.pad(5);
+ for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+ builder.putByte(d_c[_idx0-1][_idx1-1]);
+ }
+ builder.putByte(d_b[_idx0-1]);
+ for (int _idx1 = 2; _idx1 > 0; _idx1--) {
+ builder.putInt(d_a[_idx0-1][_idx1-1]);
+ }
+ }
+ builder.pad(7);
+ builder.putByte(c);
+ for (int _idx0 = 15; _idx0 > 0; _idx0--) {
+ builder.putInt(b[_idx0-1]);
+ }
+ builder.putFloat(a);
+ return builder.offset();
+ }
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public ArrayStruct get(int j) { return get(new ArrayStruct(), j); }
+ public ArrayStruct get(ArrayStruct obj, int j) { return obj.__assign(__element(j), bb); }
+ }
+}
+
diff --git a/tests/MyGame/Example/ArrayStruct.py b/tests/MyGame/Example/ArrayStruct.py
new file mode 100644
index 00000000..50f136df
--- /dev/null
+++ b/tests/MyGame/Example/ArrayStruct.py
@@ -0,0 +1,148 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
+
+class ArrayStruct(object):
+ __slots__ = ['_tab']
+
+ # ArrayStruct
+ def Init(self, buf, pos):
+ self._tab = flatbuffers.table.Table(buf, pos)
+
+ # ArrayStruct
+ def A(self): return self._tab.Get(flatbuffers.number_types.Float32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0))
+ # ArrayStruct
+ def B(self): return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(4 + i * 4)) for i in range(15)]
+ # ArrayStruct
+ def BLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # ArrayStruct
+ def BIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+ return o == 0
+
+ # ArrayStruct
+ def C(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(64))
+ # ArrayStruct
+ def D(self, obj, i):
+ obj.Init(self._tab.Bytes, self._tab.Pos + 72 + i * 32)
+ return obj
+
+ # ArrayStruct
+ def DLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # ArrayStruct
+ def DIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
+ return o == 0
+
+ # ArrayStruct
+ def E(self): return self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(136))
+ # ArrayStruct
+ def F(self): return [self._tab.Get(flatbuffers.number_types.Int64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(144 + i * 8)) for i in range(2)]
+ # ArrayStruct
+ def FLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(144))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # ArrayStruct
+ def FIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(144))
+ return o == 0
+
+
+def CreateArrayStruct(builder, a, b, c, d_a, d_b, d_c, d_d, e, f):
+ builder.Prep(8, 160)
+ for _idx0 in range(2 , 0, -1):
+ builder.PrependInt64(f[_idx0-1])
+ builder.Pad(4)
+ builder.PrependInt32(e)
+ for _idx0 in range(2 , 0, -1):
+ builder.Prep(8, 32)
+ for _idx1 in range(2 , 0, -1):
+ builder.PrependInt64(d_d[_idx0-1][_idx1-1])
+ builder.Pad(5)
+ for _idx1 in range(2 , 0, -1):
+ builder.PrependInt8(d_c[_idx0-1][_idx1-1])
+ builder.PrependInt8(d_b[_idx0-1])
+ for _idx1 in range(2 , 0, -1):
+ builder.PrependInt32(d_a[_idx0-1][_idx1-1])
+ builder.Pad(7)
+ builder.PrependInt8(c)
+ for _idx0 in range(15 , 0, -1):
+ builder.PrependInt32(b[_idx0-1])
+ builder.PrependFloat32(a)
+ return builder.Offset()
+
+import MyGame.Example.NestedStruct
+try:
+ from typing import List
+except:
+ pass
+
+class ArrayStructT(object):
+
+ # ArrayStructT
+ def __init__(self):
+ self.a = 0.0 # type: float
+ self.b = None # type: List[int]
+ self.c = 0 # type: int
+ self.d = None # type: List[MyGame.Example.NestedStruct.NestedStructT]
+ self.e = 0 # type: int
+ self.f = None # type: List[int]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ arrayStruct = ArrayStruct()
+ arrayStruct.Init(buf, pos)
+ return cls.InitFromObj(arrayStruct)
+
+ @classmethod
+ def InitFromObj(cls, arrayStruct):
+ x = ArrayStructT()
+ x._UnPack(arrayStruct)
+ return x
+
+ # ArrayStructT
+ def _UnPack(self, arrayStruct):
+ if arrayStruct is None:
+ return
+ self.a = arrayStruct.A()
+ if not arrayStruct.BIsNone():
+ if np is None:
+ self.b = []
+ for i in range(arrayStruct.BLength()):
+ self.b.append(arrayStruct.B(i))
+ else:
+ self.b = arrayStruct.BAsNumpy()
+ self.c = arrayStruct.C()
+ if not arrayStruct.DIsNone():
+ self.d = []
+ for i in range(arrayStruct.DLength()):
+ self.d.append(arrayStruct.D(i))
+ self.e = arrayStruct.E()
+ if not arrayStruct.FIsNone():
+ if np is None:
+ self.f = []
+ for i in range(arrayStruct.FLength()):
+ self.f.append(arrayStruct.F(i))
+ else:
+ self.f = arrayStruct.FAsNumpy()
+
+ # ArrayStructT
+ def Pack(self, builder):
+ return CreateArrayStruct(builder, self.a, self.b, self.c, self.d.a, self.d.b, self.d.c, self.d.d, self.e, self.f)
diff --git a/tests/MyGame/Example/ArrayTable.cs b/tests/MyGame/Example/ArrayTable.cs
new file mode 100644
index 00000000..4f743d0d
--- /dev/null
+++ b/tests/MyGame/Example/ArrayTable.cs
@@ -0,0 +1,75 @@
+// <auto-generated>
+// automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::System.Collections.Generic;
+using global::FlatBuffers;
+
+public struct ArrayTable : IFlatbufferObject
+{
+ private Table __p;
+ public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
+ public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb) { return GetRootAsArrayTable(_bb, new ArrayTable()); }
+ public static ArrayTable GetRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
+ public static bool ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "ARRT"); }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
+ public ArrayTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+ public MyGame.Example.ArrayStruct? A { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.ArrayStruct?)(new MyGame.Example.ArrayStruct()).__assign(o + __p.bb_pos, __p.bb) : null; } }
+
+ public static void StartArrayTable(FlatBufferBuilder builder) { builder.StartTable(1); }
+ public static void AddA(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayStruct> aOffset) { builder.AddStruct(0, aOffset.Value, 0); }
+ public static Offset<MyGame.Example.ArrayTable> EndArrayTable(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<MyGame.Example.ArrayTable>(o);
+ }
+ public static void FinishArrayTableBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayTable> offset) { builder.Finish(offset.Value, "ARRT"); }
+ public static void FinishSizePrefixedArrayTableBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.ArrayTable> offset) { builder.FinishSizePrefixed(offset.Value, "ARRT"); }
+ public ArrayTableT UnPack() {
+ var _o = new ArrayTableT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(ArrayTableT _o) {
+ _o.A = this.A.HasValue ? this.A.Value.UnPack() : null;
+ }
+ public static Offset<MyGame.Example.ArrayTable> Pack(FlatBufferBuilder builder, ArrayTableT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.ArrayTable>);
+ StartArrayTable(builder);
+ AddA(builder, MyGame.Example.ArrayStruct.Pack(builder, _o.A));
+ return EndArrayTable(builder);
+ }
+};
+
+public class ArrayTableT
+{
+ [Newtonsoft.Json.JsonProperty("a")]
+ public MyGame.Example.ArrayStructT A { get; set; }
+
+ public ArrayTableT() {
+ this.A = new MyGame.Example.ArrayStructT();
+ }
+
+ public static ArrayTableT DeserializeFromJson(string jsonText) {
+ return Newtonsoft.Json.JsonConvert.DeserializeObject<ArrayTableT>(jsonText);
+ }
+ public string SerializeToJson() {
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ }
+ public static ArrayTableT DeserializeFromBinary(byte[] fbBuffer) {
+ return ArrayTable.GetRootAsArrayTable(new ByteBuffer(fbBuffer)).UnPack();
+ }
+ public byte[] SerializeToBinary() {
+ var fbb = new FlatBufferBuilder(0x10000);
+ fbb.Finish(ArrayTable.Pack(fbb, this).Value);
+ return fbb.DataBuffer.ToSizedArray();
+ }
+}
+
+
+}
diff --git a/tests/MyGame/Example/ArrayTable.java b/tests/MyGame/Example/ArrayTable.java
new file mode 100644
index 00000000..41730d3f
--- /dev/null
+++ b/tests/MyGame/Example/ArrayTable.java
@@ -0,0 +1,38 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class ArrayTable extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
+ public static ArrayTable getRootAsArrayTable(ByteBuffer _bb) { return getRootAsArrayTable(_bb, new ArrayTable()); }
+ public static ArrayTable getRootAsArrayTable(ByteBuffer _bb, ArrayTable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
+ public static boolean ArrayTableBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "ARRT"); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+ public ArrayTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+ public MyGame.Example.ArrayStruct a() { return a(new MyGame.Example.ArrayStruct()); }
+ public MyGame.Example.ArrayStruct a(MyGame.Example.ArrayStruct obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
+
+ public static void startArrayTable(FlatBufferBuilder builder) { builder.startTable(1); }
+ public static void addA(FlatBufferBuilder builder, int aOffset) { builder.addStruct(0, aOffset, 0); }
+ public static int endArrayTable(FlatBufferBuilder builder) {
+ int o = builder.endTable();
+ return o;
+ }
+ public static void finishArrayTableBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "ARRT"); }
+ public static void finishSizePrefixedArrayTableBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "ARRT"); }
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public ArrayTable get(int j) { return get(new ArrayTable(), j); }
+ public ArrayTable get(ArrayTable obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
+}
+
diff --git a/tests/MyGame/Example/ArrayTable.py b/tests/MyGame/Example/ArrayTable.py
new file mode 100644
index 00000000..83905e60
--- /dev/null
+++ b/tests/MyGame/Example/ArrayTable.py
@@ -0,0 +1,80 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
+
+class ArrayTable(object):
+ __slots__ = ['_tab']
+
+ @classmethod
+ def GetRootAsArrayTable(cls, buf, offset):
+ n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
+ x = ArrayTable()
+ x.Init(buf, n + offset)
+ return x
+
+ @classmethod
+ def ArrayTableBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x41\x52\x52\x54", size_prefixed=size_prefixed)
+
+ # ArrayTable
+ def Init(self, buf, pos):
+ self._tab = flatbuffers.table.Table(buf, pos)
+
+ # ArrayTable
+ def A(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
+ if o != 0:
+ x = o + self._tab.Pos
+ from MyGame.Example.ArrayStruct import ArrayStruct
+ obj = ArrayStruct()
+ obj.Init(self._tab.Bytes, x)
+ return obj
+ return None
+
+def ArrayTableStart(builder): builder.StartObject(1)
+def ArrayTableAddA(builder, a): builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(a), 0)
+def ArrayTableEnd(builder): return builder.EndObject()
+
+import MyGame.Example.ArrayStruct
+try:
+ from typing import Optional
+except:
+ pass
+
+class ArrayTableT(object):
+
+ # ArrayTableT
+ def __init__(self):
+ self.a = None # type: Optional[MyGame.Example.ArrayStruct.ArrayStructT]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ arrayTable = ArrayTable()
+ arrayTable.Init(buf, pos)
+ return cls.InitFromObj(arrayTable)
+
+ @classmethod
+ def InitFromObj(cls, arrayTable):
+ x = ArrayTableT()
+ x._UnPack(arrayTable)
+ return x
+
+ # ArrayTableT
+ def _UnPack(self, arrayTable):
+ if arrayTable is None:
+ return
+ if arrayTable.A() is not None:
+ self.a = MyGame.Example.ArrayStruct.ArrayStructT.InitFromObj(arrayTable.A())
+
+ # ArrayTableT
+ def Pack(self, builder):
+ ArrayTableStart(builder)
+ if self.a is not None:
+ a = self.a.Pack(builder)
+ ArrayTableAddA(builder, a)
+ arrayTable = ArrayTableEnd(builder)
+ return arrayTable
diff --git a/tests/MyGame/Example/Color.cs b/tests/MyGame/Example/Color.cs
index f40d60ba..1137a276 100644
--- a/tests/MyGame/Example/Color.cs
+++ b/tests/MyGame/Example/Color.cs
@@ -5,11 +5,17 @@
namespace MyGame.Example
{
-public enum Color : sbyte
+/// Composite components of Monster color.
+[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
+[System.FlagsAttribute]
+public enum Color : byte
{
- Red = 1,
- Green = 2,
- Blue = 8,
+ Red = 1,
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
+ Green = 2,
+ /// \brief color Blue (1u << 3)
+ Blue = 8,
};
diff --git a/tests/MyGame/Example/Color.go b/tests/MyGame/Example/Color.go
index cc083348..9570ae47 100644
--- a/tests/MyGame/Example/Color.go
+++ b/tests/MyGame/Example/Color.go
@@ -2,16 +2,35 @@
package Example
-type Color = int8
+import "strconv"
+
+/// Composite components of Monster color.
+type Color byte
+
const (
- ColorRed Color = 1
+ ColorRed Color = 1
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
ColorGreen Color = 2
- ColorBlue Color = 8
+ /// \brief color Blue (1u << 3)
+ ColorBlue Color = 8
)
var EnumNamesColor = map[Color]string{
- ColorRed:"Red",
- ColorGreen:"Green",
- ColorBlue:"Blue",
+ ColorRed: "Red",
+ ColorGreen: "Green",
+ ColorBlue: "Blue",
}
+var EnumValuesColor = map[string]Color{
+ "Red": ColorRed,
+ "Green": ColorGreen,
+ "Blue": ColorBlue,
+}
+
+func (v Color) String() string {
+ if s, ok := EnumNamesColor[v]; ok {
+ return s
+ }
+ return "Color(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/tests/MyGame/Example/Color.java b/tests/MyGame/Example/Color.java
index 7c113b72..0563c0ab 100644
--- a/tests/MyGame/Example/Color.java
+++ b/tests/MyGame/Example/Color.java
@@ -2,10 +2,20 @@
package MyGame.Example;
+/**
+ * Composite components of Monster color.
+ */
public final class Color {
private Color() { }
public static final byte Red = 1;
+ /**
+ * \brief color Green
+ * Green is bit_flag with value (1u << 1)
+ */
public static final byte Green = 2;
+ /**
+ * \brief color Blue (1u << 3)
+ */
public static final byte Blue = 8;
public static final String[] names = { "Red", "Green", "", "", "", "", "", "Blue", };
diff --git a/tests/MyGame/Example/Color.kt b/tests/MyGame/Example/Color.kt
new file mode 100644
index 00000000..4c27ba35
--- /dev/null
+++ b/tests/MyGame/Example/Color.kt
@@ -0,0 +1,25 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+/**
+ * Composite components of Monster color.
+ */
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Color private constructor() {
+ companion object {
+ const val Red: UByte = 1u
+ /**
+ * \brief color Green
+ * Green is bit_flag with value (1u << 1)
+ */
+ const val Green: UByte = 2u
+ /**
+ * \brief color Blue (1u << 3)
+ */
+ const val Blue: UByte = 8u
+ val names : Array<String> = arrayOf("Red", "Green", "", "", "", "", "", "Blue")
+ fun name(e: Int) : String = names[e - Red.toInt()]
+ }
+}
diff --git a/tests/MyGame/Example/Color.lua b/tests/MyGame/Example/Color.lua
index c3ec0922..d4d2cbc8 100644
--- a/tests/MyGame/Example/Color.lua
+++ b/tests/MyGame/Example/Color.lua
@@ -2,9 +2,13 @@
-- namespace: Example
+-- Composite components of Monster color.
local Color = {
Red = 1,
+ -- \brief color Green
+ -- Green is bit_flag with value (1u << 1)
Green = 2,
+ -- \brief color Blue (1u << 3)
Blue = 8,
}
diff --git a/tests/MyGame/Example/Color.php b/tests/MyGame/Example/Color.php
index d89529e8..8c329221 100644
--- a/tests/MyGame/Example/Color.php
+++ b/tests/MyGame/Example/Color.php
@@ -3,10 +3,14 @@
namespace MyGame\Example;
+/// Composite components of Monster color.
class Color
{
const Red = 1;
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
const Green = 2;
+ /// \brief color Blue (1u << 3)
const Blue = 8;
private static $names = array(
diff --git a/tests/MyGame/Example/Color.py b/tests/MyGame/Example/Color.py
index 36e80a36..55aa8212 100644
--- a/tests/MyGame/Example/Color.py
+++ b/tests/MyGame/Example/Color.py
@@ -2,8 +2,12 @@
# namespace: Example
+# Composite components of Monster color.
class Color(object):
Red = 1
+ # \brief color Green
+ # Green is bit_flag with value (1u << 1)
Green = 2
+ # \brief color Blue (1u << 3)
Blue = 8
diff --git a/tests/MyGame/Example/Monster.cs b/tests/MyGame/Example/Monster.cs
index 54900866..56b41d9a 100644
--- a/tests/MyGame/Example/Monster.cs
+++ b/tests/MyGame/Example/Monster.cs
@@ -6,27 +6,29 @@ namespace MyGame.Example
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
-/// an example documentation comment: monster object
+/// an example documentation comment: "monster object"
public struct Monster : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONS"); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public Vec3? Pos { get { int o = __p.__offset(4); return o != 0 ? (Vec3?)(new Vec3()).__assign(o + __p.bb_pos, __p.bb) : null; } }
+ public MyGame.Example.Vec3? Pos { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.Vec3?)(new MyGame.Example.Vec3()).__assign(o + __p.bb_pos, __p.bb) : null; } }
public short Mana { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)150; } }
public bool MutateMana(short mana) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, mana); return true; } else { return false; } }
public short Hp { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)100; } }
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetNameBytes() { return __p.__vector_as_span(10); }
+ public Span<byte> GetNameBytes() { return __p.__vector_as_span<byte>(10, 1); }
#else
public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(10); }
#endif
@@ -34,38 +36,37 @@ public struct Monster : IFlatbufferObject
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetInventoryBytes() { return __p.__vector_as_span(14); }
+ public Span<byte> GetInventoryBytes() { return __p.__vector_as_span<byte>(14, 1); }
#else
public ArraySegment<byte>? GetInventoryBytes() { return __p.__vector_as_arraysegment(14); }
#endif
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; } }
- public Any TestType { get { int o = __p.__offset(18); return o != 0 ? (Any)__p.bb.Get(o + __p.bb_pos) : Any.NONE; } }
- public bool MutateTestType(Any test_type) { int o = __p.__offset(18); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)test_type); return true; } else { return false; } }
- public TTable? Test<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(20); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
- public Test? Test4(int j) { int o = __p.__offset(22); return o != 0 ? (Test?)(new Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
+ public MyGame.Example.Color Color { get { int o = __p.__offset(16); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Blue; } }
+ public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(16); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } }
+ public MyGame.Example.Any TestType { get { int o = __p.__offset(18); return o != 0 ? (MyGame.Example.Any)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Any.NONE; } }
+ public TTable? Test<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(20); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
+ public MyGame.Example.Test? Test4(int j) { int o = __p.__offset(22); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
public int Test4Length { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
public string Testarrayofstring(int j) { int o = __p.__offset(24); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
public int TestarrayofstringLength { get { int o = __p.__offset(24); return o != 0 ? __p.__vector_len(o) : 0; } }
/// an example documentation comment: this will end up in the generated code
/// multiline too
- public Monster? Testarrayoftables(int j) { int o = __p.__offset(26); return o != 0 ? (Monster?)(new Monster()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
+ public MyGame.Example.Monster? Testarrayoftables(int j) { int o = __p.__offset(26); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
public int TestarrayoftablesLength { get { int o = __p.__offset(26); return o != 0 ? __p.__vector_len(o) : 0; } }
- public Monster? TestarrayoftablesByKey(string key) { int o = __p.__offset(26); return o != 0 ? Monster.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
- public Monster? Enemy { get { int o = __p.__offset(28); return o != 0 ? (Monster?)(new Monster()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
+ public MyGame.Example.Monster? TestarrayoftablesByKey(string key) { int o = __p.__offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+ public MyGame.Example.Monster? Enemy { get { int o = __p.__offset(28); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.Monster()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetTestnestedflatbufferBytes() { return __p.__vector_as_span(30); }
+ public Span<byte> GetTestnestedflatbufferBytes() { return __p.__vector_as_span<byte>(30, 1); }
#else
public ArraySegment<byte>? GetTestnestedflatbufferBytes() { return __p.__vector_as_arraysegment(30); }
#endif
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 MyGame.Example.Monster? GetTestnestedflatbufferAsMonster() { int o = __p.__offset(30); return o != 0 ? (MyGame.Example.Monster?)(new MyGame.Example.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; } }
+ public MyGame.Example.Stat? Testempty { get { int o = __p.__offset(32); return o != 0 ? (MyGame.Example.Stat?)(new MyGame.Example.Stat()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public bool Testbool { get { int o = __p.__offset(34); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
public bool MutateTestbool(bool testbool) { int o = __p.__offset(34); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
public int Testhashs32Fnv1 { get { int o = __p.__offset(36); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
@@ -87,7 +88,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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetTestarrayofboolsBytes() { return __p.__vector_as_span(52); }
+ public Span<bool> GetTestarrayofboolsBytes() { return __p.__vector_as_span<bool>(52, 1); }
#else
public ArraySegment<byte>? GetTestarrayofboolsBytes() { return __p.__vector_as_arraysegment(52); }
#endif
@@ -101,23 +102,23 @@ public struct Monster : IFlatbufferObject
public bool MutateTestf3(float testf3) { int o = __p.__offset(58); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf3); return true; } else { return false; } }
public string Testarrayofstring2(int j) { int o = __p.__offset(60); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
public int Testarrayofstring2Length { get { int o = __p.__offset(60); return o != 0 ? __p.__vector_len(o) : 0; } }
- public Ability? Testarrayofsortedstruct(int j) { int o = __p.__offset(62); return o != 0 ? (Ability?)(new Ability()).__assign(__p.__vector(o) + j * 8, __p.bb) : null; }
+ public MyGame.Example.Ability? Testarrayofsortedstruct(int j) { int o = __p.__offset(62); return o != 0 ? (MyGame.Example.Ability?)(new MyGame.Example.Ability()).__assign(__p.__vector(o) + j * 8, __p.bb) : null; }
public int TestarrayofsortedstructLength { get { int o = __p.__offset(62); return o != 0 ? __p.__vector_len(o) : 0; } }
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetFlexBytes() { return __p.__vector_as_span(64); }
+ public Span<byte> GetFlexBytes() { return __p.__vector_as_span<byte>(64, 1); }
#else
public ArraySegment<byte>? GetFlexBytes() { return __p.__vector_as_arraysegment(64); }
#endif
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 MyGame.Example.Test? Test5(int j) { int o = __p.__offset(66); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetVectorOfLongsBytes() { return __p.__vector_as_span(68); }
+ public Span<long> GetVectorOfLongsBytes() { return __p.__vector_as_span<long>(68, 8); }
#else
public ArraySegment<byte>? GetVectorOfLongsBytes() { return __p.__vector_as_arraysegment(68); }
#endif
@@ -126,36 +127,36 @@ public struct Monster : IFlatbufferObject
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetVectorOfDoublesBytes() { return __p.__vector_as_span(70); }
+ public Span<double> GetVectorOfDoublesBytes() { return __p.__vector_as_span<double>(70, 8); }
#else
public ArraySegment<byte>? GetVectorOfDoublesBytes() { return __p.__vector_as_arraysegment(70); }
#endif
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; }
+ public MyGame.Example.Referrable? VectorOfReferrables(int j) { int o = __p.__offset(74); return o != 0 ? (MyGame.Example.Referrable?)(new MyGame.Example.Referrable()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
public int VectorOfReferrablesLength { get { int o = __p.__offset(74); return o != 0 ? __p.__vector_len(o) : 0; } }
- public Referrable? VectorOfReferrablesByKey(ulong key) { int o = __p.__offset(74); return o != 0 ? Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+ public MyGame.Example.Referrable? VectorOfReferrablesByKey(ulong key) { int o = __p.__offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
public ulong SingleWeakReference { get { int o = __p.__offset(76); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
public bool MutateSingleWeakReference(ulong single_weak_reference) { int o = __p.__offset(76); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, single_weak_reference); return true; } else { return false; } }
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetVectorOfWeakReferencesBytes() { return __p.__vector_as_span(78); }
+ public Span<ulong> GetVectorOfWeakReferencesBytes() { return __p.__vector_as_span<ulong>(78, 8); }
#else
public ArraySegment<byte>? GetVectorOfWeakReferencesBytes() { return __p.__vector_as_arraysegment(78); }
#endif
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 MyGame.Example.Referrable? VectorOfStrongReferrables(int j) { int o = __p.__offset(80); return o != 0 ? (MyGame.Example.Referrable?)(new MyGame.Example.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; } }
- public Referrable? VectorOfStrongReferrablesByKey(ulong key) { int o = __p.__offset(80); return o != 0 ? Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
+ public MyGame.Example.Referrable? VectorOfStrongReferrablesByKey(ulong key) { int o = __p.__offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(__p.__vector(o), key, __p.bb) : null; }
public ulong CoOwningReference { get { int o = __p.__offset(82); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
public bool MutateCoOwningReference(ulong co_owning_reference) { int o = __p.__offset(82); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, co_owning_reference); return true; } else { return false; } }
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_span(84); }
+ public Span<ulong> GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_span<ulong>(84, 8); }
#else
public ArraySegment<byte>? GetVectorOfCoOwningReferencesBytes() { return __p.__vector_as_arraysegment(84); }
#endif
@@ -166,30 +167,30 @@ public struct Monster : IFlatbufferObject
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_span(88); }
+ public Span<ulong> GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_span<ulong>(88, 8); }
#else
public ArraySegment<byte>? GetVectorOfNonOwningReferencesBytes() { return __p.__vector_as_arraysegment(88); }
#endif
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 AnyUniqueAliases AnyUniqueType { get { int o = __p.__offset(90); return o != 0 ? (AnyUniqueAliases)__p.bb.Get(o + __p.bb_pos) : AnyUniqueAliases.NONE; } }
- public bool MutateAnyUniqueType(AnyUniqueAliases any_unique_type) { int o = __p.__offset(90); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)any_unique_type); return true; } else { return false; } }
- public TTable? AnyUnique<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(92); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
- public AnyAmbiguousAliases AnyAmbiguousType { get { int o = __p.__offset(94); return o != 0 ? (AnyAmbiguousAliases)__p.bb.Get(o + __p.bb_pos) : AnyAmbiguousAliases.NONE; } }
- public bool MutateAnyAmbiguousType(AnyAmbiguousAliases any_ambiguous_type) { int o = __p.__offset(94); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)any_ambiguous_type); return true; } else { return false; } }
- public TTable? AnyAmbiguous<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(96); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
- public Color VectorOfEnums(int j) { int o = __p.__offset(98); return o != 0 ? (Color)__p.bb.GetSbyte(__p.__vector(o) + j * 1) : (Color)0; }
+ public MyGame.Example.AnyUniqueAliases AnyUniqueType { get { int o = __p.__offset(90); return o != 0 ? (MyGame.Example.AnyUniqueAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyUniqueAliases.NONE; } }
+ public TTable? AnyUnique<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(92); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
+ public MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType { get { int o = __p.__offset(94); return o != 0 ? (MyGame.Example.AnyAmbiguousAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyAmbiguousAliases.NONE; } }
+ public TTable? AnyAmbiguous<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(96); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
+ public MyGame.Example.Color VectorOfEnums(int j) { int o = __p.__offset(98); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(__p.__vector(o) + j * 1) : (MyGame.Example.Color)0; }
public int VectorOfEnumsLength { get { int o = __p.__offset(98); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
- public Span<byte> GetVectorOfEnumsBytes() { return __p.__vector_as_span(98); }
+ public Span<MyGame.Example.Color> GetVectorOfEnumsBytes() { return __p.__vector_as_span<MyGame.Example.Color>(98, 1); }
#else
public ArraySegment<byte>? GetVectorOfEnumsBytes() { return __p.__vector_as_arraysegment(98); }
#endif
- public Color[] GetVectorOfEnumsArray() { return __p.__vector_as_array<Color>(98); }
- public bool MutateVectorOfEnums(int j, Color vector_of_enums) { int o = __p.__offset(98); if (o != 0) { __p.bb.PutSbyte(__p.__vector(o) + j * 1, (sbyte)vector_of_enums); return true; } else { return false; } }
+ 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 MyGame.Example.Race SignedEnum { get { int o = __p.__offset(100); return o != 0 ? (MyGame.Example.Race)__p.bb.GetSbyte(o + __p.bb_pos) : MyGame.Example.Race.None; } }
+ public bool MutateSignedEnum(MyGame.Example.Race signed_enum) { int o = __p.__offset(100); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)signed_enum); return true; } else { return false; } }
- public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(48); }
- public static void AddPos(FlatBufferBuilder builder, Offset<Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 0); }
+ public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(49); }
+ public static void AddPos(FlatBufferBuilder builder, Offset<MyGame.Example.Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 0); }
public static void AddMana(FlatBufferBuilder builder, short mana) { builder.AddShort(1, mana, 150); }
public static void AddHp(FlatBufferBuilder builder, short hp) { builder.AddShort(2, hp, 100); }
public static void AddName(FlatBufferBuilder builder, StringOffset nameOffset) { builder.AddOffset(3, nameOffset.Value, 0); }
@@ -197,8 +198,8 @@ public struct Monster : IFlatbufferObject
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); }
+ public static void AddColor(FlatBufferBuilder builder, MyGame.Example.Color color) { builder.AddByte(6, (byte)color, 8); }
+ public static void AddTestType(FlatBufferBuilder builder, MyGame.Example.Any testType) { builder.AddByte(7, (byte)testType, 0); }
public static void AddTest(FlatBufferBuilder builder, int testOffset) { builder.AddOffset(8, testOffset, 0); }
public static void AddTest4(FlatBufferBuilder builder, VectorOffset test4Offset) { builder.AddOffset(9, test4Offset.Value, 0); }
public static void StartTest4Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
@@ -207,15 +208,15 @@ public struct Monster : IFlatbufferObject
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 VectorOffset CreateTestarrayoftablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.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<MyGame.Example.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 AddEnemy(FlatBufferBuilder builder, Offset<MyGame.Example.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 AddTestempty(FlatBufferBuilder builder, Offset<MyGame.Example.Stat> testemptyOffset) { builder.AddOffset(14, testemptyOffset.Value, 0); }
public static void AddTestbool(FlatBufferBuilder builder, bool testbool) { builder.AddBool(15, testbool, false); }
public static void AddTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.AddInt(16, testhashs32Fnv1, 0); }
public static void AddTesthashu32Fnv1(FlatBufferBuilder builder, uint testhashu32Fnv1) { builder.AddUint(17, testhashu32Fnv1, 0); }
@@ -254,8 +255,8 @@ public struct Monster : IFlatbufferObject
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 VectorOffset CreateVectorOfReferrablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.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<MyGame.Example.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); }
@@ -263,8 +264,8 @@ public struct Monster : IFlatbufferObject
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 VectorOffset CreateVectorOfStrongReferrablesVector(FlatBufferBuilder builder, Offset<MyGame.Example.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<MyGame.Example.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); }
@@ -276,21 +277,22 @@ public struct Monster : IFlatbufferObject
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 void AddAnyUniqueType(FlatBufferBuilder builder, AnyUniqueAliases anyUniqueType) { builder.AddByte(43, (byte)anyUniqueType, 0); }
+ public static void AddAnyUniqueType(FlatBufferBuilder builder, MyGame.Example.AnyUniqueAliases anyUniqueType) { builder.AddByte(43, (byte)anyUniqueType, 0); }
public static void AddAnyUnique(FlatBufferBuilder builder, int anyUniqueOffset) { builder.AddOffset(44, anyUniqueOffset, 0); }
- public static void AddAnyAmbiguousType(FlatBufferBuilder builder, AnyAmbiguousAliases anyAmbiguousType) { builder.AddByte(45, (byte)anyAmbiguousType, 0); }
+ public static void AddAnyAmbiguousType(FlatBufferBuilder builder, MyGame.Example.AnyAmbiguousAliases anyAmbiguousType) { builder.AddByte(45, (byte)anyAmbiguousType, 0); }
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, Color[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddSbyte((sbyte)data[i]); return builder.EndVector(); }
- public static VectorOffset CreateVectorOfEnumsVectorBlock(FlatBufferBuilder builder, Color[] data) { builder.StartVector(1, data.Length, 1); builder.Add(data); return builder.EndVector(); }
+ 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<Monster> EndMonster(FlatBufferBuilder builder) {
- int o = builder.EndObject();
+ public static void AddSignedEnum(FlatBufferBuilder builder, MyGame.Example.Race signedEnum) { builder.AddSbyte(48, (sbyte)signedEnum, -1); }
+ public static Offset<MyGame.Example.Monster> EndMonster(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
builder.Required(o, 10); // name
- return new Offset<Monster>(o);
+ return new Offset<MyGame.Example.Monster>(o);
}
- public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<Monster> offset) { builder.Finish(offset.Value, "MONS"); }
- public static void FinishSizePrefixedMonsterBuffer(FlatBufferBuilder builder, Offset<Monster> offset) { builder.FinishSizePrefixed(offset.Value, "MONS"); }
+ public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> offset) { builder.Finish(offset.Value, "MONS"); }
+ public static void FinishSizePrefixedMonsterBuffer(FlatBufferBuilder builder, Offset<MyGame.Example.Monster> offset) { builder.FinishSizePrefixed(offset.Value, "MONS"); }
public static VectorOffset CreateSortedVectorOfMonster(FlatBufferBuilder builder, Offset<Monster>[] offsets) {
Array.Sort(offsets, (Offset<Monster> o1, Offset<Monster> o2) => Table.CompareStrings(Table.__offset(10, o1.Value, builder.DataBuffer), Table.__offset(10, o2.Value, builder.DataBuffer), builder.DataBuffer));
@@ -317,7 +319,481 @@ public struct Monster : IFlatbufferObject
}
return null;
}
+ public MonsterT UnPack() {
+ var _o = new MonsterT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(MonsterT _o) {
+ _o.Pos = this.Pos.HasValue ? this.Pos.Value.UnPack() : null;
+ _o.Mana = this.Mana;
+ _o.Hp = this.Hp;
+ _o.Name = this.Name;
+ _o.Inventory = new List<byte>();
+ for (var _j = 0; _j < this.InventoryLength; ++_j) {_o.Inventory.Add(this.Inventory(_j));}
+ _o.Color = this.Color;
+ _o.Test = new MyGame.Example.AnyUnion();
+ _o.Test.Type = this.TestType;
+ switch (this.TestType) {
+ default: break;
+ case MyGame.Example.Any.Monster:
+ _o.Test.Value = this.Test<MyGame.Example.Monster>().HasValue ? this.Test<MyGame.Example.Monster>().Value.UnPack() : null;
+ break;
+ case MyGame.Example.Any.TestSimpleTableWithEnum:
+ _o.Test.Value = this.Test<MyGame.Example.TestSimpleTableWithEnum>().HasValue ? this.Test<MyGame.Example.TestSimpleTableWithEnum>().Value.UnPack() : null;
+ break;
+ case MyGame.Example.Any.MyGame_Example2_Monster:
+ _o.Test.Value = this.Test<MyGame.Example2.Monster>().HasValue ? this.Test<MyGame.Example2.Monster>().Value.UnPack() : null;
+ break;
+ }
+ _o.Test4 = new List<MyGame.Example.TestT>();
+ for (var _j = 0; _j < this.Test4Length; ++_j) {_o.Test4.Add(this.Test4(_j).HasValue ? this.Test4(_j).Value.UnPack() : null);}
+ _o.Testarrayofstring = new List<string>();
+ for (var _j = 0; _j < this.TestarrayofstringLength; ++_j) {_o.Testarrayofstring.Add(this.Testarrayofstring(_j));}
+ _o.Testarrayoftables = new List<MyGame.Example.MonsterT>();
+ for (var _j = 0; _j < this.TestarrayoftablesLength; ++_j) {_o.Testarrayoftables.Add(this.Testarrayoftables(_j).HasValue ? this.Testarrayoftables(_j).Value.UnPack() : null);}
+ _o.Enemy = this.Enemy.HasValue ? this.Enemy.Value.UnPack() : null;
+ _o.Testnestedflatbuffer = new List<byte>();
+ for (var _j = 0; _j < this.TestnestedflatbufferLength; ++_j) {_o.Testnestedflatbuffer.Add(this.Testnestedflatbuffer(_j));}
+ _o.Testempty = this.Testempty.HasValue ? this.Testempty.Value.UnPack() : null;
+ _o.Testbool = this.Testbool;
+ _o.Testhashs32Fnv1 = this.Testhashs32Fnv1;
+ _o.Testhashu32Fnv1 = this.Testhashu32Fnv1;
+ _o.Testhashs64Fnv1 = this.Testhashs64Fnv1;
+ _o.Testhashu64Fnv1 = this.Testhashu64Fnv1;
+ _o.Testhashs32Fnv1a = this.Testhashs32Fnv1a;
+ _o.Testhashu32Fnv1a = this.Testhashu32Fnv1a;
+ _o.Testhashs64Fnv1a = this.Testhashs64Fnv1a;
+ _o.Testhashu64Fnv1a = this.Testhashu64Fnv1a;
+ _o.Testarrayofbools = new List<bool>();
+ for (var _j = 0; _j < this.TestarrayofboolsLength; ++_j) {_o.Testarrayofbools.Add(this.Testarrayofbools(_j));}
+ _o.Testf = this.Testf;
+ _o.Testf2 = this.Testf2;
+ _o.Testf3 = this.Testf3;
+ _o.Testarrayofstring2 = new List<string>();
+ for (var _j = 0; _j < this.Testarrayofstring2Length; ++_j) {_o.Testarrayofstring2.Add(this.Testarrayofstring2(_j));}
+ _o.Testarrayofsortedstruct = new List<MyGame.Example.AbilityT>();
+ for (var _j = 0; _j < this.TestarrayofsortedstructLength; ++_j) {_o.Testarrayofsortedstruct.Add(this.Testarrayofsortedstruct(_j).HasValue ? this.Testarrayofsortedstruct(_j).Value.UnPack() : null);}
+ _o.Flex = new List<byte>();
+ for (var _j = 0; _j < this.FlexLength; ++_j) {_o.Flex.Add(this.Flex(_j));}
+ _o.Test5 = new List<MyGame.Example.TestT>();
+ for (var _j = 0; _j < this.Test5Length; ++_j) {_o.Test5.Add(this.Test5(_j).HasValue ? this.Test5(_j).Value.UnPack() : null);}
+ _o.VectorOfLongs = new List<long>();
+ for (var _j = 0; _j < this.VectorOfLongsLength; ++_j) {_o.VectorOfLongs.Add(this.VectorOfLongs(_j));}
+ _o.VectorOfDoubles = new List<double>();
+ for (var _j = 0; _j < this.VectorOfDoublesLength; ++_j) {_o.VectorOfDoubles.Add(this.VectorOfDoubles(_j));}
+ _o.ParentNamespaceTest = this.ParentNamespaceTest.HasValue ? this.ParentNamespaceTest.Value.UnPack() : null;
+ _o.VectorOfReferrables = new List<MyGame.Example.ReferrableT>();
+ for (var _j = 0; _j < this.VectorOfReferrablesLength; ++_j) {_o.VectorOfReferrables.Add(this.VectorOfReferrables(_j).HasValue ? this.VectorOfReferrables(_j).Value.UnPack() : null);}
+ _o.SingleWeakReference = this.SingleWeakReference;
+ _o.VectorOfWeakReferences = new List<ulong>();
+ for (var _j = 0; _j < this.VectorOfWeakReferencesLength; ++_j) {_o.VectorOfWeakReferences.Add(this.VectorOfWeakReferences(_j));}
+ _o.VectorOfStrongReferrables = new List<MyGame.Example.ReferrableT>();
+ for (var _j = 0; _j < this.VectorOfStrongReferrablesLength; ++_j) {_o.VectorOfStrongReferrables.Add(this.VectorOfStrongReferrables(_j).HasValue ? this.VectorOfStrongReferrables(_j).Value.UnPack() : null);}
+ _o.CoOwningReference = this.CoOwningReference;
+ _o.VectorOfCoOwningReferences = new List<ulong>();
+ for (var _j = 0; _j < this.VectorOfCoOwningReferencesLength; ++_j) {_o.VectorOfCoOwningReferences.Add(this.VectorOfCoOwningReferences(_j));}
+ _o.NonOwningReference = this.NonOwningReference;
+ _o.VectorOfNonOwningReferences = new List<ulong>();
+ for (var _j = 0; _j < this.VectorOfNonOwningReferencesLength; ++_j) {_o.VectorOfNonOwningReferences.Add(this.VectorOfNonOwningReferences(_j));}
+ _o.AnyUnique = new MyGame.Example.AnyUniqueAliasesUnion();
+ _o.AnyUnique.Type = this.AnyUniqueType;
+ switch (this.AnyUniqueType) {
+ default: break;
+ case MyGame.Example.AnyUniqueAliases.M:
+ _o.AnyUnique.Value = this.AnyUnique<MyGame.Example.Monster>().HasValue ? this.AnyUnique<MyGame.Example.Monster>().Value.UnPack() : null;
+ break;
+ case MyGame.Example.AnyUniqueAliases.TS:
+ _o.AnyUnique.Value = this.AnyUnique<MyGame.Example.TestSimpleTableWithEnum>().HasValue ? this.AnyUnique<MyGame.Example.TestSimpleTableWithEnum>().Value.UnPack() : null;
+ break;
+ case MyGame.Example.AnyUniqueAliases.M2:
+ _o.AnyUnique.Value = this.AnyUnique<MyGame.Example2.Monster>().HasValue ? this.AnyUnique<MyGame.Example2.Monster>().Value.UnPack() : null;
+ break;
+ }
+ _o.AnyAmbiguous = new MyGame.Example.AnyAmbiguousAliasesUnion();
+ _o.AnyAmbiguous.Type = this.AnyAmbiguousType;
+ switch (this.AnyAmbiguousType) {
+ default: break;
+ case MyGame.Example.AnyAmbiguousAliases.M1:
+ _o.AnyAmbiguous.Value = this.AnyAmbiguous<MyGame.Example.Monster>().HasValue ? this.AnyAmbiguous<MyGame.Example.Monster>().Value.UnPack() : null;
+ break;
+ case MyGame.Example.AnyAmbiguousAliases.M2:
+ _o.AnyAmbiguous.Value = this.AnyAmbiguous<MyGame.Example.Monster>().HasValue ? this.AnyAmbiguous<MyGame.Example.Monster>().Value.UnPack() : null;
+ break;
+ case MyGame.Example.AnyAmbiguousAliases.M3:
+ _o.AnyAmbiguous.Value = this.AnyAmbiguous<MyGame.Example.Monster>().HasValue ? this.AnyAmbiguous<MyGame.Example.Monster>().Value.UnPack() : null;
+ break;
+ }
+ _o.VectorOfEnums = new List<MyGame.Example.Color>();
+ for (var _j = 0; _j < this.VectorOfEnumsLength; ++_j) {_o.VectorOfEnums.Add(this.VectorOfEnums(_j));}
+ _o.SignedEnum = this.SignedEnum;
+ }
+ public static Offset<MyGame.Example.Monster> Pack(FlatBufferBuilder builder, MonsterT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.Monster>);
+ var _name = _o.Name == null ? default(StringOffset) : builder.CreateString(_o.Name);
+ var _inventory = default(VectorOffset);
+ if (_o.Inventory != null) {
+ var __inventory = _o.Inventory.ToArray();
+ _inventory = CreateInventoryVector(builder, __inventory);
+ }
+ var _test_type = _o.Test == null ? MyGame.Example.Any.NONE : _o.Test.Type;
+ var _test = _o.Test == null ? 0 : MyGame.Example.AnyUnion.Pack(builder, _o.Test);
+ var _test4 = default(VectorOffset);
+ if (_o.Test4 != null) {
+ StartTest4Vector(builder, _o.Test4.Count);
+ for (var _j = _o.Test4.Count - 1; _j >= 0; --_j) { MyGame.Example.Test.Pack(builder, _o.Test4[_j]); }
+ _test4 = builder.EndVector();
+ }
+ var _testarrayofstring = default(VectorOffset);
+ if (_o.Testarrayofstring != null) {
+ var __testarrayofstring = new StringOffset[_o.Testarrayofstring.Count];
+ for (var _j = 0; _j < __testarrayofstring.Length; ++_j) { __testarrayofstring[_j] = builder.CreateString(_o.Testarrayofstring[_j]); }
+ _testarrayofstring = CreateTestarrayofstringVector(builder, __testarrayofstring);
+ }
+ var _testarrayoftables = default(VectorOffset);
+ if (_o.Testarrayoftables != null) {
+ var __testarrayoftables = new Offset<MyGame.Example.Monster>[_o.Testarrayoftables.Count];
+ for (var _j = 0; _j < __testarrayoftables.Length; ++_j) { __testarrayoftables[_j] = MyGame.Example.Monster.Pack(builder, _o.Testarrayoftables[_j]); }
+ _testarrayoftables = CreateTestarrayoftablesVector(builder, __testarrayoftables);
+ }
+ var _enemy = _o.Enemy == null ? default(Offset<MyGame.Example.Monster>) : MyGame.Example.Monster.Pack(builder, _o.Enemy);
+ var _testnestedflatbuffer = default(VectorOffset);
+ if (_o.Testnestedflatbuffer != null) {
+ var __testnestedflatbuffer = _o.Testnestedflatbuffer.ToArray();
+ _testnestedflatbuffer = CreateTestnestedflatbufferVector(builder, __testnestedflatbuffer);
+ }
+ var _testempty = _o.Testempty == null ? default(Offset<MyGame.Example.Stat>) : MyGame.Example.Stat.Pack(builder, _o.Testempty);
+ var _testarrayofbools = default(VectorOffset);
+ if (_o.Testarrayofbools != null) {
+ var __testarrayofbools = _o.Testarrayofbools.ToArray();
+ _testarrayofbools = CreateTestarrayofboolsVector(builder, __testarrayofbools);
+ }
+ var _testarrayofstring2 = default(VectorOffset);
+ if (_o.Testarrayofstring2 != null) {
+ var __testarrayofstring2 = new StringOffset[_o.Testarrayofstring2.Count];
+ for (var _j = 0; _j < __testarrayofstring2.Length; ++_j) { __testarrayofstring2[_j] = builder.CreateString(_o.Testarrayofstring2[_j]); }
+ _testarrayofstring2 = CreateTestarrayofstring2Vector(builder, __testarrayofstring2);
+ }
+ var _testarrayofsortedstruct = default(VectorOffset);
+ if (_o.Testarrayofsortedstruct != null) {
+ StartTestarrayofsortedstructVector(builder, _o.Testarrayofsortedstruct.Count);
+ for (var _j = _o.Testarrayofsortedstruct.Count - 1; _j >= 0; --_j) { MyGame.Example.Ability.Pack(builder, _o.Testarrayofsortedstruct[_j]); }
+ _testarrayofsortedstruct = builder.EndVector();
+ }
+ var _flex = default(VectorOffset);
+ if (_o.Flex != null) {
+ var __flex = _o.Flex.ToArray();
+ _flex = CreateFlexVector(builder, __flex);
+ }
+ var _test5 = default(VectorOffset);
+ if (_o.Test5 != null) {
+ StartTest5Vector(builder, _o.Test5.Count);
+ for (var _j = _o.Test5.Count - 1; _j >= 0; --_j) { MyGame.Example.Test.Pack(builder, _o.Test5[_j]); }
+ _test5 = builder.EndVector();
+ }
+ var _vector_of_longs = default(VectorOffset);
+ if (_o.VectorOfLongs != null) {
+ var __vector_of_longs = _o.VectorOfLongs.ToArray();
+ _vector_of_longs = CreateVectorOfLongsVector(builder, __vector_of_longs);
+ }
+ var _vector_of_doubles = default(VectorOffset);
+ if (_o.VectorOfDoubles != null) {
+ var __vector_of_doubles = _o.VectorOfDoubles.ToArray();
+ _vector_of_doubles = CreateVectorOfDoublesVector(builder, __vector_of_doubles);
+ }
+ var _parent_namespace_test = _o.ParentNamespaceTest == null ? default(Offset<MyGame.InParentNamespace>) : MyGame.InParentNamespace.Pack(builder, _o.ParentNamespaceTest);
+ var _vector_of_referrables = default(VectorOffset);
+ if (_o.VectorOfReferrables != null) {
+ var __vector_of_referrables = new Offset<MyGame.Example.Referrable>[_o.VectorOfReferrables.Count];
+ for (var _j = 0; _j < __vector_of_referrables.Length; ++_j) { __vector_of_referrables[_j] = MyGame.Example.Referrable.Pack(builder, _o.VectorOfReferrables[_j]); }
+ _vector_of_referrables = CreateVectorOfReferrablesVector(builder, __vector_of_referrables);
+ }
+ var _vector_of_weak_references = default(VectorOffset);
+ if (_o.VectorOfWeakReferences != null) {
+ var __vector_of_weak_references = _o.VectorOfWeakReferences.ToArray();
+ _vector_of_weak_references = CreateVectorOfWeakReferencesVector(builder, __vector_of_weak_references);
+ }
+ var _vector_of_strong_referrables = default(VectorOffset);
+ if (_o.VectorOfStrongReferrables != null) {
+ var __vector_of_strong_referrables = new Offset<MyGame.Example.Referrable>[_o.VectorOfStrongReferrables.Count];
+ for (var _j = 0; _j < __vector_of_strong_referrables.Length; ++_j) { __vector_of_strong_referrables[_j] = MyGame.Example.Referrable.Pack(builder, _o.VectorOfStrongReferrables[_j]); }
+ _vector_of_strong_referrables = CreateVectorOfStrongReferrablesVector(builder, __vector_of_strong_referrables);
+ }
+ var _vector_of_co_owning_references = default(VectorOffset);
+ if (_o.VectorOfCoOwningReferences != null) {
+ var __vector_of_co_owning_references = _o.VectorOfCoOwningReferences.ToArray();
+ _vector_of_co_owning_references = CreateVectorOfCoOwningReferencesVector(builder, __vector_of_co_owning_references);
+ }
+ var _vector_of_non_owning_references = default(VectorOffset);
+ if (_o.VectorOfNonOwningReferences != null) {
+ var __vector_of_non_owning_references = _o.VectorOfNonOwningReferences.ToArray();
+ _vector_of_non_owning_references = CreateVectorOfNonOwningReferencesVector(builder, __vector_of_non_owning_references);
+ }
+ var _any_unique_type = _o.AnyUnique == null ? MyGame.Example.AnyUniqueAliases.NONE : _o.AnyUnique.Type;
+ var _any_unique = _o.AnyUnique == null ? 0 : MyGame.Example.AnyUniqueAliasesUnion.Pack(builder, _o.AnyUnique);
+ var _any_ambiguous_type = _o.AnyAmbiguous == null ? MyGame.Example.AnyAmbiguousAliases.NONE : _o.AnyAmbiguous.Type;
+ var _any_ambiguous = _o.AnyAmbiguous == null ? 0 : MyGame.Example.AnyAmbiguousAliasesUnion.Pack(builder, _o.AnyAmbiguous);
+ var _vector_of_enums = default(VectorOffset);
+ if (_o.VectorOfEnums != null) {
+ var __vector_of_enums = _o.VectorOfEnums.ToArray();
+ _vector_of_enums = CreateVectorOfEnumsVector(builder, __vector_of_enums);
+ }
+ StartMonster(builder);
+ AddPos(builder, MyGame.Example.Vec3.Pack(builder, _o.Pos));
+ AddMana(builder, _o.Mana);
+ AddHp(builder, _o.Hp);
+ AddName(builder, _name);
+ AddInventory(builder, _inventory);
+ AddColor(builder, _o.Color);
+ AddTestType(builder, _test_type);
+ AddTest(builder, _test);
+ AddTest4(builder, _test4);
+ AddTestarrayofstring(builder, _testarrayofstring);
+ AddTestarrayoftables(builder, _testarrayoftables);
+ AddEnemy(builder, _enemy);
+ AddTestnestedflatbuffer(builder, _testnestedflatbuffer);
+ AddTestempty(builder, _testempty);
+ AddTestbool(builder, _o.Testbool);
+ AddTesthashs32Fnv1(builder, _o.Testhashs32Fnv1);
+ AddTesthashu32Fnv1(builder, _o.Testhashu32Fnv1);
+ AddTesthashs64Fnv1(builder, _o.Testhashs64Fnv1);
+ AddTesthashu64Fnv1(builder, _o.Testhashu64Fnv1);
+ AddTesthashs32Fnv1a(builder, _o.Testhashs32Fnv1a);
+ AddTesthashu32Fnv1a(builder, _o.Testhashu32Fnv1a);
+ AddTesthashs64Fnv1a(builder, _o.Testhashs64Fnv1a);
+ AddTesthashu64Fnv1a(builder, _o.Testhashu64Fnv1a);
+ AddTestarrayofbools(builder, _testarrayofbools);
+ AddTestf(builder, _o.Testf);
+ AddTestf2(builder, _o.Testf2);
+ AddTestf3(builder, _o.Testf3);
+ AddTestarrayofstring2(builder, _testarrayofstring2);
+ AddTestarrayofsortedstruct(builder, _testarrayofsortedstruct);
+ AddFlex(builder, _flex);
+ AddTest5(builder, _test5);
+ AddVectorOfLongs(builder, _vector_of_longs);
+ AddVectorOfDoubles(builder, _vector_of_doubles);
+ AddParentNamespaceTest(builder, _parent_namespace_test);
+ AddVectorOfReferrables(builder, _vector_of_referrables);
+ AddSingleWeakReference(builder, _o.SingleWeakReference);
+ AddVectorOfWeakReferences(builder, _vector_of_weak_references);
+ AddVectorOfStrongReferrables(builder, _vector_of_strong_referrables);
+ AddCoOwningReference(builder, _o.CoOwningReference);
+ AddVectorOfCoOwningReferences(builder, _vector_of_co_owning_references);
+ AddNonOwningReference(builder, _o.NonOwningReference);
+ AddVectorOfNonOwningReferences(builder, _vector_of_non_owning_references);
+ AddAnyUniqueType(builder, _any_unique_type);
+ AddAnyUnique(builder, _any_unique);
+ AddAnyAmbiguousType(builder, _any_ambiguous_type);
+ AddAnyAmbiguous(builder, _any_ambiguous);
+ AddVectorOfEnums(builder, _vector_of_enums);
+ AddSignedEnum(builder, _o.SignedEnum);
+ return EndMonster(builder);
+ }
};
+public class MonsterT
+{
+ [Newtonsoft.Json.JsonProperty("pos")]
+ public MyGame.Example.Vec3T Pos { get; set; }
+ [Newtonsoft.Json.JsonProperty("mana")]
+ public short Mana { get; set; }
+ [Newtonsoft.Json.JsonProperty("hp")]
+ public short Hp { get; set; }
+ [Newtonsoft.Json.JsonProperty("name")]
+ public string Name { get; set; }
+ [Newtonsoft.Json.JsonProperty("inventory")]
+ public List<byte> Inventory { get; set; }
+ [Newtonsoft.Json.JsonProperty("color")]
+ public MyGame.Example.Color Color { get; set; }
+ [Newtonsoft.Json.JsonProperty("test_type")]
+ private MyGame.Example.Any TestType {
+ get {
+ return this.Test != null ? this.Test.Type : MyGame.Example.Any.NONE;
+ }
+ set {
+ this.Test = new MyGame.Example.AnyUnion();
+ this.Test.Type = value;
+ }
+ }
+ [Newtonsoft.Json.JsonProperty("test")]
+ [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyUnion_JsonConverter))]
+ public MyGame.Example.AnyUnion Test { get; set; }
+ [Newtonsoft.Json.JsonProperty("test4")]
+ public List<MyGame.Example.TestT> Test4 { get; set; }
+ [Newtonsoft.Json.JsonProperty("testarrayofstring")]
+ public List<string> Testarrayofstring { get; set; }
+ [Newtonsoft.Json.JsonProperty("testarrayoftables")]
+ public List<MyGame.Example.MonsterT> Testarrayoftables { get; set; }
+ [Newtonsoft.Json.JsonProperty("enemy")]
+ public MyGame.Example.MonsterT Enemy { get; set; }
+ [Newtonsoft.Json.JsonProperty("testnestedflatbuffer")]
+ public List<byte> Testnestedflatbuffer { get; set; }
+ [Newtonsoft.Json.JsonProperty("testempty")]
+ public MyGame.Example.StatT Testempty { get; set; }
+ [Newtonsoft.Json.JsonProperty("testbool")]
+ public bool Testbool { get; set; }
+ [Newtonsoft.Json.JsonProperty("testhashs32_fnv1")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public int Testhashs32Fnv1 { get; set; }
+ [Newtonsoft.Json.JsonProperty("testhashu32_fnv1")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public uint Testhashu32Fnv1 { get; set; }
+ [Newtonsoft.Json.JsonProperty("testhashs64_fnv1")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public long Testhashs64Fnv1 { get; set; }
+ [Newtonsoft.Json.JsonProperty("testhashu64_fnv1")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public ulong Testhashu64Fnv1 { get; set; }
+ [Newtonsoft.Json.JsonProperty("testhashs32_fnv1a")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public int Testhashs32Fnv1a { get; set; }
+ [Newtonsoft.Json.JsonProperty("testhashu32_fnv1a")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public uint Testhashu32Fnv1a { get; set; }
+ [Newtonsoft.Json.JsonProperty("testhashs64_fnv1a")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public long Testhashs64Fnv1a { get; set; }
+ [Newtonsoft.Json.JsonProperty("testhashu64_fnv1a")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public ulong Testhashu64Fnv1a { get; set; }
+ [Newtonsoft.Json.JsonProperty("testarrayofbools")]
+ public List<bool> Testarrayofbools { get; set; }
+ [Newtonsoft.Json.JsonProperty("testf")]
+ public float Testf { get; set; }
+ [Newtonsoft.Json.JsonProperty("testf2")]
+ public float Testf2 { get; set; }
+ [Newtonsoft.Json.JsonProperty("testf3")]
+ public float Testf3 { get; set; }
+ [Newtonsoft.Json.JsonProperty("testarrayofstring2")]
+ public List<string> Testarrayofstring2 { get; set; }
+ [Newtonsoft.Json.JsonProperty("testarrayofsortedstruct")]
+ public List<MyGame.Example.AbilityT> Testarrayofsortedstruct { get; set; }
+ [Newtonsoft.Json.JsonProperty("flex")]
+ public List<byte> Flex { get; set; }
+ [Newtonsoft.Json.JsonProperty("test5")]
+ public List<MyGame.Example.TestT> Test5 { get; set; }
+ [Newtonsoft.Json.JsonProperty("vector_of_longs")]
+ public List<long> VectorOfLongs { get; set; }
+ [Newtonsoft.Json.JsonProperty("vector_of_doubles")]
+ public List<double> VectorOfDoubles { get; set; }
+ [Newtonsoft.Json.JsonProperty("parent_namespace_test")]
+ public MyGame.InParentNamespaceT ParentNamespaceTest { get; set; }
+ [Newtonsoft.Json.JsonProperty("vector_of_referrables")]
+ public List<MyGame.Example.ReferrableT> VectorOfReferrables { get; set; }
+ [Newtonsoft.Json.JsonProperty("single_weak_reference")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public ulong SingleWeakReference { get; set; }
+ [Newtonsoft.Json.JsonProperty("vector_of_weak_references")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public List<ulong> VectorOfWeakReferences { get; set; }
+ [Newtonsoft.Json.JsonProperty("vector_of_strong_referrables")]
+ public List<MyGame.Example.ReferrableT> VectorOfStrongReferrables { get; set; }
+ [Newtonsoft.Json.JsonProperty("co_owning_reference")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public ulong CoOwningReference { get; set; }
+ [Newtonsoft.Json.JsonProperty("vector_of_co_owning_references")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public List<ulong> VectorOfCoOwningReferences { get; set; }
+ [Newtonsoft.Json.JsonProperty("non_owning_reference")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public ulong NonOwningReference { get; set; }
+ [Newtonsoft.Json.JsonProperty("vector_of_non_owning_references")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public List<ulong> VectorOfNonOwningReferences { get; set; }
+ [Newtonsoft.Json.JsonProperty("any_unique_type")]
+ private MyGame.Example.AnyUniqueAliases AnyUniqueType {
+ get {
+ return this.AnyUnique != null ? this.AnyUnique.Type : MyGame.Example.AnyUniqueAliases.NONE;
+ }
+ set {
+ this.AnyUnique = new MyGame.Example.AnyUniqueAliasesUnion();
+ this.AnyUnique.Type = value;
+ }
+ }
+ [Newtonsoft.Json.JsonProperty("any_unique")]
+ [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyUniqueAliasesUnion_JsonConverter))]
+ public MyGame.Example.AnyUniqueAliasesUnion AnyUnique { get; set; }
+ [Newtonsoft.Json.JsonProperty("any_ambiguous_type")]
+ private MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType {
+ get {
+ return this.AnyAmbiguous != null ? this.AnyAmbiguous.Type : MyGame.Example.AnyAmbiguousAliases.NONE;
+ }
+ set {
+ this.AnyAmbiguous = new MyGame.Example.AnyAmbiguousAliasesUnion();
+ this.AnyAmbiguous.Type = value;
+ }
+ }
+ [Newtonsoft.Json.JsonProperty("any_ambiguous")]
+ [Newtonsoft.Json.JsonConverter(typeof(MyGame.Example.AnyAmbiguousAliasesUnion_JsonConverter))]
+ public MyGame.Example.AnyAmbiguousAliasesUnion AnyAmbiguous { get; set; }
+ [Newtonsoft.Json.JsonProperty("vector_of_enums")]
+ public List<MyGame.Example.Color> VectorOfEnums { get; set; }
+ [Newtonsoft.Json.JsonProperty("signed_enum")]
+ public MyGame.Example.Race SignedEnum { get; set; }
+
+ public MonsterT() {
+ this.Pos = new MyGame.Example.Vec3T();
+ this.Mana = 150;
+ this.Hp = 100;
+ this.Name = null;
+ this.Inventory = null;
+ this.Color = MyGame.Example.Color.Blue;
+ this.Test = null;
+ this.Test4 = null;
+ this.Testarrayofstring = null;
+ this.Testarrayoftables = null;
+ this.Enemy = null;
+ this.Testnestedflatbuffer = null;
+ this.Testempty = null;
+ this.Testbool = false;
+ this.Testhashs32Fnv1 = 0;
+ this.Testhashu32Fnv1 = 0;
+ this.Testhashs64Fnv1 = 0;
+ this.Testhashu64Fnv1 = 0;
+ this.Testhashs32Fnv1a = 0;
+ this.Testhashu32Fnv1a = 0;
+ this.Testhashs64Fnv1a = 0;
+ this.Testhashu64Fnv1a = 0;
+ this.Testarrayofbools = null;
+ this.Testf = 3.14159f;
+ this.Testf2 = 3.0f;
+ this.Testf3 = 0.0f;
+ this.Testarrayofstring2 = null;
+ this.Testarrayofsortedstruct = null;
+ this.Flex = null;
+ this.Test5 = null;
+ this.VectorOfLongs = null;
+ this.VectorOfDoubles = null;
+ this.ParentNamespaceTest = null;
+ this.VectorOfReferrables = null;
+ this.SingleWeakReference = 0;
+ this.VectorOfWeakReferences = null;
+ this.VectorOfStrongReferrables = null;
+ this.CoOwningReference = 0;
+ this.VectorOfCoOwningReferences = null;
+ this.NonOwningReference = 0;
+ this.VectorOfNonOwningReferences = null;
+ this.AnyUnique = null;
+ this.AnyAmbiguous = null;
+ this.VectorOfEnums = null;
+ this.SignedEnum = MyGame.Example.Race.None;
+ }
+
+ public static MonsterT DeserializeFromJson(string jsonText) {
+ return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterT>(jsonText);
+ }
+ public string SerializeToJson() {
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ }
+ public static MonsterT DeserializeFromBinary(byte[] fbBuffer) {
+ return Monster.GetRootAsMonster(new ByteBuffer(fbBuffer)).UnPack();
+ }
+ public byte[] SerializeToBinary() {
+ var fbb = new FlatBufferBuilder(0x10000);
+ fbb.Finish(Monster.Pack(fbb, this).Value);
+ return fbb.DataBuffer.ToSizedArray();
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Monster.go b/tests/MyGame/Example/Monster.go
index 1eedc5eb..7db88a9c 100644
--- a/tests/MyGame/Example/Monster.go
+++ b/tests/MyGame/Example/Monster.go
@@ -8,7 +8,429 @@ import (
MyGame "MyGame"
)
-/// an example documentation comment: monster object
+/// an example documentation comment: "monster object"
+type MonsterT struct {
+ Pos *Vec3T
+ Mana int16
+ Hp int16
+ Name string
+ Inventory []byte
+ Color Color
+ Test *AnyT
+ Test4 []*TestT
+ Testarrayofstring []string
+ Testarrayoftables []*MonsterT
+ Enemy *MonsterT
+ Testnestedflatbuffer []byte
+ Testempty *StatT
+ Testbool bool
+ Testhashs32Fnv1 int32
+ Testhashu32Fnv1 uint32
+ Testhashs64Fnv1 int64
+ Testhashu64Fnv1 uint64
+ Testhashs32Fnv1a int32
+ Testhashu32Fnv1a uint32
+ Testhashs64Fnv1a int64
+ Testhashu64Fnv1a uint64
+ Testarrayofbools []bool
+ Testf float32
+ Testf2 float32
+ Testf3 float32
+ Testarrayofstring2 []string
+ Testarrayofsortedstruct []*AbilityT
+ Flex []byte
+ Test5 []*TestT
+ VectorOfLongs []int64
+ VectorOfDoubles []float64
+ ParentNamespaceTest *MyGame.InParentNamespaceT
+ VectorOfReferrables []*ReferrableT
+ SingleWeakReference uint64
+ VectorOfWeakReferences []uint64
+ VectorOfStrongReferrables []*ReferrableT
+ CoOwningReference uint64
+ VectorOfCoOwningReferences []uint64
+ NonOwningReference uint64
+ VectorOfNonOwningReferences []uint64
+ AnyUnique *AnyUniqueAliasesT
+ AnyAmbiguous *AnyAmbiguousAliasesT
+ VectorOfEnums []Color
+ SignedEnum Race
+}
+
+func (t *MonsterT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ nameOffset := builder.CreateString(t.Name)
+ inventoryOffset := flatbuffers.UOffsetT(0)
+ if t.Inventory != nil {
+ inventoryOffset = builder.CreateByteString(t.Inventory)
+ }
+ testOffset := t.Test.Pack(builder)
+
+ test4Offset := flatbuffers.UOffsetT(0)
+ if t.Test4 != nil {
+ test4Length := len(t.Test4)
+ MonsterStartTest4Vector(builder, test4Length)
+ for j := test4Length - 1; j >= 0; j-- {
+ t.Test4[j].Pack(builder)
+ }
+ test4Offset = builder.EndVector(test4Length)
+ }
+ testarrayofstringOffset := flatbuffers.UOffsetT(0)
+ if t.Testarrayofstring != nil {
+ testarrayofstringLength := len(t.Testarrayofstring)
+ testarrayofstringOffsets := make([]flatbuffers.UOffsetT, testarrayofstringLength)
+ for j := 0; j < testarrayofstringLength; j++ {
+ testarrayofstringOffsets[j] = builder.CreateString(t.Testarrayofstring[j])
+ }
+ MonsterStartTestarrayofstringVector(builder, testarrayofstringLength)
+ for j := testarrayofstringLength - 1; j >= 0; j-- {
+ builder.PrependUOffsetT(testarrayofstringOffsets[j])
+ }
+ testarrayofstringOffset = builder.EndVector(testarrayofstringLength)
+ }
+ testarrayoftablesOffset := flatbuffers.UOffsetT(0)
+ if t.Testarrayoftables != nil {
+ testarrayoftablesLength := len(t.Testarrayoftables)
+ testarrayoftablesOffsets := make([]flatbuffers.UOffsetT, testarrayoftablesLength)
+ for j := 0; j < testarrayoftablesLength; j++ {
+ testarrayoftablesOffsets[j] = t.Testarrayoftables[j].Pack(builder)
+ }
+ MonsterStartTestarrayoftablesVector(builder, testarrayoftablesLength)
+ for j := testarrayoftablesLength - 1; j >= 0; j-- {
+ builder.PrependUOffsetT(testarrayoftablesOffsets[j])
+ }
+ testarrayoftablesOffset = builder.EndVector(testarrayoftablesLength)
+ }
+ enemyOffset := t.Enemy.Pack(builder)
+ testnestedflatbufferOffset := flatbuffers.UOffsetT(0)
+ if t.Testnestedflatbuffer != nil {
+ testnestedflatbufferOffset = builder.CreateByteString(t.Testnestedflatbuffer)
+ }
+ testemptyOffset := t.Testempty.Pack(builder)
+ testarrayofboolsOffset := flatbuffers.UOffsetT(0)
+ if t.Testarrayofbools != nil {
+ testarrayofboolsLength := len(t.Testarrayofbools)
+ MonsterStartTestarrayofboolsVector(builder, testarrayofboolsLength)
+ for j := testarrayofboolsLength - 1; j >= 0; j-- {
+ builder.PrependBool(t.Testarrayofbools[j])
+ }
+ testarrayofboolsOffset = builder.EndVector(testarrayofboolsLength)
+ }
+ testarrayofstring2Offset := flatbuffers.UOffsetT(0)
+ if t.Testarrayofstring2 != nil {
+ testarrayofstring2Length := len(t.Testarrayofstring2)
+ testarrayofstring2Offsets := make([]flatbuffers.UOffsetT, testarrayofstring2Length)
+ for j := 0; j < testarrayofstring2Length; j++ {
+ testarrayofstring2Offsets[j] = builder.CreateString(t.Testarrayofstring2[j])
+ }
+ MonsterStartTestarrayofstring2Vector(builder, testarrayofstring2Length)
+ for j := testarrayofstring2Length - 1; j >= 0; j-- {
+ builder.PrependUOffsetT(testarrayofstring2Offsets[j])
+ }
+ testarrayofstring2Offset = builder.EndVector(testarrayofstring2Length)
+ }
+ testarrayofsortedstructOffset := flatbuffers.UOffsetT(0)
+ if t.Testarrayofsortedstruct != nil {
+ testarrayofsortedstructLength := len(t.Testarrayofsortedstruct)
+ MonsterStartTestarrayofsortedstructVector(builder, testarrayofsortedstructLength)
+ for j := testarrayofsortedstructLength - 1; j >= 0; j-- {
+ t.Testarrayofsortedstruct[j].Pack(builder)
+ }
+ testarrayofsortedstructOffset = builder.EndVector(testarrayofsortedstructLength)
+ }
+ flexOffset := flatbuffers.UOffsetT(0)
+ if t.Flex != nil {
+ flexOffset = builder.CreateByteString(t.Flex)
+ }
+ test5Offset := flatbuffers.UOffsetT(0)
+ if t.Test5 != nil {
+ test5Length := len(t.Test5)
+ MonsterStartTest5Vector(builder, test5Length)
+ for j := test5Length - 1; j >= 0; j-- {
+ t.Test5[j].Pack(builder)
+ }
+ test5Offset = builder.EndVector(test5Length)
+ }
+ vectorOfLongsOffset := flatbuffers.UOffsetT(0)
+ if t.VectorOfLongs != nil {
+ vectorOfLongsLength := len(t.VectorOfLongs)
+ MonsterStartVectorOfLongsVector(builder, vectorOfLongsLength)
+ for j := vectorOfLongsLength - 1; j >= 0; j-- {
+ builder.PrependInt64(t.VectorOfLongs[j])
+ }
+ vectorOfLongsOffset = builder.EndVector(vectorOfLongsLength)
+ }
+ vectorOfDoublesOffset := flatbuffers.UOffsetT(0)
+ if t.VectorOfDoubles != nil {
+ vectorOfDoublesLength := len(t.VectorOfDoubles)
+ MonsterStartVectorOfDoublesVector(builder, vectorOfDoublesLength)
+ for j := vectorOfDoublesLength - 1; j >= 0; j-- {
+ builder.PrependFloat64(t.VectorOfDoubles[j])
+ }
+ vectorOfDoublesOffset = builder.EndVector(vectorOfDoublesLength)
+ }
+ parentNamespaceTestOffset := t.ParentNamespaceTest.Pack(builder)
+ vectorOfReferrablesOffset := flatbuffers.UOffsetT(0)
+ if t.VectorOfReferrables != nil {
+ vectorOfReferrablesLength := len(t.VectorOfReferrables)
+ vectorOfReferrablesOffsets := make([]flatbuffers.UOffsetT, vectorOfReferrablesLength)
+ for j := 0; j < vectorOfReferrablesLength; j++ {
+ vectorOfReferrablesOffsets[j] = t.VectorOfReferrables[j].Pack(builder)
+ }
+ MonsterStartVectorOfReferrablesVector(builder, vectorOfReferrablesLength)
+ for j := vectorOfReferrablesLength - 1; j >= 0; j-- {
+ builder.PrependUOffsetT(vectorOfReferrablesOffsets[j])
+ }
+ vectorOfReferrablesOffset = builder.EndVector(vectorOfReferrablesLength)
+ }
+ vectorOfWeakReferencesOffset := flatbuffers.UOffsetT(0)
+ if t.VectorOfWeakReferences != nil {
+ vectorOfWeakReferencesLength := len(t.VectorOfWeakReferences)
+ MonsterStartVectorOfWeakReferencesVector(builder, vectorOfWeakReferencesLength)
+ for j := vectorOfWeakReferencesLength - 1; j >= 0; j-- {
+ builder.PrependUint64(t.VectorOfWeakReferences[j])
+ }
+ vectorOfWeakReferencesOffset = builder.EndVector(vectorOfWeakReferencesLength)
+ }
+ vectorOfStrongReferrablesOffset := flatbuffers.UOffsetT(0)
+ if t.VectorOfStrongReferrables != nil {
+ vectorOfStrongReferrablesLength := len(t.VectorOfStrongReferrables)
+ vectorOfStrongReferrablesOffsets := make([]flatbuffers.UOffsetT, vectorOfStrongReferrablesLength)
+ for j := 0; j < vectorOfStrongReferrablesLength; j++ {
+ vectorOfStrongReferrablesOffsets[j] = t.VectorOfStrongReferrables[j].Pack(builder)
+ }
+ MonsterStartVectorOfStrongReferrablesVector(builder, vectorOfStrongReferrablesLength)
+ for j := vectorOfStrongReferrablesLength - 1; j >= 0; j-- {
+ builder.PrependUOffsetT(vectorOfStrongReferrablesOffsets[j])
+ }
+ vectorOfStrongReferrablesOffset = builder.EndVector(vectorOfStrongReferrablesLength)
+ }
+ vectorOfCoOwningReferencesOffset := flatbuffers.UOffsetT(0)
+ if t.VectorOfCoOwningReferences != nil {
+ vectorOfCoOwningReferencesLength := len(t.VectorOfCoOwningReferences)
+ MonsterStartVectorOfCoOwningReferencesVector(builder, vectorOfCoOwningReferencesLength)
+ for j := vectorOfCoOwningReferencesLength - 1; j >= 0; j-- {
+ builder.PrependUint64(t.VectorOfCoOwningReferences[j])
+ }
+ vectorOfCoOwningReferencesOffset = builder.EndVector(vectorOfCoOwningReferencesLength)
+ }
+ vectorOfNonOwningReferencesOffset := flatbuffers.UOffsetT(0)
+ if t.VectorOfNonOwningReferences != nil {
+ vectorOfNonOwningReferencesLength := len(t.VectorOfNonOwningReferences)
+ MonsterStartVectorOfNonOwningReferencesVector(builder, vectorOfNonOwningReferencesLength)
+ for j := vectorOfNonOwningReferencesLength - 1; j >= 0; j-- {
+ builder.PrependUint64(t.VectorOfNonOwningReferences[j])
+ }
+ vectorOfNonOwningReferencesOffset = builder.EndVector(vectorOfNonOwningReferencesLength)
+ }
+ anyUniqueOffset := t.AnyUnique.Pack(builder)
+
+ anyAmbiguousOffset := t.AnyAmbiguous.Pack(builder)
+
+ vectorOfEnumsOffset := flatbuffers.UOffsetT(0)
+ if t.VectorOfEnums != nil {
+ vectorOfEnumsLength := len(t.VectorOfEnums)
+ MonsterStartVectorOfEnumsVector(builder, vectorOfEnumsLength)
+ for j := vectorOfEnumsLength - 1; j >= 0; j-- {
+ builder.PrependByte(byte(t.VectorOfEnums[j]))
+ }
+ vectorOfEnumsOffset = builder.EndVector(vectorOfEnumsLength)
+ }
+ MonsterStart(builder)
+ posOffset := t.Pos.Pack(builder)
+ MonsterAddPos(builder, posOffset)
+ MonsterAddMana(builder, t.Mana)
+ MonsterAddHp(builder, t.Hp)
+ MonsterAddName(builder, nameOffset)
+ MonsterAddInventory(builder, inventoryOffset)
+ MonsterAddColor(builder, t.Color)
+ if t.Test != nil {
+ MonsterAddTestType(builder, t.Test.Type)
+ }
+ MonsterAddTest(builder, testOffset)
+ MonsterAddTest4(builder, test4Offset)
+ MonsterAddTestarrayofstring(builder, testarrayofstringOffset)
+ MonsterAddTestarrayoftables(builder, testarrayoftablesOffset)
+ MonsterAddEnemy(builder, enemyOffset)
+ MonsterAddTestnestedflatbuffer(builder, testnestedflatbufferOffset)
+ MonsterAddTestempty(builder, testemptyOffset)
+ MonsterAddTestbool(builder, t.Testbool)
+ MonsterAddTesthashs32Fnv1(builder, t.Testhashs32Fnv1)
+ MonsterAddTesthashu32Fnv1(builder, t.Testhashu32Fnv1)
+ MonsterAddTesthashs64Fnv1(builder, t.Testhashs64Fnv1)
+ MonsterAddTesthashu64Fnv1(builder, t.Testhashu64Fnv1)
+ MonsterAddTesthashs32Fnv1a(builder, t.Testhashs32Fnv1a)
+ MonsterAddTesthashu32Fnv1a(builder, t.Testhashu32Fnv1a)
+ MonsterAddTesthashs64Fnv1a(builder, t.Testhashs64Fnv1a)
+ MonsterAddTesthashu64Fnv1a(builder, t.Testhashu64Fnv1a)
+ MonsterAddTestarrayofbools(builder, testarrayofboolsOffset)
+ MonsterAddTestf(builder, t.Testf)
+ MonsterAddTestf2(builder, t.Testf2)
+ MonsterAddTestf3(builder, t.Testf3)
+ MonsterAddTestarrayofstring2(builder, testarrayofstring2Offset)
+ MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstructOffset)
+ MonsterAddFlex(builder, flexOffset)
+ MonsterAddTest5(builder, test5Offset)
+ MonsterAddVectorOfLongs(builder, vectorOfLongsOffset)
+ MonsterAddVectorOfDoubles(builder, vectorOfDoublesOffset)
+ MonsterAddParentNamespaceTest(builder, parentNamespaceTestOffset)
+ MonsterAddVectorOfReferrables(builder, vectorOfReferrablesOffset)
+ MonsterAddSingleWeakReference(builder, t.SingleWeakReference)
+ MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferencesOffset)
+ MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrablesOffset)
+ MonsterAddCoOwningReference(builder, t.CoOwningReference)
+ MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferencesOffset)
+ MonsterAddNonOwningReference(builder, t.NonOwningReference)
+ MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferencesOffset)
+ if t.AnyUnique != nil {
+ MonsterAddAnyUniqueType(builder, t.AnyUnique.Type)
+ }
+ MonsterAddAnyUnique(builder, anyUniqueOffset)
+ if t.AnyAmbiguous != nil {
+ MonsterAddAnyAmbiguousType(builder, t.AnyAmbiguous.Type)
+ }
+ MonsterAddAnyAmbiguous(builder, anyAmbiguousOffset)
+ MonsterAddVectorOfEnums(builder, vectorOfEnumsOffset)
+ MonsterAddSignedEnum(builder, t.SignedEnum)
+ return MonsterEnd(builder)
+}
+
+func (rcv *Monster) UnPackTo(t *MonsterT) {
+ t.Pos = rcv.Pos(nil).UnPack()
+ t.Mana = rcv.Mana()
+ t.Hp = rcv.Hp()
+ t.Name = string(rcv.Name())
+ t.Inventory = rcv.InventoryBytes()
+ t.Color = rcv.Color()
+ testTable := flatbuffers.Table{}
+ if rcv.Test(&testTable) {
+ t.Test = rcv.TestType().UnPack(testTable)
+ }
+ test4Length := rcv.Test4Length()
+ t.Test4 = make([]*TestT, test4Length)
+ for j := 0; j < test4Length; j++ {
+ x := Test{}
+ rcv.Test4(&x, j)
+ t.Test4[j] = x.UnPack()
+ }
+ testarrayofstringLength := rcv.TestarrayofstringLength()
+ t.Testarrayofstring = make([]string, testarrayofstringLength)
+ for j := 0; j < testarrayofstringLength; j++ {
+ t.Testarrayofstring[j] = string(rcv.Testarrayofstring(j))
+ }
+ testarrayoftablesLength := rcv.TestarrayoftablesLength()
+ t.Testarrayoftables = make([]*MonsterT, testarrayoftablesLength)
+ for j := 0; j < testarrayoftablesLength; j++ {
+ x := Monster{}
+ rcv.Testarrayoftables(&x, j)
+ t.Testarrayoftables[j] = x.UnPack()
+ }
+ t.Enemy = rcv.Enemy(nil).UnPack()
+ t.Testnestedflatbuffer = rcv.TestnestedflatbufferBytes()
+ t.Testempty = rcv.Testempty(nil).UnPack()
+ t.Testbool = rcv.Testbool()
+ t.Testhashs32Fnv1 = rcv.Testhashs32Fnv1()
+ t.Testhashu32Fnv1 = rcv.Testhashu32Fnv1()
+ t.Testhashs64Fnv1 = rcv.Testhashs64Fnv1()
+ t.Testhashu64Fnv1 = rcv.Testhashu64Fnv1()
+ t.Testhashs32Fnv1a = rcv.Testhashs32Fnv1a()
+ t.Testhashu32Fnv1a = rcv.Testhashu32Fnv1a()
+ t.Testhashs64Fnv1a = rcv.Testhashs64Fnv1a()
+ t.Testhashu64Fnv1a = rcv.Testhashu64Fnv1a()
+ testarrayofboolsLength := rcv.TestarrayofboolsLength()
+ t.Testarrayofbools = make([]bool, testarrayofboolsLength)
+ for j := 0; j < testarrayofboolsLength; j++ {
+ t.Testarrayofbools[j] = rcv.Testarrayofbools(j)
+ }
+ t.Testf = rcv.Testf()
+ t.Testf2 = rcv.Testf2()
+ t.Testf3 = rcv.Testf3()
+ testarrayofstring2Length := rcv.Testarrayofstring2Length()
+ t.Testarrayofstring2 = make([]string, testarrayofstring2Length)
+ for j := 0; j < testarrayofstring2Length; j++ {
+ t.Testarrayofstring2[j] = string(rcv.Testarrayofstring2(j))
+ }
+ testarrayofsortedstructLength := rcv.TestarrayofsortedstructLength()
+ t.Testarrayofsortedstruct = make([]*AbilityT, testarrayofsortedstructLength)
+ for j := 0; j < testarrayofsortedstructLength; j++ {
+ x := Ability{}
+ rcv.Testarrayofsortedstruct(&x, j)
+ t.Testarrayofsortedstruct[j] = x.UnPack()
+ }
+ t.Flex = rcv.FlexBytes()
+ test5Length := rcv.Test5Length()
+ t.Test5 = make([]*TestT, test5Length)
+ for j := 0; j < test5Length; j++ {
+ x := Test{}
+ rcv.Test5(&x, j)
+ t.Test5[j] = x.UnPack()
+ }
+ vectorOfLongsLength := rcv.VectorOfLongsLength()
+ t.VectorOfLongs = make([]int64, vectorOfLongsLength)
+ for j := 0; j < vectorOfLongsLength; j++ {
+ t.VectorOfLongs[j] = rcv.VectorOfLongs(j)
+ }
+ vectorOfDoublesLength := rcv.VectorOfDoublesLength()
+ t.VectorOfDoubles = make([]float64, vectorOfDoublesLength)
+ for j := 0; j < vectorOfDoublesLength; j++ {
+ t.VectorOfDoubles[j] = rcv.VectorOfDoubles(j)
+ }
+ t.ParentNamespaceTest = rcv.ParentNamespaceTest(nil).UnPack()
+ vectorOfReferrablesLength := rcv.VectorOfReferrablesLength()
+ t.VectorOfReferrables = make([]*ReferrableT, vectorOfReferrablesLength)
+ for j := 0; j < vectorOfReferrablesLength; j++ {
+ x := Referrable{}
+ rcv.VectorOfReferrables(&x, j)
+ t.VectorOfReferrables[j] = x.UnPack()
+ }
+ t.SingleWeakReference = rcv.SingleWeakReference()
+ vectorOfWeakReferencesLength := rcv.VectorOfWeakReferencesLength()
+ t.VectorOfWeakReferences = make([]uint64, vectorOfWeakReferencesLength)
+ for j := 0; j < vectorOfWeakReferencesLength; j++ {
+ t.VectorOfWeakReferences[j] = rcv.VectorOfWeakReferences(j)
+ }
+ vectorOfStrongReferrablesLength := rcv.VectorOfStrongReferrablesLength()
+ t.VectorOfStrongReferrables = make([]*ReferrableT, vectorOfStrongReferrablesLength)
+ for j := 0; j < vectorOfStrongReferrablesLength; j++ {
+ x := Referrable{}
+ rcv.VectorOfStrongReferrables(&x, j)
+ t.VectorOfStrongReferrables[j] = x.UnPack()
+ }
+ t.CoOwningReference = rcv.CoOwningReference()
+ vectorOfCoOwningReferencesLength := rcv.VectorOfCoOwningReferencesLength()
+ t.VectorOfCoOwningReferences = make([]uint64, vectorOfCoOwningReferencesLength)
+ for j := 0; j < vectorOfCoOwningReferencesLength; j++ {
+ t.VectorOfCoOwningReferences[j] = rcv.VectorOfCoOwningReferences(j)
+ }
+ t.NonOwningReference = rcv.NonOwningReference()
+ vectorOfNonOwningReferencesLength := rcv.VectorOfNonOwningReferencesLength()
+ t.VectorOfNonOwningReferences = make([]uint64, vectorOfNonOwningReferencesLength)
+ for j := 0; j < vectorOfNonOwningReferencesLength; j++ {
+ t.VectorOfNonOwningReferences[j] = rcv.VectorOfNonOwningReferences(j)
+ }
+ anyUniqueTable := flatbuffers.Table{}
+ if rcv.AnyUnique(&anyUniqueTable) {
+ t.AnyUnique = rcv.AnyUniqueType().UnPack(anyUniqueTable)
+ }
+ anyAmbiguousTable := flatbuffers.Table{}
+ if rcv.AnyAmbiguous(&anyAmbiguousTable) {
+ t.AnyAmbiguous = rcv.AnyAmbiguousType().UnPack(anyAmbiguousTable)
+ }
+ vectorOfEnumsLength := rcv.VectorOfEnumsLength()
+ t.VectorOfEnums = make([]Color, vectorOfEnumsLength)
+ for j := 0; j < vectorOfEnumsLength; j++ {
+ t.VectorOfEnums[j] = rcv.VectorOfEnums(j)
+ }
+ t.SignedEnum = rcv.SignedEnum()
+}
+
+func (rcv *Monster) UnPack() *MonsterT {
+ if rcv == nil { return nil }
+ t := &MonsterT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type Monster struct {
_tab flatbuffers.Table
}
@@ -111,25 +533,25 @@ func (rcv *Monster) MutateInventory(j int, n byte) bool {
func (rcv *Monster) Color() Color {
o := flatbuffers.UOffsetT(rcv._tab.Offset(16))
if o != 0 {
- return rcv._tab.GetInt8(o + rcv._tab.Pos)
+ return Color(rcv._tab.GetByte(o + rcv._tab.Pos))
}
return 8
}
func (rcv *Monster) MutateColor(n Color) bool {
- return rcv._tab.MutateInt8Slot(16, n)
+ return rcv._tab.MutateByteSlot(16, byte(n))
}
-func (rcv *Monster) TestType() byte {
+func (rcv *Monster) TestType() Any {
o := flatbuffers.UOffsetT(rcv._tab.Offset(18))
if o != 0 {
- return rcv._tab.GetByte(o + rcv._tab.Pos)
+ return Any(rcv._tab.GetByte(o + rcv._tab.Pos))
}
return 0
}
-func (rcv *Monster) MutateTestType(n byte) bool {
- return rcv._tab.MutateByteSlot(18, n)
+func (rcv *Monster) MutateTestType(n Any) bool {
+ return rcv._tab.MutateByteSlot(18, byte(n))
}
func (rcv *Monster) Test(obj *flatbuffers.Table) bool {
@@ -739,16 +1161,16 @@ func (rcv *Monster) MutateVectorOfNonOwningReferences(j int, n uint64) bool {
return false
}
-func (rcv *Monster) AnyUniqueType() byte {
+func (rcv *Monster) AnyUniqueType() AnyUniqueAliases {
o := flatbuffers.UOffsetT(rcv._tab.Offset(90))
if o != 0 {
- return rcv._tab.GetByte(o + rcv._tab.Pos)
+ return AnyUniqueAliases(rcv._tab.GetByte(o + rcv._tab.Pos))
}
return 0
}
-func (rcv *Monster) MutateAnyUniqueType(n byte) bool {
- return rcv._tab.MutateByteSlot(90, n)
+func (rcv *Monster) MutateAnyUniqueType(n AnyUniqueAliases) bool {
+ return rcv._tab.MutateByteSlot(90, byte(n))
}
func (rcv *Monster) AnyUnique(obj *flatbuffers.Table) bool {
@@ -760,16 +1182,16 @@ func (rcv *Monster) AnyUnique(obj *flatbuffers.Table) bool {
return false
}
-func (rcv *Monster) AnyAmbiguousType() byte {
+func (rcv *Monster) AnyAmbiguousType() AnyAmbiguousAliases {
o := flatbuffers.UOffsetT(rcv._tab.Offset(94))
if o != 0 {
- return rcv._tab.GetByte(o + rcv._tab.Pos)
+ return AnyAmbiguousAliases(rcv._tab.GetByte(o + rcv._tab.Pos))
}
return 0
}
-func (rcv *Monster) MutateAnyAmbiguousType(n byte) bool {
- return rcv._tab.MutateByteSlot(94, n)
+func (rcv *Monster) MutateAnyAmbiguousType(n AnyAmbiguousAliases) bool {
+ return rcv._tab.MutateByteSlot(94, byte(n))
}
func (rcv *Monster) AnyAmbiguous(obj *flatbuffers.Table) bool {
@@ -785,7 +1207,7 @@ func (rcv *Monster) VectorOfEnums(j int) Color {
o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
if o != 0 {
a := rcv._tab.Vector(o)
- return rcv._tab.GetInt8(a + flatbuffers.UOffsetT(j*1))
+ return Color(rcv._tab.GetByte(a + flatbuffers.UOffsetT(j*1)))
}
return 0
}
@@ -798,17 +1220,37 @@ func (rcv *Monster) VectorOfEnumsLength() int {
return 0
}
+func (rcv *Monster) VectorOfEnumsBytes() []byte {
+ o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
+ if o != 0 {
+ return rcv._tab.ByteVector(o + rcv._tab.Pos)
+ }
+ return nil
+}
+
func (rcv *Monster) MutateVectorOfEnums(j int, n Color) bool {
o := flatbuffers.UOffsetT(rcv._tab.Offset(98))
if o != 0 {
a := rcv._tab.Vector(o)
- return rcv._tab.MutateInt8(a+flatbuffers.UOffsetT(j*1), n)
+ return rcv._tab.MutateByte(a+flatbuffers.UOffsetT(j*1), byte(n))
}
return false
}
+func (rcv *Monster) SignedEnum() Race {
+ o := flatbuffers.UOffsetT(rcv._tab.Offset(100))
+ if o != 0 {
+ return Race(rcv._tab.GetInt8(o + rcv._tab.Pos))
+ }
+ return -1
+}
+
+func (rcv *Monster) MutateSignedEnum(n Race) bool {
+ return rcv._tab.MutateInt8Slot(100, int8(n))
+}
+
func MonsterStart(builder *flatbuffers.Builder) {
- builder.StartObject(48)
+ builder.StartObject(49)
}
func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) {
builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0)
@@ -828,11 +1270,11 @@ func MonsterAddInventory(builder *flatbuffers.Builder, inventory flatbuffers.UOf
func MonsterStartInventoryVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
return builder.StartVector(1, numElems, 1)
}
-func MonsterAddColor(builder *flatbuffers.Builder, color int8) {
- builder.PrependInt8Slot(6, color, 8)
+func MonsterAddColor(builder *flatbuffers.Builder, color Color) {
+ builder.PrependByteSlot(6, byte(color), 8)
}
-func MonsterAddTestType(builder *flatbuffers.Builder, testType byte) {
- builder.PrependByteSlot(7, testType, 0)
+func MonsterAddTestType(builder *flatbuffers.Builder, testType Any) {
+ builder.PrependByteSlot(7, byte(testType), 0)
}
func MonsterAddTest(builder *flatbuffers.Builder, test flatbuffers.UOffsetT) {
builder.PrependUOffsetTSlot(8, flatbuffers.UOffsetT(test), 0)
@@ -987,14 +1429,14 @@ func MonsterAddVectorOfNonOwningReferences(builder *flatbuffers.Builder, vectorO
func MonsterStartVectorOfNonOwningReferencesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
return builder.StartVector(8, numElems, 8)
}
-func MonsterAddAnyUniqueType(builder *flatbuffers.Builder, anyUniqueType byte) {
- builder.PrependByteSlot(43, anyUniqueType, 0)
+func MonsterAddAnyUniqueType(builder *flatbuffers.Builder, anyUniqueType AnyUniqueAliases) {
+ builder.PrependByteSlot(43, byte(anyUniqueType), 0)
}
func MonsterAddAnyUnique(builder *flatbuffers.Builder, anyUnique flatbuffers.UOffsetT) {
builder.PrependUOffsetTSlot(44, flatbuffers.UOffsetT(anyUnique), 0)
}
-func MonsterAddAnyAmbiguousType(builder *flatbuffers.Builder, anyAmbiguousType byte) {
- builder.PrependByteSlot(45, anyAmbiguousType, 0)
+func MonsterAddAnyAmbiguousType(builder *flatbuffers.Builder, anyAmbiguousType AnyAmbiguousAliases) {
+ builder.PrependByteSlot(45, byte(anyAmbiguousType), 0)
}
func MonsterAddAnyAmbiguous(builder *flatbuffers.Builder, anyAmbiguous flatbuffers.UOffsetT) {
builder.PrependUOffsetTSlot(46, flatbuffers.UOffsetT(anyAmbiguous), 0)
@@ -1005,6 +1447,9 @@ func MonsterAddVectorOfEnums(builder *flatbuffers.Builder, vectorOfEnums flatbuf
func MonsterStartVectorOfEnumsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
return builder.StartVector(1, numElems, 1)
}
+func MonsterAddSignedEnum(builder *flatbuffers.Builder, signedEnum Race) {
+ builder.PrependInt8Slot(48, int8(signedEnum), -1)
+}
func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
return builder.EndObject()
}
diff --git a/tests/MyGame/Example/Monster.java b/tests/MyGame/Example/Monster.java
index 848f9a7a..da461edf 100644
--- a/tests/MyGame/Example/Monster.java
+++ b/tests/MyGame/Example/Monster.java
@@ -9,17 +9,18 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
/**
- * an example documentation comment: monster object
+ * an example documentation comment: "monster object"
*/
public final class Monster extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public static boolean MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public Vec3 pos() { return pos(new Vec3()); }
- public Vec3 pos(Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
+ public MyGame.Example.Vec3 pos() { return pos(new MyGame.Example.Vec3()); }
+ public MyGame.Example.Vec3 pos(MyGame.Example.Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
public short mana() { int o = __offset(6); return o != 0 ? bb.getShort(o + bb_pos) : 150; }
public boolean mutateMana(short mana) { int o = __offset(6); if (o != 0) { bb.putShort(o + bb_pos, mana); return true; } else { return false; } }
public short hp() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 100; }
@@ -29,39 +30,48 @@ public final class Monster extends Table {
public ByteBuffer nameInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 10, 1); }
public int inventory(int j) { int o = __offset(14); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
public int inventoryLength() { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; }
+ public ByteVector inventoryVector() { return inventoryVector(new ByteVector()); }
+ public ByteVector inventoryVector(ByteVector obj) { int o = __offset(14); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer inventoryAsByteBuffer() { return __vector_as_bytebuffer(14, 1); }
public ByteBuffer inventoryInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 14, 1); }
public boolean mutateInventory(int j, int inventory) { int o = __offset(14); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)inventory); return true; } else { return false; } }
- public byte color() { int o = __offset(16); return o != 0 ? bb.get(o + bb_pos) : 8; }
- public boolean mutateColor(byte color) { int o = __offset(16); if (o != 0) { bb.put(o + bb_pos, color); return true; } else { return false; } }
+ public int color() { int o = __offset(16); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 8; }
+ public boolean mutateColor(int color) { int o = __offset(16); if (o != 0) { bb.put(o + bb_pos, (byte)color); return true; } else { return false; } }
public byte testType() { int o = __offset(18); return o != 0 ? bb.get(o + bb_pos) : 0; }
- public boolean mutateTestType(byte test_type) { int o = __offset(18); if (o != 0) { bb.put(o + bb_pos, test_type); return true; } else { return false; } }
- public Table test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o) : null; }
- public Test test4(int j) { return test4(new Test(), j); }
- public Test test4(Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
+ public Table test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o + bb_pos) : null; }
+ public MyGame.Example.Test test4(int j) { return test4(new MyGame.Example.Test(), j); }
+ public MyGame.Example.Test test4(MyGame.Example.Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
public int test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
+ public MyGame.Example.Test.Vector test4Vector() { return test4Vector(new MyGame.Example.Test.Vector()); }
+ public MyGame.Example.Test.Vector test4Vector(MyGame.Example.Test.Vector obj) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
public String testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
public int testarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
+ public StringVector testarrayofstringVector() { return testarrayofstringVector(new StringVector()); }
+ public StringVector testarrayofstringVector(StringVector obj) { int o = __offset(24); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
/**
* an example documentation comment: this will end up in the generated code
* multiline too
*/
- public Monster testarrayoftables(int j) { return testarrayoftables(new Monster(), j); }
- public Monster testarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+ public MyGame.Example.Monster testarrayoftables(int j) { return testarrayoftables(new MyGame.Example.Monster(), j); }
+ public MyGame.Example.Monster testarrayoftables(MyGame.Example.Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
- public Monster testarrayoftablesByKey(String key) { int o = __offset(26); return o != 0 ? Monster.__lookup_by_key(null, __vector(o), key, bb) : null; }
- public Monster testarrayoftablesByKey(Monster obj, String key) { int o = __offset(26); return o != 0 ? Monster.__lookup_by_key(obj, __vector(o), key, bb) : null; }
- public Monster enemy() { return enemy(new Monster()); }
- public Monster enemy(Monster obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+ public MyGame.Example.Monster testarrayoftablesByKey(String key) { int o = __offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(null, __vector(o), key, bb) : null; }
+ public MyGame.Example.Monster testarrayoftablesByKey(MyGame.Example.Monster obj, String key) { int o = __offset(26); return o != 0 ? MyGame.Example.Monster.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+ public MyGame.Example.Monster.Vector testarrayoftablesVector() { return testarrayoftablesVector(new MyGame.Example.Monster.Vector()); }
+ public MyGame.Example.Monster.Vector testarrayoftablesVector(MyGame.Example.Monster.Vector obj) { int o = __offset(26); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
+ public MyGame.Example.Monster enemy() { return enemy(new MyGame.Example.Monster()); }
+ public MyGame.Example.Monster enemy(MyGame.Example.Monster obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
public int testnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
public int testnestedflatbufferLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; }
+ public ByteVector testnestedflatbufferVector() { return testnestedflatbufferVector(new ByteVector()); }
+ public ByteVector testnestedflatbufferVector(ByteVector obj) { int o = __offset(30); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer testnestedflatbufferAsByteBuffer() { return __vector_as_bytebuffer(30, 1); }
public ByteBuffer testnestedflatbufferInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 30, 1); }
- public Monster testnestedflatbufferAsMonster() { return testnestedflatbufferAsMonster(new Monster()); }
- public Monster testnestedflatbufferAsMonster(Monster obj) { int o = __offset(30); return o != 0 ? obj.__assign(__indirect(__vector(o)), bb) : null; }
+ public MyGame.Example.Monster testnestedflatbufferAsMonster() { return testnestedflatbufferAsMonster(new MyGame.Example.Monster()); }
+ public MyGame.Example.Monster testnestedflatbufferAsMonster(MyGame.Example.Monster obj) { int o = __offset(30); return o != 0 ? obj.__assign(__indirect(__vector(o)), bb) : null; }
public boolean mutateTestnestedflatbuffer(int j, int testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)testnestedflatbuffer); return true; } else { return false; } }
- public Stat testempty() { return testempty(new Stat()); }
- public Stat testempty(Stat obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
+ public MyGame.Example.Stat testempty() { return testempty(new MyGame.Example.Stat()); }
+ public MyGame.Example.Stat testempty(MyGame.Example.Stat obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
public boolean testbool() { int o = __offset(34); return o != 0 ? 0!=bb.get(o + bb_pos) : false; }
public boolean mutateTestbool(boolean testbool) { int o = __offset(34); if (o != 0) { bb.put(o + bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
public int testhashs32Fnv1() { int o = __offset(36); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
@@ -82,6 +92,8 @@ public final class Monster extends Table {
public boolean mutateTesthashu64Fnv1a(long testhashu64_fnv1a) { int o = __offset(50); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
public boolean testarrayofbools(int j) { int o = __offset(52); return o != 0 ? 0!=bb.get(__vector(o) + j * 1) : false; }
public int testarrayofboolsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; }
+ public BooleanVector testarrayofboolsVector() { return testarrayofboolsVector(new BooleanVector()); }
+ public BooleanVector testarrayofboolsVector(BooleanVector obj) { int o = __offset(52); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer testarrayofboolsAsByteBuffer() { return __vector_as_bytebuffer(52, 1); }
public ByteBuffer testarrayofboolsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 52, 1); }
public boolean mutateTestarrayofbools(int j, boolean testarrayofbools) { int o = __offset(52); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
@@ -93,50 +105,70 @@ public final class Monster extends Table {
public boolean mutateTestf3(float testf3) { int o = __offset(58); if (o != 0) { bb.putFloat(o + bb_pos, testf3); return true; } else { return false; } }
public String testarrayofstring2(int j) { int o = __offset(60); return o != 0 ? __string(__vector(o) + j * 4) : null; }
public int testarrayofstring2Length() { int o = __offset(60); return o != 0 ? __vector_len(o) : 0; }
- public Ability testarrayofsortedstruct(int j) { return testarrayofsortedstruct(new Ability(), j); }
- public Ability testarrayofsortedstruct(Ability obj, int j) { int o = __offset(62); return o != 0 ? obj.__assign(__vector(o) + j * 8, bb) : null; }
+ public StringVector testarrayofstring2Vector() { return testarrayofstring2Vector(new StringVector()); }
+ public StringVector testarrayofstring2Vector(StringVector obj) { int o = __offset(60); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
+ public MyGame.Example.Ability testarrayofsortedstruct(int j) { return testarrayofsortedstruct(new MyGame.Example.Ability(), j); }
+ public MyGame.Example.Ability testarrayofsortedstruct(MyGame.Example.Ability obj, int j) { int o = __offset(62); return o != 0 ? obj.__assign(__vector(o) + j * 8, bb) : null; }
public int testarrayofsortedstructLength() { int o = __offset(62); return o != 0 ? __vector_len(o) : 0; }
+ public MyGame.Example.Ability.Vector testarrayofsortedstructVector() { return testarrayofsortedstructVector(new MyGame.Example.Ability.Vector()); }
+ public MyGame.Example.Ability.Vector testarrayofsortedstructVector(MyGame.Example.Ability.Vector obj) { int o = __offset(62); return o != 0 ? obj.__assign(__vector(o), 8, bb) : null; }
public int flex(int j) { int o = __offset(64); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
public int flexLength() { int o = __offset(64); return o != 0 ? __vector_len(o) : 0; }
+ public ByteVector flexVector() { return flexVector(new ByteVector()); }
+ public ByteVector flexVector(ByteVector obj) { int o = __offset(64); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer flexAsByteBuffer() { return __vector_as_bytebuffer(64, 1); }
public ByteBuffer flexInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 64, 1); }
public boolean mutateFlex(int j, int flex) { int o = __offset(64); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)flex); return true; } else { return false; } }
- public Test test5(int j) { return test5(new Test(), j); }
- public Test test5(Test obj, int j) { int o = __offset(66); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
+ public MyGame.Example.Test test5(int j) { return test5(new MyGame.Example.Test(), j); }
+ public MyGame.Example.Test test5(MyGame.Example.Test obj, int j) { int o = __offset(66); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
public int test5Length() { int o = __offset(66); return o != 0 ? __vector_len(o) : 0; }
+ public MyGame.Example.Test.Vector test5Vector() { return test5Vector(new MyGame.Example.Test.Vector()); }
+ public MyGame.Example.Test.Vector test5Vector(MyGame.Example.Test.Vector obj) { int o = __offset(66); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
public long vectorOfLongs(int j) { int o = __offset(68); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
public int vectorOfLongsLength() { int o = __offset(68); return o != 0 ? __vector_len(o) : 0; }
+ public LongVector vectorOfLongsVector() { return vectorOfLongsVector(new LongVector()); }
+ public LongVector vectorOfLongsVector(LongVector obj) { int o = __offset(68); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer vectorOfLongsAsByteBuffer() { return __vector_as_bytebuffer(68, 8); }
public ByteBuffer vectorOfLongsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 68, 8); }
public boolean mutateVectorOfLongs(int j, long vector_of_longs) { int o = __offset(68); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
public double vectorOfDoubles(int j) { int o = __offset(70); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
public int vectorOfDoublesLength() { int o = __offset(70); return o != 0 ? __vector_len(o) : 0; }
+ public DoubleVector vectorOfDoublesVector() { return vectorOfDoublesVector(new DoubleVector()); }
+ public DoubleVector vectorOfDoublesVector(DoubleVector obj) { int o = __offset(70); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer vectorOfDoublesAsByteBuffer() { return __vector_as_bytebuffer(70, 8); }
public ByteBuffer vectorOfDoublesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 70, 8); }
public boolean mutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __offset(70); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
public MyGame.InParentNamespace parentNamespaceTest() { return parentNamespaceTest(new MyGame.InParentNamespace()); }
public MyGame.InParentNamespace parentNamespaceTest(MyGame.InParentNamespace obj) { int o = __offset(72); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
- public Referrable vectorOfReferrables(int j) { return vectorOfReferrables(new Referrable(), j); }
- public Referrable vectorOfReferrables(Referrable obj, int j) { int o = __offset(74); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+ public MyGame.Example.Referrable vectorOfReferrables(int j) { return vectorOfReferrables(new MyGame.Example.Referrable(), j); }
+ public MyGame.Example.Referrable vectorOfReferrables(MyGame.Example.Referrable obj, int j) { int o = __offset(74); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
public int vectorOfReferrablesLength() { int o = __offset(74); return o != 0 ? __vector_len(o) : 0; }
- public Referrable vectorOfReferrablesByKey(long key) { int o = __offset(74); return o != 0 ? Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
- public Referrable vectorOfReferrablesByKey(Referrable obj, long key) { int o = __offset(74); return o != 0 ? Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+ public MyGame.Example.Referrable vectorOfReferrablesByKey(long key) { int o = __offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
+ public MyGame.Example.Referrable vectorOfReferrablesByKey(MyGame.Example.Referrable obj, long key) { int o = __offset(74); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+ public MyGame.Example.Referrable.Vector vectorOfReferrablesVector() { return vectorOfReferrablesVector(new MyGame.Example.Referrable.Vector()); }
+ public MyGame.Example.Referrable.Vector vectorOfReferrablesVector(MyGame.Example.Referrable.Vector obj) { int o = __offset(74); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
public long singleWeakReference() { int o = __offset(76); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
public boolean mutateSingleWeakReference(long single_weak_reference) { int o = __offset(76); if (o != 0) { bb.putLong(o + bb_pos, single_weak_reference); return true; } else { return false; } }
public long vectorOfWeakReferences(int j) { int o = __offset(78); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
public int vectorOfWeakReferencesLength() { int o = __offset(78); return o != 0 ? __vector_len(o) : 0; }
+ public LongVector vectorOfWeakReferencesVector() { return vectorOfWeakReferencesVector(new LongVector()); }
+ public LongVector vectorOfWeakReferencesVector(LongVector obj) { int o = __offset(78); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer vectorOfWeakReferencesAsByteBuffer() { return __vector_as_bytebuffer(78, 8); }
public ByteBuffer vectorOfWeakReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 78, 8); }
public boolean mutateVectorOfWeakReferences(int j, long vector_of_weak_references) { int o = __offset(78); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_weak_references); return true; } else { return false; } }
- public Referrable vectorOfStrongReferrables(int j) { return vectorOfStrongReferrables(new Referrable(), j); }
- public Referrable vectorOfStrongReferrables(Referrable obj, int j) { int o = __offset(80); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
+ public MyGame.Example.Referrable vectorOfStrongReferrables(int j) { return vectorOfStrongReferrables(new MyGame.Example.Referrable(), j); }
+ public MyGame.Example.Referrable vectorOfStrongReferrables(MyGame.Example.Referrable obj, int j) { int o = __offset(80); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
public int vectorOfStrongReferrablesLength() { int o = __offset(80); return o != 0 ? __vector_len(o) : 0; }
- public Referrable vectorOfStrongReferrablesByKey(long key) { int o = __offset(80); return o != 0 ? Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
- public Referrable vectorOfStrongReferrablesByKey(Referrable obj, long key) { int o = __offset(80); return o != 0 ? Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+ public MyGame.Example.Referrable vectorOfStrongReferrablesByKey(long key) { int o = __offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb) : null; }
+ public MyGame.Example.Referrable vectorOfStrongReferrablesByKey(MyGame.Example.Referrable obj, long key) { int o = __offset(80); return o != 0 ? MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb) : null; }
+ public MyGame.Example.Referrable.Vector vectorOfStrongReferrablesVector() { return vectorOfStrongReferrablesVector(new MyGame.Example.Referrable.Vector()); }
+ public MyGame.Example.Referrable.Vector vectorOfStrongReferrablesVector(MyGame.Example.Referrable.Vector obj) { int o = __offset(80); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
public long coOwningReference() { int o = __offset(82); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
public boolean mutateCoOwningReference(long co_owning_reference) { int o = __offset(82); if (o != 0) { bb.putLong(o + bb_pos, co_owning_reference); return true; } else { return false; } }
public long vectorOfCoOwningReferences(int j) { int o = __offset(84); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
public int vectorOfCoOwningReferencesLength() { int o = __offset(84); return o != 0 ? __vector_len(o) : 0; }
+ public LongVector vectorOfCoOwningReferencesVector() { return vectorOfCoOwningReferencesVector(new LongVector()); }
+ public LongVector vectorOfCoOwningReferencesVector(LongVector obj) { int o = __offset(84); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer vectorOfCoOwningReferencesAsByteBuffer() { return __vector_as_bytebuffer(84, 8); }
public ByteBuffer vectorOfCoOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 84, 8); }
public boolean mutateVectorOfCoOwningReferences(int j, long vector_of_co_owning_references) { int o = __offset(84); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_co_owning_references); return true; } else { return false; } }
@@ -144,30 +176,35 @@ public final class Monster extends Table {
public boolean mutateNonOwningReference(long non_owning_reference) { int o = __offset(86); if (o != 0) { bb.putLong(o + bb_pos, non_owning_reference); return true; } else { return false; } }
public long vectorOfNonOwningReferences(int j) { int o = __offset(88); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
public int vectorOfNonOwningReferencesLength() { int o = __offset(88); return o != 0 ? __vector_len(o) : 0; }
+ public LongVector vectorOfNonOwningReferencesVector() { return vectorOfNonOwningReferencesVector(new LongVector()); }
+ public LongVector vectorOfNonOwningReferencesVector(LongVector obj) { int o = __offset(88); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer vectorOfNonOwningReferencesAsByteBuffer() { return __vector_as_bytebuffer(88, 8); }
public ByteBuffer vectorOfNonOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 88, 8); }
public boolean mutateVectorOfNonOwningReferences(int j, long vector_of_non_owning_references) { int o = __offset(88); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
public byte anyUniqueType() { int o = __offset(90); return o != 0 ? bb.get(o + bb_pos) : 0; }
- public boolean mutateAnyUniqueType(byte any_unique_type) { int o = __offset(90); if (o != 0) { bb.put(o + bb_pos, any_unique_type); return true; } else { return false; } }
- public Table anyUnique(Table obj) { int o = __offset(92); return o != 0 ? __union(obj, o) : null; }
+ public Table anyUnique(Table obj) { int o = __offset(92); return o != 0 ? __union(obj, o + bb_pos) : null; }
public byte anyAmbiguousType() { int o = __offset(94); return o != 0 ? bb.get(o + bb_pos) : 0; }
- public boolean mutateAnyAmbiguousType(byte any_ambiguous_type) { int o = __offset(94); if (o != 0) { bb.put(o + bb_pos, any_ambiguous_type); return true; } else { return false; } }
- public Table anyAmbiguous(Table obj) { int o = __offset(96); return o != 0 ? __union(obj, o) : null; }
- public byte vectorOfEnums(int j) { int o = __offset(98); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
+ public Table anyAmbiguous(Table obj) { int o = __offset(96); return o != 0 ? __union(obj, o + bb_pos) : null; }
+ public int vectorOfEnums(int j) { int o = __offset(98); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
public int vectorOfEnumsLength() { int o = __offset(98); return o != 0 ? __vector_len(o) : 0; }
+ public ByteVector vectorOfEnumsVector() { return vectorOfEnumsVector(new ByteVector()); }
+ public ByteVector vectorOfEnumsVector(ByteVector obj) { int o = __offset(98); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer vectorOfEnumsAsByteBuffer() { return __vector_as_bytebuffer(98, 1); }
public ByteBuffer vectorOfEnumsInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 98, 1); }
- public boolean mutateVectorOfEnums(int j, byte vector_of_enums) { int o = __offset(98); if (o != 0) { bb.put(__vector(o) + j * 1, vector_of_enums); return true; } else { return false; } }
+ public boolean mutateVectorOfEnums(int j, int vector_of_enums) { int o = __offset(98); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)vector_of_enums); return true; } else { return false; } }
+ public byte signedEnum() { int o = __offset(100); return o != 0 ? bb.get(o + bb_pos) : -1; }
+ public boolean mutateSignedEnum(byte signed_enum) { int o = __offset(100); if (o != 0) { bb.put(o + bb_pos, signed_enum); return true; } else { return false; } }
- public static void startMonster(FlatBufferBuilder builder) { builder.startObject(48); }
+ public static void startMonster(FlatBufferBuilder builder) { builder.startTable(49); }
public static void addPos(FlatBufferBuilder builder, int posOffset) { builder.addStruct(0, posOffset, 0); }
public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(3, nameOffset, 0); }
public static void addInventory(FlatBufferBuilder builder, int inventoryOffset) { builder.addOffset(5, inventoryOffset, 0); }
- public static int 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 int createInventoryVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
+ public static int createInventoryVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
public static void startInventoryVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
- public static void addColor(FlatBufferBuilder builder, byte color) { builder.addByte(6, color, 8); }
+ public static void addColor(FlatBufferBuilder builder, int color) { builder.addByte(6, (byte)color, (byte)8); }
public static void addTestType(FlatBufferBuilder builder, byte testType) { builder.addByte(7, testType, 0); }
public static void addTest(FlatBufferBuilder builder, int testOffset) { builder.addOffset(8, testOffset, 0); }
public static void addTest4(FlatBufferBuilder builder, int test4Offset) { builder.addOffset(9, test4Offset, 0); }
@@ -180,7 +217,8 @@ public final class Monster extends Table {
public static void startTestarrayoftablesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static void addEnemy(FlatBufferBuilder builder, int enemyOffset) { builder.addOffset(12, enemyOffset, 0); }
public static void addTestnestedflatbuffer(FlatBufferBuilder builder, int testnestedflatbufferOffset) { builder.addOffset(13, testnestedflatbufferOffset, 0); }
- public static int 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 int createTestnestedflatbufferVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
+ public static int createTestnestedflatbufferVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
public static void startTestnestedflatbufferVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
public static void addTestempty(FlatBufferBuilder builder, int testemptyOffset) { builder.addOffset(14, testemptyOffset, 0); }
public static void addTestbool(FlatBufferBuilder builder, boolean testbool) { builder.addBoolean(15, testbool, false); }
@@ -204,7 +242,8 @@ public final class Monster extends Table {
public static void addTestarrayofsortedstruct(FlatBufferBuilder builder, int testarrayofsortedstructOffset) { builder.addOffset(29, testarrayofsortedstructOffset, 0); }
public static void startTestarrayofsortedstructVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 4); }
public static void addFlex(FlatBufferBuilder builder, int flexOffset) { builder.addOffset(30, flexOffset, 0); }
- public static int 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 int createFlexVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
+ public static int createFlexVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
public static void startFlexVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
public static void addTest5(FlatBufferBuilder builder, int test5Offset) { builder.addOffset(31, test5Offset, 0); }
public static void startTest5Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
@@ -238,10 +277,12 @@ public final class Monster extends Table {
public static void addAnyAmbiguousType(FlatBufferBuilder builder, byte anyAmbiguousType) { builder.addByte(45, anyAmbiguousType, 0); }
public static void addAnyAmbiguous(FlatBufferBuilder builder, int anyAmbiguousOffset) { builder.addOffset(46, anyAmbiguousOffset, 0); }
public static void addVectorOfEnums(FlatBufferBuilder builder, int vectorOfEnumsOffset) { builder.addOffset(47, vectorOfEnumsOffset, 0); }
- public static int createVectorOfEnumsVector(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 int createVectorOfEnumsVector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
+ public static int createVectorOfEnumsVector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
public static void startVectorOfEnumsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
+ public static void addSignedEnum(FlatBufferBuilder builder, byte signedEnum) { builder.addByte(48, signedEnum, -1); }
public static int endMonster(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
builder.required(o, 10); // name
return o;
}
@@ -252,7 +293,7 @@ public final class Monster extends Table {
protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb); }
public static Monster __lookup_by_key(Monster obj, int vectorLocation, String key, ByteBuffer bb) {
- byte[] byteKey = key.getBytes(Table.UTF8_CHARSET.get());
+ byte[] byteKey = key.getBytes(java.nio.charset.StandardCharsets.UTF_8);
int span = bb.getInt(vectorLocation - 4);
int start = 0;
while (span != 0) {
@@ -271,5 +312,14 @@ public final class Monster extends Table {
}
return null;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Monster get(int j) { return get(new Monster(), j); }
+ public Monster get(Monster obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ public Monster getByKey(String key) { return __lookup_by_key(null, __vector(), key, bb); }
+ public Monster getByKey(Monster obj, String key) { return __lookup_by_key(obj, __vector(), key, bb); }
+ }
}
diff --git a/tests/MyGame/Example/Monster.kt b/tests/MyGame/Example/Monster.kt
new file mode 100644
index 00000000..90f6c438
--- /dev/null
+++ b/tests/MyGame/Example/Monster.kt
@@ -0,0 +1,989 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+/**
+ * an example documentation comment: "monster object"
+ */
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Monster : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Monster {
+ __init(_i, _bb)
+ return this
+ }
+ val pos : MyGame.Example.Vec3? get() = pos(MyGame.Example.Vec3())
+ fun pos(obj: MyGame.Example.Vec3) : MyGame.Example.Vec3? {
+ val o = __offset(4)
+ return if (o != 0) {
+ obj.__assign(o + bb_pos, bb)
+ } else {
+ null
+ }
+ }
+ val mana : Short
+ get() {
+ val o = __offset(6)
+ return if(o != 0) bb.getShort(o + bb_pos) else 150
+ }
+ fun mutateMana(mana: Short) : Boolean {
+ val o = __offset(6)
+ return if (o != 0) {
+ bb.putShort(o + bb_pos, mana)
+ true
+ } else {
+ false
+ }
+ }
+ val hp : Short
+ get() {
+ val o = __offset(8)
+ return if(o != 0) bb.getShort(o + bb_pos) else 100
+ }
+ fun mutateHp(hp: Short) : Boolean {
+ val o = __offset(8)
+ return if (o != 0) {
+ bb.putShort(o + bb_pos, hp)
+ true
+ } else {
+ false
+ }
+ }
+ val name : String?
+ get() {
+ val o = __offset(10)
+ return if (o != 0) __string(o + bb_pos) else null
+ }
+ val nameAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(10, 1)
+ fun nameInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 10, 1)
+ fun inventory(j: Int) : UByte {
+ val o = __offset(14)
+ return if (o != 0) {
+ bb.get(__vector(o) + j * 1).toUByte()
+ } else {
+ 0u
+ }
+ }
+ val inventoryLength : Int
+ get() {
+ val o = __offset(14); return if (o != 0) __vector_len(o) else 0
+ }
+ val inventoryAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(14, 1)
+ fun inventoryInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 14, 1)
+ fun mutateInventory(j: Int, inventory: UByte) : Boolean {
+ val o = __offset(14)
+ return if (o != 0) {
+ bb.put(__vector(o) + j * 1, inventory.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ val color : UByte
+ get() {
+ val o = __offset(16)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 8u
+ }
+ fun mutateColor(color: UByte) : Boolean {
+ val o = __offset(16)
+ return if (o != 0) {
+ bb.put(o + bb_pos, color.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ val testType : UByte
+ get() {
+ val o = __offset(18)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+ }
+ fun mutateTestType(testType: UByte) : Boolean {
+ val o = __offset(18)
+ return if (o != 0) {
+ bb.put(o + bb_pos, testType.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ fun test(obj: Table) : Table? {
+ val o = __offset(20); return if (o != 0) __union(obj, o + bb_pos) else null
+ }
+ fun test4(j: Int) : MyGame.Example.Test? = test4(MyGame.Example.Test(), j)
+ fun test4(obj: MyGame.Example.Test, j: Int) : MyGame.Example.Test? {
+ val o = __offset(22)
+ return if (o != 0) {
+ obj.__assign(__vector(o) + j * 4, bb)
+ } else {
+ null
+ }
+ }
+ val test4Length : Int
+ get() {
+ val o = __offset(22); return if (o != 0) __vector_len(o) else 0
+ }
+ fun testarrayofstring(j: Int) : String? {
+ val o = __offset(24)
+ return if (o != 0) {
+ __string(__vector(o) + j * 4)
+ } else {
+ null
+ }
+ }
+ val testarrayofstringLength : Int
+ get() {
+ val o = __offset(24); return if (o != 0) __vector_len(o) else 0
+ }
+ /**
+ * an example documentation comment: this will end up in the generated code
+ * multiline too
+ */
+ fun testarrayoftables(j: Int) : MyGame.Example.Monster? = testarrayoftables(MyGame.Example.Monster(), j)
+ fun testarrayoftables(obj: MyGame.Example.Monster, j: Int) : MyGame.Example.Monster? {
+ val o = __offset(26)
+ return if (o != 0) {
+ obj.__assign(__indirect(__vector(o) + j * 4), bb)
+ } else {
+ null
+ }
+ }
+ val testarrayoftablesLength : Int
+ get() {
+ val o = __offset(26); return if (o != 0) __vector_len(o) else 0
+ }
+ fun testarrayoftablesByKey(key: String) : MyGame.Example.Monster? {
+ val o = __offset(26)
+ return if (o != 0) {
+ MyGame.Example.Monster.__lookup_by_key(null, __vector(o), key, bb)
+ } else {
+ null
+ }
+ }
+ fun testarrayoftablesByKey(obj: MyGame.Example.Monster, key: String) : MyGame.Example.Monster? {
+ val o = __offset(26)
+ return if (o != 0) {
+ MyGame.Example.Monster.__lookup_by_key(obj, __vector(o), key, bb)
+ } else {
+ null
+ }
+ }
+ val enemy : MyGame.Example.Monster? get() = enemy(MyGame.Example.Monster())
+ fun enemy(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
+ val o = __offset(28)
+ return if (o != 0) {
+ obj.__assign(__indirect(o + bb_pos), bb)
+ } else {
+ null
+ }
+ }
+ fun testnestedflatbuffer(j: Int) : UByte {
+ val o = __offset(30)
+ return if (o != 0) {
+ bb.get(__vector(o) + j * 1).toUByte()
+ } else {
+ 0u
+ }
+ }
+ val testnestedflatbufferLength : Int
+ get() {
+ val o = __offset(30); return if (o != 0) __vector_len(o) else 0
+ }
+ val testnestedflatbufferAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(30, 1)
+ fun testnestedflatbufferInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 30, 1)
+ val testnestedflatbufferAsMonster : MyGame.Example.Monster? get() = testnestedflatbufferAsMonster(MyGame.Example.Monster())
+ fun testnestedflatbufferAsMonster(obj: MyGame.Example.Monster) : MyGame.Example.Monster? {
+ val o = __offset(30)
+ return if (o != 0) {
+ obj.__assign(__indirect(__vector(o)), bb)
+ } else {
+ null
+ }
+ }
+ fun mutateTestnestedflatbuffer(j: Int, testnestedflatbuffer: UByte) : Boolean {
+ val o = __offset(30)
+ return if (o != 0) {
+ bb.put(__vector(o) + j * 1, testnestedflatbuffer.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ val testempty : MyGame.Example.Stat? get() = testempty(MyGame.Example.Stat())
+ fun testempty(obj: MyGame.Example.Stat) : MyGame.Example.Stat? {
+ val o = __offset(32)
+ return if (o != 0) {
+ obj.__assign(__indirect(o + bb_pos), bb)
+ } else {
+ null
+ }
+ }
+ val testbool : Boolean
+ get() {
+ val o = __offset(34)
+ return if(o != 0) 0.toByte() != bb.get(o + bb_pos) else false
+ }
+ fun mutateTestbool(testbool: Boolean) : Boolean {
+ val o = __offset(34)
+ return if (o != 0) {
+ bb.put(o + bb_pos, (if(testbool) 1 else 0).toByte())
+ true
+ } else {
+ false
+ }
+ }
+ val testhashs32Fnv1 : Int
+ get() {
+ val o = __offset(36)
+ return if(o != 0) bb.getInt(o + bb_pos) else 0
+ }
+ fun mutateTesthashs32Fnv1(testhashs32Fnv1: Int) : Boolean {
+ val o = __offset(36)
+ return if (o != 0) {
+ bb.putInt(o + bb_pos, testhashs32Fnv1)
+ true
+ } else {
+ false
+ }
+ }
+ val testhashu32Fnv1 : UInt
+ get() {
+ val o = __offset(38)
+ return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+ }
+ fun mutateTesthashu32Fnv1(testhashu32Fnv1: UInt) : Boolean {
+ val o = __offset(38)
+ return if (o != 0) {
+ bb.putInt(o + bb_pos, testhashu32Fnv1.toInt())
+ true
+ } else {
+ false
+ }
+ }
+ val testhashs64Fnv1 : Long
+ get() {
+ val o = __offset(40)
+ return if(o != 0) bb.getLong(o + bb_pos) else 0L
+ }
+ fun mutateTesthashs64Fnv1(testhashs64Fnv1: Long) : Boolean {
+ val o = __offset(40)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, testhashs64Fnv1)
+ true
+ } else {
+ false
+ }
+ }
+ val testhashu64Fnv1 : ULong
+ get() {
+ val o = __offset(42)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+ }
+ fun mutateTesthashu64Fnv1(testhashu64Fnv1: ULong) : Boolean {
+ val o = __offset(42)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, testhashu64Fnv1.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ val testhashs32Fnv1a : Int
+ get() {
+ val o = __offset(44)
+ return if(o != 0) bb.getInt(o + bb_pos) else 0
+ }
+ fun mutateTesthashs32Fnv1a(testhashs32Fnv1a: Int) : Boolean {
+ val o = __offset(44)
+ return if (o != 0) {
+ bb.putInt(o + bb_pos, testhashs32Fnv1a)
+ true
+ } else {
+ false
+ }
+ }
+ val testhashu32Fnv1a : UInt
+ get() {
+ val o = __offset(46)
+ return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+ }
+ fun mutateTesthashu32Fnv1a(testhashu32Fnv1a: UInt) : Boolean {
+ val o = __offset(46)
+ return if (o != 0) {
+ bb.putInt(o + bb_pos, testhashu32Fnv1a.toInt())
+ true
+ } else {
+ false
+ }
+ }
+ val testhashs64Fnv1a : Long
+ get() {
+ val o = __offset(48)
+ return if(o != 0) bb.getLong(o + bb_pos) else 0L
+ }
+ fun mutateTesthashs64Fnv1a(testhashs64Fnv1a: Long) : Boolean {
+ val o = __offset(48)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, testhashs64Fnv1a)
+ true
+ } else {
+ false
+ }
+ }
+ val testhashu64Fnv1a : ULong
+ get() {
+ val o = __offset(50)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+ }
+ fun mutateTesthashu64Fnv1a(testhashu64Fnv1a: ULong) : Boolean {
+ val o = __offset(50)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, testhashu64Fnv1a.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ fun testarrayofbools(j: Int) : Boolean {
+ val o = __offset(52)
+ return if (o != 0) {
+ 0.toByte() != bb.get(__vector(o) + j * 1)
+ } else {
+ false
+ }
+ }
+ val testarrayofboolsLength : Int
+ get() {
+ val o = __offset(52); return if (o != 0) __vector_len(o) else 0
+ }
+ val testarrayofboolsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(52, 1)
+ fun testarrayofboolsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 52, 1)
+ fun mutateTestarrayofbools(j: Int, testarrayofbools: Boolean) : Boolean {
+ val o = __offset(52)
+ return if (o != 0) {
+ bb.put(__vector(o) + j * 1, (if(testarrayofbools) 1 else 0).toByte())
+ true
+ } else {
+ false
+ }
+ }
+ val testf : Float
+ get() {
+ val o = __offset(54)
+ return if(o != 0) bb.getFloat(o + bb_pos) else 3.14159f
+ }
+ fun mutateTestf(testf: Float) : Boolean {
+ val o = __offset(54)
+ return if (o != 0) {
+ bb.putFloat(o + bb_pos, testf)
+ true
+ } else {
+ false
+ }
+ }
+ val testf2 : Float
+ get() {
+ val o = __offset(56)
+ return if(o != 0) bb.getFloat(o + bb_pos) else 3.0f
+ }
+ fun mutateTestf2(testf2: Float) : Boolean {
+ val o = __offset(56)
+ return if (o != 0) {
+ bb.putFloat(o + bb_pos, testf2)
+ true
+ } else {
+ false
+ }
+ }
+ val testf3 : Float
+ get() {
+ val o = __offset(58)
+ return if(o != 0) bb.getFloat(o + bb_pos) else 0.0f
+ }
+ fun mutateTestf3(testf3: Float) : Boolean {
+ val o = __offset(58)
+ return if (o != 0) {
+ bb.putFloat(o + bb_pos, testf3)
+ true
+ } else {
+ false
+ }
+ }
+ fun testarrayofstring2(j: Int) : String? {
+ val o = __offset(60)
+ return if (o != 0) {
+ __string(__vector(o) + j * 4)
+ } else {
+ null
+ }
+ }
+ val testarrayofstring2Length : Int
+ get() {
+ val o = __offset(60); return if (o != 0) __vector_len(o) else 0
+ }
+ fun testarrayofsortedstruct(j: Int) : MyGame.Example.Ability? = testarrayofsortedstruct(MyGame.Example.Ability(), j)
+ fun testarrayofsortedstruct(obj: MyGame.Example.Ability, j: Int) : MyGame.Example.Ability? {
+ val o = __offset(62)
+ return if (o != 0) {
+ obj.__assign(__vector(o) + j * 8, bb)
+ } else {
+ null
+ }
+ }
+ val testarrayofsortedstructLength : Int
+ get() {
+ val o = __offset(62); return if (o != 0) __vector_len(o) else 0
+ }
+ fun flex(j: Int) : UByte {
+ val o = __offset(64)
+ return if (o != 0) {
+ bb.get(__vector(o) + j * 1).toUByte()
+ } else {
+ 0u
+ }
+ }
+ val flexLength : Int
+ get() {
+ val o = __offset(64); return if (o != 0) __vector_len(o) else 0
+ }
+ val flexAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(64, 1)
+ fun flexInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 64, 1)
+ fun mutateFlex(j: Int, flex: UByte) : Boolean {
+ val o = __offset(64)
+ return if (o != 0) {
+ bb.put(__vector(o) + j * 1, flex.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ fun test5(j: Int) : MyGame.Example.Test? = test5(MyGame.Example.Test(), j)
+ fun test5(obj: MyGame.Example.Test, j: Int) : MyGame.Example.Test? {
+ val o = __offset(66)
+ return if (o != 0) {
+ obj.__assign(__vector(o) + j * 4, bb)
+ } else {
+ null
+ }
+ }
+ val test5Length : Int
+ get() {
+ val o = __offset(66); return if (o != 0) __vector_len(o) else 0
+ }
+ fun vectorOfLongs(j: Int) : Long {
+ val o = __offset(68)
+ return if (o != 0) {
+ bb.getLong(__vector(o) + j * 8)
+ } else {
+ 0
+ }
+ }
+ val vectorOfLongsLength : Int
+ get() {
+ val o = __offset(68); return if (o != 0) __vector_len(o) else 0
+ }
+ val vectorOfLongsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(68, 8)
+ fun vectorOfLongsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 68, 8)
+ fun mutateVectorOfLongs(j: Int, vectorOfLongs: Long) : Boolean {
+ val o = __offset(68)
+ return if (o != 0) {
+ bb.putLong(__vector(o) + j * 8, vectorOfLongs)
+ true
+ } else {
+ false
+ }
+ }
+ fun vectorOfDoubles(j: Int) : Double {
+ val o = __offset(70)
+ return if (o != 0) {
+ bb.getDouble(__vector(o) + j * 8)
+ } else {
+ 0.0
+ }
+ }
+ val vectorOfDoublesLength : Int
+ get() {
+ val o = __offset(70); return if (o != 0) __vector_len(o) else 0
+ }
+ val vectorOfDoublesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(70, 8)
+ fun vectorOfDoublesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 70, 8)
+ fun mutateVectorOfDoubles(j: Int, vectorOfDoubles: Double) : Boolean {
+ val o = __offset(70)
+ return if (o != 0) {
+ bb.putDouble(__vector(o) + j * 8, vectorOfDoubles)
+ true
+ } else {
+ false
+ }
+ }
+ val parentNamespaceTest : MyGame.InParentNamespace? get() = parentNamespaceTest(MyGame.InParentNamespace())
+ fun parentNamespaceTest(obj: MyGame.InParentNamespace) : MyGame.InParentNamespace? {
+ val o = __offset(72)
+ return if (o != 0) {
+ obj.__assign(__indirect(o + bb_pos), bb)
+ } else {
+ null
+ }
+ }
+ fun vectorOfReferrables(j: Int) : MyGame.Example.Referrable? = vectorOfReferrables(MyGame.Example.Referrable(), j)
+ fun vectorOfReferrables(obj: MyGame.Example.Referrable, j: Int) : MyGame.Example.Referrable? {
+ val o = __offset(74)
+ return if (o != 0) {
+ obj.__assign(__indirect(__vector(o) + j * 4), bb)
+ } else {
+ null
+ }
+ }
+ val vectorOfReferrablesLength : Int
+ get() {
+ val o = __offset(74); return if (o != 0) __vector_len(o) else 0
+ }
+ fun vectorOfReferrablesByKey(key: ULong) : MyGame.Example.Referrable? {
+ val o = __offset(74)
+ return if (o != 0) {
+ MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb)
+ } else {
+ null
+ }
+ }
+ fun vectorOfReferrablesByKey(obj: MyGame.Example.Referrable, key: ULong) : MyGame.Example.Referrable? {
+ val o = __offset(74)
+ return if (o != 0) {
+ MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb)
+ } else {
+ null
+ }
+ }
+ val singleWeakReference : ULong
+ get() {
+ val o = __offset(76)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+ }
+ fun mutateSingleWeakReference(singleWeakReference: ULong) : Boolean {
+ val o = __offset(76)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, singleWeakReference.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ fun vectorOfWeakReferences(j: Int) : ULong {
+ val o = __offset(78)
+ return if (o != 0) {
+ bb.getLong(__vector(o) + j * 8).toULong()
+ } else {
+ 0uL
+ }
+ }
+ val vectorOfWeakReferencesLength : Int
+ get() {
+ val o = __offset(78); return if (o != 0) __vector_len(o) else 0
+ }
+ val vectorOfWeakReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(78, 8)
+ fun vectorOfWeakReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 78, 8)
+ fun mutateVectorOfWeakReferences(j: Int, vectorOfWeakReferences: ULong) : Boolean {
+ val o = __offset(78)
+ return if (o != 0) {
+ bb.putLong(__vector(o) + j * 8, vectorOfWeakReferences.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ fun vectorOfStrongReferrables(j: Int) : MyGame.Example.Referrable? = vectorOfStrongReferrables(MyGame.Example.Referrable(), j)
+ fun vectorOfStrongReferrables(obj: MyGame.Example.Referrable, j: Int) : MyGame.Example.Referrable? {
+ val o = __offset(80)
+ return if (o != 0) {
+ obj.__assign(__indirect(__vector(o) + j * 4), bb)
+ } else {
+ null
+ }
+ }
+ val vectorOfStrongReferrablesLength : Int
+ get() {
+ val o = __offset(80); return if (o != 0) __vector_len(o) else 0
+ }
+ fun vectorOfStrongReferrablesByKey(key: ULong) : MyGame.Example.Referrable? {
+ val o = __offset(80)
+ return if (o != 0) {
+ MyGame.Example.Referrable.__lookup_by_key(null, __vector(o), key, bb)
+ } else {
+ null
+ }
+ }
+ fun vectorOfStrongReferrablesByKey(obj: MyGame.Example.Referrable, key: ULong) : MyGame.Example.Referrable? {
+ val o = __offset(80)
+ return if (o != 0) {
+ MyGame.Example.Referrable.__lookup_by_key(obj, __vector(o), key, bb)
+ } else {
+ null
+ }
+ }
+ val coOwningReference : ULong
+ get() {
+ val o = __offset(82)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+ }
+ fun mutateCoOwningReference(coOwningReference: ULong) : Boolean {
+ val o = __offset(82)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, coOwningReference.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ fun vectorOfCoOwningReferences(j: Int) : ULong {
+ val o = __offset(84)
+ return if (o != 0) {
+ bb.getLong(__vector(o) + j * 8).toULong()
+ } else {
+ 0uL
+ }
+ }
+ val vectorOfCoOwningReferencesLength : Int
+ get() {
+ val o = __offset(84); return if (o != 0) __vector_len(o) else 0
+ }
+ val vectorOfCoOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(84, 8)
+ fun vectorOfCoOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 84, 8)
+ fun mutateVectorOfCoOwningReferences(j: Int, vectorOfCoOwningReferences: ULong) : Boolean {
+ val o = __offset(84)
+ return if (o != 0) {
+ bb.putLong(__vector(o) + j * 8, vectorOfCoOwningReferences.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ val nonOwningReference : ULong
+ get() {
+ val o = __offset(86)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+ }
+ fun mutateNonOwningReference(nonOwningReference: ULong) : Boolean {
+ val o = __offset(86)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, nonOwningReference.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ fun vectorOfNonOwningReferences(j: Int) : ULong {
+ val o = __offset(88)
+ return if (o != 0) {
+ bb.getLong(__vector(o) + j * 8).toULong()
+ } else {
+ 0uL
+ }
+ }
+ val vectorOfNonOwningReferencesLength : Int
+ get() {
+ val o = __offset(88); return if (o != 0) __vector_len(o) else 0
+ }
+ val vectorOfNonOwningReferencesAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(88, 8)
+ fun vectorOfNonOwningReferencesInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 88, 8)
+ fun mutateVectorOfNonOwningReferences(j: Int, vectorOfNonOwningReferences: ULong) : Boolean {
+ val o = __offset(88)
+ return if (o != 0) {
+ bb.putLong(__vector(o) + j * 8, vectorOfNonOwningReferences.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ val anyUniqueType : UByte
+ get() {
+ val o = __offset(90)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+ }
+ fun mutateAnyUniqueType(anyUniqueType: UByte) : Boolean {
+ val o = __offset(90)
+ return if (o != 0) {
+ bb.put(o + bb_pos, anyUniqueType.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ fun anyUnique(obj: Table) : Table? {
+ val o = __offset(92); return if (o != 0) __union(obj, o + bb_pos) else null
+ }
+ val anyAmbiguousType : UByte
+ get() {
+ val o = __offset(94)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+ }
+ fun mutateAnyAmbiguousType(anyAmbiguousType: UByte) : Boolean {
+ val o = __offset(94)
+ return if (o != 0) {
+ bb.put(o + bb_pos, anyAmbiguousType.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ fun anyAmbiguous(obj: Table) : Table? {
+ val o = __offset(96); return if (o != 0) __union(obj, o + bb_pos) else null
+ }
+ fun vectorOfEnums(j: Int) : UByte {
+ val o = __offset(98)
+ return if (o != 0) {
+ bb.get(__vector(o) + j * 1).toUByte()
+ } else {
+ 0u
+ }
+ }
+ val vectorOfEnumsLength : Int
+ get() {
+ val o = __offset(98); return if (o != 0) __vector_len(o) else 0
+ }
+ val vectorOfEnumsAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(98, 1)
+ fun vectorOfEnumsInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 98, 1)
+ fun mutateVectorOfEnums(j: Int, vectorOfEnums: UByte) : Boolean {
+ val o = __offset(98)
+ return if (o != 0) {
+ bb.put(__vector(o) + j * 1, vectorOfEnums.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ val signedEnum : Byte
+ get() {
+ val o = __offset(100)
+ return if(o != 0) bb.get(o + bb_pos) else -1
+ }
+ fun mutateSignedEnum(signedEnum: Byte) : Boolean {
+ val o = __offset(100)
+ return if (o != 0) {
+ bb.put(o + bb_pos, signedEnum)
+ true
+ } else {
+ false
+ }
+ }
+ override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int {
+ return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb)
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster())
+ fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun MonsterBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MONS")
+ fun startMonster(builder: FlatBufferBuilder) = builder.startTable(49)
+ fun addPos(builder: FlatBufferBuilder, pos: Int) = builder.addStruct(0, pos, 0)
+ fun addMana(builder: FlatBufferBuilder, mana: Short) = builder.addShort(1, mana, 150)
+ fun addHp(builder: FlatBufferBuilder, hp: Short) = builder.addShort(2, hp, 100)
+ fun addName(builder: FlatBufferBuilder, name: Int) = builder.addOffset(3, name, 0)
+ fun addInventory(builder: FlatBufferBuilder, inventory: Int) = builder.addOffset(5, inventory, 0)
+ fun createInventoryVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+ builder.startVector(1, data.size, 1)
+ for (i in data.size - 1 downTo 0) {
+ builder.addByte(data[i].toByte())
+ }
+ return builder.endVector()
+ }
+ fun startInventoryVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+ fun addColor(builder: FlatBufferBuilder, color: UByte) = builder.addByte(6, color.toByte(), 8)
+ fun addTestType(builder: FlatBufferBuilder, testType: UByte) = builder.addByte(7, testType.toByte(), 0)
+ fun addTest(builder: FlatBufferBuilder, test: Int) = builder.addOffset(8, test, 0)
+ fun addTest4(builder: FlatBufferBuilder, test4: Int) = builder.addOffset(9, test4, 0)
+ fun startTest4Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 2)
+ fun addTestarrayofstring(builder: FlatBufferBuilder, testarrayofstring: Int) = builder.addOffset(10, testarrayofstring, 0)
+ fun createTestarrayofstringVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+ builder.startVector(4, data.size, 4)
+ for (i in data.size - 1 downTo 0) {
+ builder.addOffset(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startTestarrayofstringVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+ fun addTestarrayoftables(builder: FlatBufferBuilder, testarrayoftables: Int) = builder.addOffset(11, testarrayoftables, 0)
+ fun createTestarrayoftablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+ builder.startVector(4, data.size, 4)
+ for (i in data.size - 1 downTo 0) {
+ builder.addOffset(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startTestarrayoftablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+ fun addEnemy(builder: FlatBufferBuilder, enemy: Int) = builder.addOffset(12, enemy, 0)
+ fun addTestnestedflatbuffer(builder: FlatBufferBuilder, testnestedflatbuffer: Int) = builder.addOffset(13, testnestedflatbuffer, 0)
+ fun createTestnestedflatbufferVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+ builder.startVector(1, data.size, 1)
+ for (i in data.size - 1 downTo 0) {
+ builder.addByte(data[i].toByte())
+ }
+ return builder.endVector()
+ }
+ fun startTestnestedflatbufferVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+ fun addTestempty(builder: FlatBufferBuilder, testempty: Int) = builder.addOffset(14, testempty, 0)
+ fun addTestbool(builder: FlatBufferBuilder, testbool: Boolean) = builder.addBoolean(15, testbool, false)
+ fun addTesthashs32Fnv1(builder: FlatBufferBuilder, testhashs32Fnv1: Int) = builder.addInt(16, testhashs32Fnv1, 0)
+ fun addTesthashu32Fnv1(builder: FlatBufferBuilder, testhashu32Fnv1: UInt) = builder.addInt(17, testhashu32Fnv1.toInt(), 0)
+ fun addTesthashs64Fnv1(builder: FlatBufferBuilder, testhashs64Fnv1: Long) = builder.addLong(18, testhashs64Fnv1, 0L)
+ fun addTesthashu64Fnv1(builder: FlatBufferBuilder, testhashu64Fnv1: ULong) = builder.addLong(19, testhashu64Fnv1.toLong(), 0)
+ fun addTesthashs32Fnv1a(builder: FlatBufferBuilder, testhashs32Fnv1a: Int) = builder.addInt(20, testhashs32Fnv1a, 0)
+ fun addTesthashu32Fnv1a(builder: FlatBufferBuilder, testhashu32Fnv1a: UInt) = builder.addInt(21, testhashu32Fnv1a.toInt(), 0)
+ fun addTesthashs64Fnv1a(builder: FlatBufferBuilder, testhashs64Fnv1a: Long) = builder.addLong(22, testhashs64Fnv1a, 0L)
+ fun addTesthashu64Fnv1a(builder: FlatBufferBuilder, testhashu64Fnv1a: ULong) = builder.addLong(23, testhashu64Fnv1a.toLong(), 0)
+ fun addTestarrayofbools(builder: FlatBufferBuilder, testarrayofbools: Int) = builder.addOffset(24, testarrayofbools, 0)
+ fun createTestarrayofboolsVector(builder: FlatBufferBuilder, data: BooleanArray) : Int {
+ builder.startVector(1, data.size, 1)
+ for (i in data.size - 1 downTo 0) {
+ builder.addBoolean(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startTestarrayofboolsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+ fun addTestf(builder: FlatBufferBuilder, testf: Float) = builder.addFloat(25, testf, 3.14159)
+ fun addTestf2(builder: FlatBufferBuilder, testf2: Float) = builder.addFloat(26, testf2, 3.0)
+ fun addTestf3(builder: FlatBufferBuilder, testf3: Float) = builder.addFloat(27, testf3, 0.0)
+ fun addTestarrayofstring2(builder: FlatBufferBuilder, testarrayofstring2: Int) = builder.addOffset(28, testarrayofstring2, 0)
+ fun createTestarrayofstring2Vector(builder: FlatBufferBuilder, data: IntArray) : Int {
+ builder.startVector(4, data.size, 4)
+ for (i in data.size - 1 downTo 0) {
+ builder.addOffset(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startTestarrayofstring2Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+ fun addTestarrayofsortedstruct(builder: FlatBufferBuilder, testarrayofsortedstruct: Int) = builder.addOffset(29, testarrayofsortedstruct, 0)
+ fun startTestarrayofsortedstructVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 4)
+ fun addFlex(builder: FlatBufferBuilder, flex: Int) = builder.addOffset(30, flex, 0)
+ fun createFlexVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+ builder.startVector(1, data.size, 1)
+ for (i in data.size - 1 downTo 0) {
+ builder.addByte(data[i].toByte())
+ }
+ return builder.endVector()
+ }
+ fun startFlexVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+ fun addTest5(builder: FlatBufferBuilder, test5: Int) = builder.addOffset(31, test5, 0)
+ fun startTest5Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 2)
+ fun addVectorOfLongs(builder: FlatBufferBuilder, vectorOfLongs: Int) = builder.addOffset(32, vectorOfLongs, 0)
+ fun createVectorOfLongsVector(builder: FlatBufferBuilder, data: LongArray) : Int {
+ builder.startVector(8, data.size, 8)
+ for (i in data.size - 1 downTo 0) {
+ builder.addLong(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startVectorOfLongsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+ fun addVectorOfDoubles(builder: FlatBufferBuilder, vectorOfDoubles: Int) = builder.addOffset(33, vectorOfDoubles, 0)
+ fun createVectorOfDoublesVector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+ builder.startVector(8, data.size, 8)
+ for (i in data.size - 1 downTo 0) {
+ builder.addDouble(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startVectorOfDoublesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+ fun addParentNamespaceTest(builder: FlatBufferBuilder, parentNamespaceTest: Int) = builder.addOffset(34, parentNamespaceTest, 0)
+ fun addVectorOfReferrables(builder: FlatBufferBuilder, vectorOfReferrables: Int) = builder.addOffset(35, vectorOfReferrables, 0)
+ fun createVectorOfReferrablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+ builder.startVector(4, data.size, 4)
+ for (i in data.size - 1 downTo 0) {
+ builder.addOffset(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startVectorOfReferrablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+ fun addSingleWeakReference(builder: FlatBufferBuilder, singleWeakReference: ULong) = builder.addLong(36, singleWeakReference.toLong(), 0)
+ fun addVectorOfWeakReferences(builder: FlatBufferBuilder, vectorOfWeakReferences: Int) = builder.addOffset(37, vectorOfWeakReferences, 0)
+ fun createVectorOfWeakReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+ builder.startVector(8, data.size, 8)
+ for (i in data.size - 1 downTo 0) {
+ builder.addLong(data[i].toLong())
+ }
+ return builder.endVector()
+ }
+ fun startVectorOfWeakReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+ fun addVectorOfStrongReferrables(builder: FlatBufferBuilder, vectorOfStrongReferrables: Int) = builder.addOffset(38, vectorOfStrongReferrables, 0)
+ fun createVectorOfStrongReferrablesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+ builder.startVector(4, data.size, 4)
+ for (i in data.size - 1 downTo 0) {
+ builder.addOffset(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startVectorOfStrongReferrablesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+ fun addCoOwningReference(builder: FlatBufferBuilder, coOwningReference: ULong) = builder.addLong(39, coOwningReference.toLong(), 0)
+ fun addVectorOfCoOwningReferences(builder: FlatBufferBuilder, vectorOfCoOwningReferences: Int) = builder.addOffset(40, vectorOfCoOwningReferences, 0)
+ fun createVectorOfCoOwningReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+ builder.startVector(8, data.size, 8)
+ for (i in data.size - 1 downTo 0) {
+ builder.addLong(data[i].toLong())
+ }
+ return builder.endVector()
+ }
+ fun startVectorOfCoOwningReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+ fun addNonOwningReference(builder: FlatBufferBuilder, nonOwningReference: ULong) = builder.addLong(41, nonOwningReference.toLong(), 0)
+ fun addVectorOfNonOwningReferences(builder: FlatBufferBuilder, vectorOfNonOwningReferences: Int) = builder.addOffset(42, vectorOfNonOwningReferences, 0)
+ fun createVectorOfNonOwningReferencesVector(builder: FlatBufferBuilder, data: ULongArray) : Int {
+ builder.startVector(8, data.size, 8)
+ for (i in data.size - 1 downTo 0) {
+ builder.addLong(data[i].toLong())
+ }
+ return builder.endVector()
+ }
+ fun startVectorOfNonOwningReferencesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+ fun addAnyUniqueType(builder: FlatBufferBuilder, anyUniqueType: UByte) = builder.addByte(43, anyUniqueType.toByte(), 0)
+ fun addAnyUnique(builder: FlatBufferBuilder, anyUnique: Int) = builder.addOffset(44, anyUnique, 0)
+ fun addAnyAmbiguousType(builder: FlatBufferBuilder, anyAmbiguousType: UByte) = builder.addByte(45, anyAmbiguousType.toByte(), 0)
+ fun addAnyAmbiguous(builder: FlatBufferBuilder, anyAmbiguous: Int) = builder.addOffset(46, anyAmbiguous, 0)
+ fun addVectorOfEnums(builder: FlatBufferBuilder, vectorOfEnums: Int) = builder.addOffset(47, vectorOfEnums, 0)
+ fun createVectorOfEnumsVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+ builder.startVector(1, data.size, 1)
+ for (i in data.size - 1 downTo 0) {
+ builder.addByte(data[i].toByte())
+ }
+ return builder.endVector()
+ }
+ fun startVectorOfEnumsVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+ fun addSignedEnum(builder: FlatBufferBuilder, signedEnum: Byte) = builder.addByte(48, signedEnum, -1)
+ fun endMonster(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ builder.required(o, 10)
+ return o
+ }
+ fun finishMonsterBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MONS")
+ fun finishSizePrefixedMonsterBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MONS")
+ fun __lookup_by_key(obj: Monster?, vectorLocation: Int, key: String, bb: ByteBuffer) : Monster? {
+ val byteKey = key.toByteArray(java.nio.charset.StandardCharsets.UTF_8)
+ var span = bb.getInt(vectorLocation - 4)
+ var start = 0
+ while (span != 0) {
+ var middle = span / 2
+ val tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb)
+ val comp = compareStrings(__offset(10, bb.capacity() - tableOffset, bb), byteKey, bb)
+ when {
+ comp > 0 -> span = middle
+ comp < 0 -> {
+ middle++
+ start += middle
+ span -= middle
+ }
+ else -> {
+ return (obj ?: Monster()).__assign(tableOffset, bb)
+ }
+ }
+ }
+ return null
+ }
+ }
+}
diff --git a/tests/MyGame/Example/Monster.lua b/tests/MyGame/Example/Monster.lua
index f12808b4..8f82d9de 100644
--- a/tests/MyGame/Example/Monster.lua
+++ b/tests/MyGame/Example/Monster.lua
@@ -4,7 +4,7 @@
local flatbuffers = require('flatbuffers')
--- /// an example documentation comment: monster object
+-- an example documentation comment: "monster object"
local Monster = {} -- the module
local Monster_mt = {} -- the class metatable
@@ -69,7 +69,7 @@ end
function Monster_mt:Color()
local o = self.view:Offset(16)
if o ~= 0 then
- return self.view:Get(flatbuffers.N.Int8, o + self.view.pos)
+ return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
end
return 8
end
@@ -120,8 +120,8 @@ function Monster_mt:TestarrayofstringLength()
end
return 0
end
--- /// an example documentation comment: this will end up in the generated code
--- /// multiline too
+-- an example documentation comment: this will end up in the generated code
+-- multiline too
function Monster_mt:Testarrayoftables(j)
local o = self.view:Offset(26)
if o ~= 0 then
@@ -511,7 +511,7 @@ function Monster_mt:VectorOfEnums(j)
local o = self.view:Offset(98)
if o ~= 0 then
local a = self.view:Vector(o)
- return self.view:Get(flatbuffers.N.Int8, a + ((j-1) * 1))
+ return self.view:Get(flatbuffers.N.Uint8, a + ((j-1) * 1))
end
return 0
end
@@ -522,14 +522,21 @@ function Monster_mt:VectorOfEnumsLength()
end
return 0
end
-function Monster.Start(builder) builder:StartObject(48) end
+function Monster_mt:SignedEnum()
+ local o = self.view:Offset(100)
+ if o ~= 0 then
+ return self.view:Get(flatbuffers.N.Int8, o + self.view.pos)
+ end
+ return -1
+end
+function Monster.Start(builder) builder:StartObject(49) end
function Monster.AddPos(builder, pos) builder:PrependStructSlot(0, pos, 0) end
function Monster.AddMana(builder, mana) builder:PrependInt16Slot(1, mana, 150) end
function Monster.AddHp(builder, hp) builder:PrependInt16Slot(2, hp, 100) end
function Monster.AddName(builder, name) builder:PrependUOffsetTRelativeSlot(3, name, 0) end
function Monster.AddInventory(builder, inventory) builder:PrependUOffsetTRelativeSlot(5, inventory, 0) end
function Monster.StartInventoryVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
-function Monster.AddColor(builder, color) builder:PrependInt8Slot(6, color, 8) end
+function Monster.AddColor(builder, color) builder:PrependUint8Slot(6, color, 8) end
function Monster.AddTestType(builder, testType) builder:PrependUint8Slot(7, testType, 0) end
function Monster.AddTest(builder, test) builder:PrependUOffsetTRelativeSlot(8, test, 0) end
function Monster.AddTest4(builder, test4) builder:PrependUOffsetTRelativeSlot(9, test4, 0) end
@@ -588,6 +595,7 @@ function Monster.AddAnyAmbiguousType(builder, anyAmbiguousType) builder:PrependU
function Monster.AddAnyAmbiguous(builder, anyAmbiguous) builder:PrependUOffsetTRelativeSlot(46, anyAmbiguous, 0) end
function Monster.AddVectorOfEnums(builder, vectorOfEnums) builder:PrependUOffsetTRelativeSlot(47, vectorOfEnums, 0) end
function Monster.StartVectorOfEnumsVector(builder, numElems) return builder:StartVector(1, numElems, 1) end
+function Monster.AddSignedEnum(builder, signedEnum) builder:PrependInt8Slot(48, signedEnum, -1) end
function Monster.End(builder) return builder:EndObject() end
return Monster -- return the module \ No newline at end of file
diff --git a/tests/MyGame/Example/Monster.php b/tests/MyGame/Example/Monster.php
index 311f0174..a07ffcc6 100644
--- a/tests/MyGame/Example/Monster.php
+++ b/tests/MyGame/Example/Monster.php
@@ -8,7 +8,7 @@ use \Google\FlatBuffers\Table;
use \Google\FlatBuffers\ByteBuffer;
use \Google\FlatBuffers\FlatBufferBuilder;
-/// an example documentation comment: monster object
+/// an example documentation comment: "monster object"
class Monster extends Table
{
/**
@@ -107,12 +107,12 @@ class Monster extends Table
}
/**
- * @return sbyte
+ * @return byte
*/
public function getColor()
{
$o = $this->__offset(16);
- return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : \MyGame\Example\Color::Blue;
+ return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Color::Blue;
}
/**
@@ -171,8 +171,8 @@ class Monster extends Table
return $o != 0 ? $this->__vector_len($o) : 0;
}
-/// an example documentation comment: this will end up in the generated code
-/// multiline too
+ /// an example documentation comment: this will end up in the generated code
+ /// multiline too
/**
* @returnVectorOffset
*/
@@ -649,12 +649,12 @@ class Monster extends Table
/**
* @param int offset
- * @return sbyte
+ * @return byte
*/
public function getVectorOfEnums($j)
{
$o = $this->__offset(98);
- return $o != 0 ? $this->bb->getSbyte($this->__vector($o) + $j * 1) : 0;
+ return $o != 0 ? $this->bb->getByte($this->__vector($o) + $j * 1) : 0;
}
/**
@@ -667,21 +667,38 @@ class Monster extends Table
}
/**
+ * @return string
+ */
+ public function getVectorOfEnumsBytes()
+ {
+ return $this->__vector_as_bytes(98);
+ }
+
+ /**
+ * @return sbyte
+ */
+ public function getSignedEnum()
+ {
+ $o = $this->__offset(100);
+ return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : \MyGame\Example\Race::None;
+ }
+
+ /**
* @param FlatBufferBuilder $builder
* @return void
*/
public static function startMonster(FlatBufferBuilder $builder)
{
- $builder->StartObject(48);
+ $builder->StartObject(49);
}
/**
* @param FlatBufferBuilder $builder
* @return Monster
*/
- public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct, $flex, $test5, $vector_of_longs, $vector_of_doubles, $parent_namespace_test, $vector_of_referrables, $single_weak_reference, $vector_of_weak_references, $vector_of_strong_referrables, $co_owning_reference, $vector_of_co_owning_references, $non_owning_reference, $vector_of_non_owning_references, $any_unique_type, $any_unique, $any_ambiguous_type, $any_ambiguous, $vector_of_enums)
+ public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct, $flex, $test5, $vector_of_longs, $vector_of_doubles, $parent_namespace_test, $vector_of_referrables, $single_weak_reference, $vector_of_weak_references, $vector_of_strong_referrables, $co_owning_reference, $vector_of_co_owning_references, $non_owning_reference, $vector_of_non_owning_references, $any_unique_type, $any_unique, $any_ambiguous_type, $any_ambiguous, $vector_of_enums, $signed_enum)
{
- $builder->startObject(48);
+ $builder->startObject(49);
self::addPos($builder, $pos);
self::addMana($builder, $mana);
self::addHp($builder, $hp);
@@ -729,6 +746,7 @@ class Monster extends Table
self::addAnyAmbiguousType($builder, $any_ambiguous_type);
self::addAnyAmbiguous($builder, $any_ambiguous);
self::addVectorOfEnums($builder, $vector_of_enums);
+ self::addSignedEnum($builder, $signed_enum);
$o = $builder->endObject();
$builder->required($o, 10); // name
return $o;
@@ -810,12 +828,12 @@ class Monster extends Table
/**
* @param FlatBufferBuilder $builder
- * @param sbyte
+ * @param byte
* @return void
*/
public static function addColor(FlatBufferBuilder $builder, $color)
{
- $builder->addSbyteX(6, $color, 8);
+ $builder->addByteX(6, $color, 8);
}
/**
@@ -1606,7 +1624,7 @@ class Monster extends Table
{
$builder->startVector(1, count($data), 1);
for ($i = count($data) - 1; $i >= 0; $i--) {
- $builder->putSbyte($data[$i]);
+ $builder->putByte($data[$i]);
}
return $builder->endVector();
}
@@ -1623,6 +1641,16 @@ class Monster extends Table
/**
* @param FlatBufferBuilder $builder
+ * @param sbyte
+ * @return void
+ */
+ public static function addSignedEnum(FlatBufferBuilder $builder, $signedEnum)
+ {
+ $builder->addSbyteX(48, $signedEnum, -1);
+ }
+
+ /**
+ * @param FlatBufferBuilder $builder
* @return int table offset
*/
public static function endMonster(FlatBufferBuilder $builder)
diff --git a/tests/MyGame/Example/Monster.py b/tests/MyGame/Example/Monster.py
index bcc8a634..641d038c 100644
--- a/tests/MyGame/Example/Monster.py
+++ b/tests/MyGame/Example/Monster.py
@@ -3,8 +3,10 @@
# namespace: Example
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
-# /// an example documentation comment: monster object
+# an example documentation comment: "monster object"
class Monster(object):
__slots__ = ['_tab']
@@ -15,6 +17,10 @@ class Monster(object):
x.Init(buf, n + offset)
return x
+ @classmethod
+ def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
# Monster
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
@@ -24,7 +30,7 @@ class Monster(object):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
x = o + self._tab.Pos
- from .Vec3 import Vec3
+ from MyGame.Example.Vec3 import Vec3
obj = Vec3()
obj.Init(self._tab.Bytes, x)
return obj
@@ -74,10 +80,15 @@ class Monster(object):
return 0
# Monster
+ def InventoryIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
+ return o == 0
+
+ # Monster
def Color(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
+ return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
return 8
# Monster
@@ -103,7 +114,7 @@ class Monster(object):
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
- from .Test import Test
+ from MyGame.Example.Test import Test
obj = Test()
obj.Init(self._tab.Bytes, x)
return obj
@@ -117,6 +128,11 @@ class Monster(object):
return 0
# Monster
+ def Test4IsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+ return o == 0
+
+ # Monster
def Testarrayofstring(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
if o != 0:
@@ -131,8 +147,13 @@ class Monster(object):
return self._tab.VectorLen(o)
return 0
-# /// an example documentation comment: this will end up in the generated code
-# /// multiline too
+ # Monster
+ def TestarrayofstringIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+ return o == 0
+
+ # an example documentation comment: this will end up in the generated code
+ # multiline too
# Monster
def Testarrayoftables(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
@@ -140,7 +161,7 @@ class Monster(object):
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
- from .Monster import Monster
+ from MyGame.Example.Monster import Monster
obj = Monster()
obj.Init(self._tab.Bytes, x)
return obj
@@ -154,11 +175,16 @@ class Monster(object):
return 0
# Monster
+ def TestarrayoftablesIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+ return o == 0
+
+ # Monster
def Enemy(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(28))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
- from .Monster import Monster
+ from MyGame.Example.Monster import Monster
obj = Monster()
obj.Init(self._tab.Bytes, x)
return obj
@@ -187,11 +213,16 @@ class Monster(object):
return 0
# Monster
+ def TestnestedflatbufferIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(30))
+ return o == 0
+
+ # Monster
def Testempty(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(32))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
- from .Stat import Stat
+ from MyGame.Example.Stat import Stat
obj = Stat()
obj.Init(self._tab.Bytes, x)
return obj
@@ -283,6 +314,11 @@ class Monster(object):
return 0
# Monster
+ def TestarrayofboolsIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(52))
+ return o == 0
+
+ # Monster
def Testf(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(54))
if o != 0:
@@ -319,12 +355,17 @@ class Monster(object):
return 0
# Monster
+ def Testarrayofstring2IsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(60))
+ return o == 0
+
+ # Monster
def Testarrayofsortedstruct(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 8
- from .Ability import Ability
+ from MyGame.Example.Ability import Ability
obj = Ability()
obj.Init(self._tab.Bytes, x)
return obj
@@ -338,6 +379,11 @@ class Monster(object):
return 0
# Monster
+ def TestarrayofsortedstructIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(62))
+ return o == 0
+
+ # Monster
def Flex(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
if o != 0:
@@ -360,12 +406,17 @@ class Monster(object):
return 0
# Monster
+ def FlexIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(64))
+ return o == 0
+
+ # Monster
def Test5(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
- from .Test import Test
+ from MyGame.Example.Test import Test
obj = Test()
obj.Init(self._tab.Bytes, x)
return obj
@@ -379,6 +430,11 @@ class Monster(object):
return 0
# Monster
+ def Test5IsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(66))
+ return o == 0
+
+ # Monster
def VectorOfLongs(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
if o != 0:
@@ -401,6 +457,11 @@ class Monster(object):
return 0
# Monster
+ def VectorOfLongsIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(68))
+ return o == 0
+
+ # Monster
def VectorOfDoubles(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
if o != 0:
@@ -423,11 +484,16 @@ class Monster(object):
return 0
# Monster
+ def VectorOfDoublesIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(70))
+ return o == 0
+
+ # Monster
def ParentNamespaceTest(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(72))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
- from .InParentNamespace import InParentNamespace
+ from MyGame.InParentNamespace import InParentNamespace
obj = InParentNamespace()
obj.Init(self._tab.Bytes, x)
return obj
@@ -440,7 +506,7 @@ class Monster(object):
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
- from .Referrable import Referrable
+ from MyGame.Example.Referrable import Referrable
obj = Referrable()
obj.Init(self._tab.Bytes, x)
return obj
@@ -454,6 +520,11 @@ class Monster(object):
return 0
# Monster
+ def VectorOfReferrablesIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(74))
+ return o == 0
+
+ # Monster
def SingleWeakReference(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(76))
if o != 0:
@@ -483,13 +554,18 @@ class Monster(object):
return 0
# Monster
+ def VectorOfWeakReferencesIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(78))
+ return o == 0
+
+ # Monster
def VectorOfStrongReferrables(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
if o != 0:
x = self._tab.Vector(o)
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
x = self._tab.Indirect(x)
- from .Referrable import Referrable
+ from MyGame.Example.Referrable import Referrable
obj = Referrable()
obj.Init(self._tab.Bytes, x)
return obj
@@ -503,6 +579,11 @@ class Monster(object):
return 0
# Monster
+ def VectorOfStrongReferrablesIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(80))
+ return o == 0
+
+ # Monster
def CoOwningReference(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(82))
if o != 0:
@@ -532,6 +613,11 @@ class Monster(object):
return 0
# Monster
+ def VectorOfCoOwningReferencesIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(84))
+ return o == 0
+
+ # Monster
def NonOwningReference(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(86))
if o != 0:
@@ -561,6 +647,11 @@ class Monster(object):
return 0
# Monster
+ def VectorOfNonOwningReferencesIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(88))
+ return o == 0
+
+ # Monster
def AnyUniqueType(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(90))
if o != 0:
@@ -599,14 +690,14 @@ class Monster(object):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
if o != 0:
a = self._tab.Vector(o)
- return self._tab.Get(flatbuffers.number_types.Int8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
+ return self._tab.Get(flatbuffers.number_types.Uint8Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 1))
return 0
# Monster
def VectorOfEnumsAsNumpy(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
if o != 0:
- return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Int8Flags, o)
+ return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Uint8Flags, o)
return 0
# Monster
@@ -616,14 +707,26 @@ class Monster(object):
return self._tab.VectorLen(o)
return 0
-def MonsterStart(builder): builder.StartObject(48)
+ # Monster
+ def VectorOfEnumsIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(98))
+ return o == 0
+
+ # Monster
+ def SignedEnum(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(100))
+ if o != 0:
+ return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
+ return -1
+
+def MonsterStart(builder): builder.StartObject(49)
def MonsterAddPos(builder, pos): builder.PrependStructSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(pos), 0)
def MonsterAddMana(builder, mana): builder.PrependInt16Slot(1, mana, 150)
def MonsterAddHp(builder, hp): builder.PrependInt16Slot(2, hp, 100)
def MonsterAddName(builder, name): builder.PrependUOffsetTRelativeSlot(3, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
def MonsterAddInventory(builder, inventory): builder.PrependUOffsetTRelativeSlot(5, flatbuffers.number_types.UOffsetTFlags.py_type(inventory), 0)
def MonsterStartInventoryVector(builder, numElems): return builder.StartVector(1, numElems, 1)
-def MonsterAddColor(builder, color): builder.PrependInt8Slot(6, color, 8)
+def MonsterAddColor(builder, color): builder.PrependUint8Slot(6, color, 8)
def MonsterAddTestType(builder, testType): builder.PrependUint8Slot(7, testType, 0)
def MonsterAddTest(builder, test): builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(test), 0)
def MonsterAddTest4(builder, test4): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(test4), 0)
@@ -682,4 +785,481 @@ def MonsterAddAnyAmbiguousType(builder, anyAmbiguousType): builder.PrependUint8S
def MonsterAddAnyAmbiguous(builder, anyAmbiguous): builder.PrependUOffsetTRelativeSlot(46, flatbuffers.number_types.UOffsetTFlags.py_type(anyAmbiguous), 0)
def MonsterAddVectorOfEnums(builder, vectorOfEnums): builder.PrependUOffsetTRelativeSlot(47, flatbuffers.number_types.UOffsetTFlags.py_type(vectorOfEnums), 0)
def MonsterStartVectorOfEnumsVector(builder, numElems): return builder.StartVector(1, numElems, 1)
+def MonsterAddSignedEnum(builder, signedEnum): builder.PrependInt8Slot(48, signedEnum, -1)
def MonsterEnd(builder): return builder.EndObject()
+
+import MyGame.Example.Ability
+import MyGame.Example.Any
+import MyGame.Example.AnyAmbiguousAliases
+import MyGame.Example.AnyUniqueAliases
+import MyGame.Example.Referrable
+import MyGame.Example.Stat
+import MyGame.Example.Test
+import MyGame.Example.TestSimpleTableWithEnum
+import MyGame.Example.Vec3
+import MyGame.Example2.Monster
+import MyGame.InParentNamespace
+try:
+ from typing import List, Optional, Union
+except:
+ pass
+
+class MonsterT(object):
+
+ # MonsterT
+ def __init__(self):
+ self.pos = None # type: Optional[MyGame.Example.Vec3.Vec3T]
+ self.mana = 150 # type: int
+ self.hp = 100 # type: int
+ self.name = None # type: str
+ self.inventory = None # type: List[int]
+ self.color = 8 # type: int
+ self.testType = 0 # type: int
+ self.test = None # type: Union[None, MyGame.Example.Monster.MonsterT, MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT, MyGame.Example2.Monster.MonsterT]
+ self.test4 = None # type: List[MyGame.Example.Test.TestT]
+ self.testarrayofstring = None # type: List[str]
+ self.testarrayoftables = None # type: List[MyGame.Example.Monster.MonsterT]
+ self.enemy = None # type: Optional[MyGame.Example.Monster.MonsterT]
+ self.testnestedflatbuffer = None # type: List[int]
+ self.testempty = None # type: Optional[MyGame.Example.Stat.StatT]
+ self.testbool = False # type: bool
+ self.testhashs32Fnv1 = 0 # type: int
+ self.testhashu32Fnv1 = 0 # type: int
+ self.testhashs64Fnv1 = 0 # type: int
+ self.testhashu64Fnv1 = 0 # type: int
+ self.testhashs32Fnv1a = 0 # type: int
+ self.testhashu32Fnv1a = 0 # type: int
+ self.testhashs64Fnv1a = 0 # type: int
+ self.testhashu64Fnv1a = 0 # type: int
+ self.testarrayofbools = None # type: List[bool]
+ self.testf = 3.14159 # type: float
+ self.testf2 = 3.0 # type: float
+ self.testf3 = 0.0 # type: float
+ self.testarrayofstring2 = None # type: List[str]
+ self.testarrayofsortedstruct = None # type: List[MyGame.Example.Ability.AbilityT]
+ self.flex = None # type: List[int]
+ self.test5 = None # type: List[MyGame.Example.Test.TestT]
+ self.vectorOfLongs = None # type: List[int]
+ self.vectorOfDoubles = None # type: List[float]
+ self.parentNamespaceTest = None # type: Optional[MyGame.InParentNamespace.InParentNamespaceT]
+ self.vectorOfReferrables = None # type: List[MyGame.Example.Referrable.ReferrableT]
+ self.singleWeakReference = 0 # type: int
+ self.vectorOfWeakReferences = None # type: List[int]
+ self.vectorOfStrongReferrables = None # type: List[MyGame.Example.Referrable.ReferrableT]
+ self.coOwningReference = 0 # type: int
+ self.vectorOfCoOwningReferences = None # type: List[int]
+ self.nonOwningReference = 0 # type: int
+ self.vectorOfNonOwningReferences = None # type: List[int]
+ self.anyUniqueType = 0 # type: int
+ self.anyUnique = None # type: Union[None, MyGame.Example.Monster.MonsterT, MyGame.Example.TestSimpleTableWithEnum.TestSimpleTableWithEnumT, MyGame.Example2.Monster.MonsterT]
+ self.anyAmbiguousType = 0 # type: int
+ self.anyAmbiguous = None # type: Union[None, MyGame.Example.Monster.MonsterT, MyGame.Example.Monster.MonsterT, MyGame.Example.Monster.MonsterT]
+ self.vectorOfEnums = None # type: List[int]
+ self.signedEnum = -1 # type: int
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ monster = Monster()
+ monster.Init(buf, pos)
+ return cls.InitFromObj(monster)
+
+ @classmethod
+ def InitFromObj(cls, monster):
+ x = MonsterT()
+ x._UnPack(monster)
+ return x
+
+ # MonsterT
+ def _UnPack(self, monster):
+ if monster is None:
+ return
+ if monster.Pos() is not None:
+ self.pos = MyGame.Example.Vec3.Vec3T.InitFromObj(monster.Pos())
+ self.mana = monster.Mana()
+ self.hp = monster.Hp()
+ self.name = monster.Name()
+ if not monster.InventoryIsNone():
+ if np is None:
+ self.inventory = []
+ for i in range(monster.InventoryLength()):
+ self.inventory.append(monster.Inventory(i))
+ else:
+ self.inventory = monster.InventoryAsNumpy()
+ self.color = monster.Color()
+ self.testType = monster.TestType()
+ self.test = MyGame.Example.Any.AnyCreator(self.testType, monster.Test())
+ if not monster.Test4IsNone():
+ self.test4 = []
+ for i in range(monster.Test4Length()):
+ if monster.Test4(i) is None:
+ self.test4.append(None)
+ else:
+ test_ = MyGame.Example.Test.TestT.InitFromObj(monster.Test4(i))
+ self.test4.append(test_)
+ if not monster.TestarrayofstringIsNone():
+ self.testarrayofstring = []
+ for i in range(monster.TestarrayofstringLength()):
+ self.testarrayofstring.append(monster.Testarrayofstring(i))
+ if not monster.TestarrayoftablesIsNone():
+ self.testarrayoftables = []
+ for i in range(monster.TestarrayoftablesLength()):
+ if monster.Testarrayoftables(i) is None:
+ self.testarrayoftables.append(None)
+ else:
+ monster_ = MyGame.Example.Monster.MonsterT.InitFromObj(monster.Testarrayoftables(i))
+ self.testarrayoftables.append(monster_)
+ if monster.Enemy() is not None:
+ self.enemy = MyGame.Example.Monster.MonsterT.InitFromObj(monster.Enemy())
+ if not monster.TestnestedflatbufferIsNone():
+ if np is None:
+ self.testnestedflatbuffer = []
+ for i in range(monster.TestnestedflatbufferLength()):
+ self.testnestedflatbuffer.append(monster.Testnestedflatbuffer(i))
+ else:
+ self.testnestedflatbuffer = monster.TestnestedflatbufferAsNumpy()
+ if monster.Testempty() is not None:
+ self.testempty = MyGame.Example.Stat.StatT.InitFromObj(monster.Testempty())
+ self.testbool = monster.Testbool()
+ self.testhashs32Fnv1 = monster.Testhashs32Fnv1()
+ self.testhashu32Fnv1 = monster.Testhashu32Fnv1()
+ self.testhashs64Fnv1 = monster.Testhashs64Fnv1()
+ self.testhashu64Fnv1 = monster.Testhashu64Fnv1()
+ self.testhashs32Fnv1a = monster.Testhashs32Fnv1a()
+ self.testhashu32Fnv1a = monster.Testhashu32Fnv1a()
+ self.testhashs64Fnv1a = monster.Testhashs64Fnv1a()
+ self.testhashu64Fnv1a = monster.Testhashu64Fnv1a()
+ if not monster.TestarrayofboolsIsNone():
+ if np is None:
+ self.testarrayofbools = []
+ for i in range(monster.TestarrayofboolsLength()):
+ self.testarrayofbools.append(monster.Testarrayofbools(i))
+ else:
+ self.testarrayofbools = monster.TestarrayofboolsAsNumpy()
+ self.testf = monster.Testf()
+ self.testf2 = monster.Testf2()
+ self.testf3 = monster.Testf3()
+ if not monster.Testarrayofstring2IsNone():
+ self.testarrayofstring2 = []
+ for i in range(monster.Testarrayofstring2Length()):
+ self.testarrayofstring2.append(monster.Testarrayofstring2(i))
+ if not monster.TestarrayofsortedstructIsNone():
+ self.testarrayofsortedstruct = []
+ for i in range(monster.TestarrayofsortedstructLength()):
+ if monster.Testarrayofsortedstruct(i) is None:
+ self.testarrayofsortedstruct.append(None)
+ else:
+ ability_ = MyGame.Example.Ability.AbilityT.InitFromObj(monster.Testarrayofsortedstruct(i))
+ self.testarrayofsortedstruct.append(ability_)
+ if not monster.FlexIsNone():
+ if np is None:
+ self.flex = []
+ for i in range(monster.FlexLength()):
+ self.flex.append(monster.Flex(i))
+ else:
+ self.flex = monster.FlexAsNumpy()
+ if not monster.Test5IsNone():
+ self.test5 = []
+ for i in range(monster.Test5Length()):
+ if monster.Test5(i) is None:
+ self.test5.append(None)
+ else:
+ test_ = MyGame.Example.Test.TestT.InitFromObj(monster.Test5(i))
+ self.test5.append(test_)
+ if not monster.VectorOfLongsIsNone():
+ if np is None:
+ self.vectorOfLongs = []
+ for i in range(monster.VectorOfLongsLength()):
+ self.vectorOfLongs.append(monster.VectorOfLongs(i))
+ else:
+ self.vectorOfLongs = monster.VectorOfLongsAsNumpy()
+ if not monster.VectorOfDoublesIsNone():
+ if np is None:
+ self.vectorOfDoubles = []
+ for i in range(monster.VectorOfDoublesLength()):
+ self.vectorOfDoubles.append(monster.VectorOfDoubles(i))
+ else:
+ self.vectorOfDoubles = monster.VectorOfDoublesAsNumpy()
+ if monster.ParentNamespaceTest() is not None:
+ self.parentNamespaceTest = MyGame.InParentNamespace.InParentNamespaceT.InitFromObj(monster.ParentNamespaceTest())
+ if not monster.VectorOfReferrablesIsNone():
+ self.vectorOfReferrables = []
+ for i in range(monster.VectorOfReferrablesLength()):
+ if monster.VectorOfReferrables(i) is None:
+ self.vectorOfReferrables.append(None)
+ else:
+ referrable_ = MyGame.Example.Referrable.ReferrableT.InitFromObj(monster.VectorOfReferrables(i))
+ self.vectorOfReferrables.append(referrable_)
+ self.singleWeakReference = monster.SingleWeakReference()
+ if not monster.VectorOfWeakReferencesIsNone():
+ if np is None:
+ self.vectorOfWeakReferences = []
+ for i in range(monster.VectorOfWeakReferencesLength()):
+ self.vectorOfWeakReferences.append(monster.VectorOfWeakReferences(i))
+ else:
+ self.vectorOfWeakReferences = monster.VectorOfWeakReferencesAsNumpy()
+ if not monster.VectorOfStrongReferrablesIsNone():
+ self.vectorOfStrongReferrables = []
+ for i in range(monster.VectorOfStrongReferrablesLength()):
+ if monster.VectorOfStrongReferrables(i) is None:
+ self.vectorOfStrongReferrables.append(None)
+ else:
+ referrable_ = MyGame.Example.Referrable.ReferrableT.InitFromObj(monster.VectorOfStrongReferrables(i))
+ self.vectorOfStrongReferrables.append(referrable_)
+ self.coOwningReference = monster.CoOwningReference()
+ if not monster.VectorOfCoOwningReferencesIsNone():
+ if np is None:
+ self.vectorOfCoOwningReferences = []
+ for i in range(monster.VectorOfCoOwningReferencesLength()):
+ self.vectorOfCoOwningReferences.append(monster.VectorOfCoOwningReferences(i))
+ else:
+ self.vectorOfCoOwningReferences = monster.VectorOfCoOwningReferencesAsNumpy()
+ self.nonOwningReference = monster.NonOwningReference()
+ if not monster.VectorOfNonOwningReferencesIsNone():
+ if np is None:
+ self.vectorOfNonOwningReferences = []
+ for i in range(monster.VectorOfNonOwningReferencesLength()):
+ self.vectorOfNonOwningReferences.append(monster.VectorOfNonOwningReferences(i))
+ else:
+ self.vectorOfNonOwningReferences = monster.VectorOfNonOwningReferencesAsNumpy()
+ self.anyUniqueType = monster.AnyUniqueType()
+ self.anyUnique = MyGame.Example.AnyUniqueAliases.AnyUniqueAliasesCreator(self.anyUniqueType, monster.AnyUnique())
+ self.anyAmbiguousType = monster.AnyAmbiguousType()
+ self.anyAmbiguous = MyGame.Example.AnyAmbiguousAliases.AnyAmbiguousAliasesCreator(self.anyAmbiguousType, monster.AnyAmbiguous())
+ if not monster.VectorOfEnumsIsNone():
+ if np is None:
+ self.vectorOfEnums = []
+ for i in range(monster.VectorOfEnumsLength()):
+ self.vectorOfEnums.append(monster.VectorOfEnums(i))
+ else:
+ self.vectorOfEnums = monster.VectorOfEnumsAsNumpy()
+ self.signedEnum = monster.SignedEnum()
+
+ # MonsterT
+ def Pack(self, builder):
+ if self.name is not None:
+ name = builder.CreateString(self.name)
+ if self.inventory is not None:
+ if np is not None and type(self.inventory) is np.ndarray:
+ inventory = builder.CreateNumpyVector(self.inventory)
+ else:
+ MonsterStartInventoryVector(builder, len(self.inventory))
+ for i in reversed(range(len(self.inventory))):
+ builder.PrependUint8(self.inventory[i])
+ inventory = builder.EndVector(len(self.inventory))
+ if self.test is not None:
+ test = self.test.Pack(builder)
+ if self.test4 is not None:
+ MonsterStartTest4Vector(builder, len(self.test4))
+ for i in reversed(range(len(self.test4))):
+ self.test4[i].Pack(builder)
+ test4 = builder.EndVector(len(self.test4))
+ if self.testarrayofstring is not None:
+ testarrayofstringlist = []
+ for i in range(len(self.testarrayofstring)):
+ testarrayofstringlist.append(builder.CreateString(self.testarrayofstring[i]))
+ MonsterStartTestarrayofstringVector(builder, len(self.testarrayofstring))
+ for i in reversed(range(len(self.testarrayofstring))):
+ builder.PrependUOffsetTRelative(testarrayofstringlist[i])
+ testarrayofstring = builder.EndVector(len(self.testarrayofstring))
+ if self.testarrayoftables is not None:
+ testarrayoftableslist = []
+ for i in range(len(self.testarrayoftables)):
+ testarrayoftableslist.append(self.testarrayoftables[i].Pack(builder))
+ MonsterStartTestarrayoftablesVector(builder, len(self.testarrayoftables))
+ for i in reversed(range(len(self.testarrayoftables))):
+ builder.PrependUOffsetTRelative(testarrayoftableslist[i])
+ testarrayoftables = builder.EndVector(len(self.testarrayoftables))
+ if self.enemy is not None:
+ enemy = self.enemy.Pack(builder)
+ if self.testnestedflatbuffer is not None:
+ if np is not None and type(self.testnestedflatbuffer) is np.ndarray:
+ testnestedflatbuffer = builder.CreateNumpyVector(self.testnestedflatbuffer)
+ else:
+ MonsterStartTestnestedflatbufferVector(builder, len(self.testnestedflatbuffer))
+ for i in reversed(range(len(self.testnestedflatbuffer))):
+ builder.PrependUint8(self.testnestedflatbuffer[i])
+ testnestedflatbuffer = builder.EndVector(len(self.testnestedflatbuffer))
+ if self.testempty is not None:
+ testempty = self.testempty.Pack(builder)
+ if self.testarrayofbools is not None:
+ if np is not None and type(self.testarrayofbools) is np.ndarray:
+ testarrayofbools = builder.CreateNumpyVector(self.testarrayofbools)
+ else:
+ MonsterStartTestarrayofboolsVector(builder, len(self.testarrayofbools))
+ for i in reversed(range(len(self.testarrayofbools))):
+ builder.PrependBool(self.testarrayofbools[i])
+ testarrayofbools = builder.EndVector(len(self.testarrayofbools))
+ if self.testarrayofstring2 is not None:
+ testarrayofstring2list = []
+ for i in range(len(self.testarrayofstring2)):
+ testarrayofstring2list.append(builder.CreateString(self.testarrayofstring2[i]))
+ MonsterStartTestarrayofstring2Vector(builder, len(self.testarrayofstring2))
+ for i in reversed(range(len(self.testarrayofstring2))):
+ builder.PrependUOffsetTRelative(testarrayofstring2list[i])
+ testarrayofstring2 = builder.EndVector(len(self.testarrayofstring2))
+ if self.testarrayofsortedstruct is not None:
+ MonsterStartTestarrayofsortedstructVector(builder, len(self.testarrayofsortedstruct))
+ for i in reversed(range(len(self.testarrayofsortedstruct))):
+ self.testarrayofsortedstruct[i].Pack(builder)
+ testarrayofsortedstruct = builder.EndVector(len(self.testarrayofsortedstruct))
+ if self.flex is not None:
+ if np is not None and type(self.flex) is np.ndarray:
+ flex = builder.CreateNumpyVector(self.flex)
+ else:
+ MonsterStartFlexVector(builder, len(self.flex))
+ for i in reversed(range(len(self.flex))):
+ builder.PrependUint8(self.flex[i])
+ flex = builder.EndVector(len(self.flex))
+ if self.test5 is not None:
+ MonsterStartTest5Vector(builder, len(self.test5))
+ for i in reversed(range(len(self.test5))):
+ self.test5[i].Pack(builder)
+ test5 = builder.EndVector(len(self.test5))
+ if self.vectorOfLongs is not None:
+ if np is not None and type(self.vectorOfLongs) is np.ndarray:
+ vectorOfLongs = builder.CreateNumpyVector(self.vectorOfLongs)
+ else:
+ MonsterStartVectorOfLongsVector(builder, len(self.vectorOfLongs))
+ for i in reversed(range(len(self.vectorOfLongs))):
+ builder.PrependInt64(self.vectorOfLongs[i])
+ vectorOfLongs = builder.EndVector(len(self.vectorOfLongs))
+ if self.vectorOfDoubles is not None:
+ if np is not None and type(self.vectorOfDoubles) is np.ndarray:
+ vectorOfDoubles = builder.CreateNumpyVector(self.vectorOfDoubles)
+ else:
+ MonsterStartVectorOfDoublesVector(builder, len(self.vectorOfDoubles))
+ for i in reversed(range(len(self.vectorOfDoubles))):
+ builder.PrependFloat64(self.vectorOfDoubles[i])
+ vectorOfDoubles = builder.EndVector(len(self.vectorOfDoubles))
+ if self.parentNamespaceTest is not None:
+ parentNamespaceTest = self.parentNamespaceTest.Pack(builder)
+ if self.vectorOfReferrables is not None:
+ vectorOfReferrableslist = []
+ for i in range(len(self.vectorOfReferrables)):
+ vectorOfReferrableslist.append(self.vectorOfReferrables[i].Pack(builder))
+ MonsterStartVectorOfReferrablesVector(builder, len(self.vectorOfReferrables))
+ for i in reversed(range(len(self.vectorOfReferrables))):
+ builder.PrependUOffsetTRelative(vectorOfReferrableslist[i])
+ vectorOfReferrables = builder.EndVector(len(self.vectorOfReferrables))
+ if self.vectorOfWeakReferences is not None:
+ if np is not None and type(self.vectorOfWeakReferences) is np.ndarray:
+ vectorOfWeakReferences = builder.CreateNumpyVector(self.vectorOfWeakReferences)
+ else:
+ MonsterStartVectorOfWeakReferencesVector(builder, len(self.vectorOfWeakReferences))
+ for i in reversed(range(len(self.vectorOfWeakReferences))):
+ builder.PrependUint64(self.vectorOfWeakReferences[i])
+ vectorOfWeakReferences = builder.EndVector(len(self.vectorOfWeakReferences))
+ if self.vectorOfStrongReferrables is not None:
+ vectorOfStrongReferrableslist = []
+ for i in range(len(self.vectorOfStrongReferrables)):
+ vectorOfStrongReferrableslist.append(self.vectorOfStrongReferrables[i].Pack(builder))
+ MonsterStartVectorOfStrongReferrablesVector(builder, len(self.vectorOfStrongReferrables))
+ for i in reversed(range(len(self.vectorOfStrongReferrables))):
+ builder.PrependUOffsetTRelative(vectorOfStrongReferrableslist[i])
+ vectorOfStrongReferrables = builder.EndVector(len(self.vectorOfStrongReferrables))
+ if self.vectorOfCoOwningReferences is not None:
+ if np is not None and type(self.vectorOfCoOwningReferences) is np.ndarray:
+ vectorOfCoOwningReferences = builder.CreateNumpyVector(self.vectorOfCoOwningReferences)
+ else:
+ MonsterStartVectorOfCoOwningReferencesVector(builder, len(self.vectorOfCoOwningReferences))
+ for i in reversed(range(len(self.vectorOfCoOwningReferences))):
+ builder.PrependUint64(self.vectorOfCoOwningReferences[i])
+ vectorOfCoOwningReferences = builder.EndVector(len(self.vectorOfCoOwningReferences))
+ if self.vectorOfNonOwningReferences is not None:
+ if np is not None and type(self.vectorOfNonOwningReferences) is np.ndarray:
+ vectorOfNonOwningReferences = builder.CreateNumpyVector(self.vectorOfNonOwningReferences)
+ else:
+ MonsterStartVectorOfNonOwningReferencesVector(builder, len(self.vectorOfNonOwningReferences))
+ for i in reversed(range(len(self.vectorOfNonOwningReferences))):
+ builder.PrependUint64(self.vectorOfNonOwningReferences[i])
+ vectorOfNonOwningReferences = builder.EndVector(len(self.vectorOfNonOwningReferences))
+ if self.anyUnique is not None:
+ anyUnique = self.anyUnique.Pack(builder)
+ if self.anyAmbiguous is not None:
+ anyAmbiguous = self.anyAmbiguous.Pack(builder)
+ if self.vectorOfEnums is not None:
+ if np is not None and type(self.vectorOfEnums) is np.ndarray:
+ vectorOfEnums = builder.CreateNumpyVector(self.vectorOfEnums)
+ else:
+ MonsterStartVectorOfEnumsVector(builder, len(self.vectorOfEnums))
+ for i in reversed(range(len(self.vectorOfEnums))):
+ builder.PrependUint8(self.vectorOfEnums[i])
+ vectorOfEnums = builder.EndVector(len(self.vectorOfEnums))
+ MonsterStart(builder)
+ if self.pos is not None:
+ pos = self.pos.Pack(builder)
+ MonsterAddPos(builder, pos)
+ MonsterAddMana(builder, self.mana)
+ MonsterAddHp(builder, self.hp)
+ if self.name is not None:
+ MonsterAddName(builder, name)
+ if self.inventory is not None:
+ MonsterAddInventory(builder, inventory)
+ MonsterAddColor(builder, self.color)
+ MonsterAddTestType(builder, self.testType)
+ if self.test is not None:
+ MonsterAddTest(builder, test)
+ if self.test4 is not None:
+ MonsterAddTest4(builder, test4)
+ if self.testarrayofstring is not None:
+ MonsterAddTestarrayofstring(builder, testarrayofstring)
+ if self.testarrayoftables is not None:
+ MonsterAddTestarrayoftables(builder, testarrayoftables)
+ if self.enemy is not None:
+ MonsterAddEnemy(builder, enemy)
+ if self.testnestedflatbuffer is not None:
+ MonsterAddTestnestedflatbuffer(builder, testnestedflatbuffer)
+ if self.testempty is not None:
+ MonsterAddTestempty(builder, testempty)
+ MonsterAddTestbool(builder, self.testbool)
+ MonsterAddTesthashs32Fnv1(builder, self.testhashs32Fnv1)
+ MonsterAddTesthashu32Fnv1(builder, self.testhashu32Fnv1)
+ MonsterAddTesthashs64Fnv1(builder, self.testhashs64Fnv1)
+ MonsterAddTesthashu64Fnv1(builder, self.testhashu64Fnv1)
+ MonsterAddTesthashs32Fnv1a(builder, self.testhashs32Fnv1a)
+ MonsterAddTesthashu32Fnv1a(builder, self.testhashu32Fnv1a)
+ MonsterAddTesthashs64Fnv1a(builder, self.testhashs64Fnv1a)
+ MonsterAddTesthashu64Fnv1a(builder, self.testhashu64Fnv1a)
+ if self.testarrayofbools is not None:
+ MonsterAddTestarrayofbools(builder, testarrayofbools)
+ MonsterAddTestf(builder, self.testf)
+ MonsterAddTestf2(builder, self.testf2)
+ MonsterAddTestf3(builder, self.testf3)
+ if self.testarrayofstring2 is not None:
+ MonsterAddTestarrayofstring2(builder, testarrayofstring2)
+ if self.testarrayofsortedstruct is not None:
+ MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstruct)
+ if self.flex is not None:
+ MonsterAddFlex(builder, flex)
+ if self.test5 is not None:
+ MonsterAddTest5(builder, test5)
+ if self.vectorOfLongs is not None:
+ MonsterAddVectorOfLongs(builder, vectorOfLongs)
+ if self.vectorOfDoubles is not None:
+ MonsterAddVectorOfDoubles(builder, vectorOfDoubles)
+ if self.parentNamespaceTest is not None:
+ MonsterAddParentNamespaceTest(builder, parentNamespaceTest)
+ if self.vectorOfReferrables is not None:
+ MonsterAddVectorOfReferrables(builder, vectorOfReferrables)
+ MonsterAddSingleWeakReference(builder, self.singleWeakReference)
+ if self.vectorOfWeakReferences is not None:
+ MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferences)
+ if self.vectorOfStrongReferrables is not None:
+ MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrables)
+ MonsterAddCoOwningReference(builder, self.coOwningReference)
+ if self.vectorOfCoOwningReferences is not None:
+ MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferences)
+ MonsterAddNonOwningReference(builder, self.nonOwningReference)
+ if self.vectorOfNonOwningReferences is not None:
+ MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferences)
+ MonsterAddAnyUniqueType(builder, self.anyUniqueType)
+ if self.anyUnique is not None:
+ MonsterAddAnyUnique(builder, anyUnique)
+ MonsterAddAnyAmbiguousType(builder, self.anyAmbiguousType)
+ if self.anyAmbiguous is not None:
+ MonsterAddAnyAmbiguous(builder, anyAmbiguous)
+ if self.vectorOfEnums is not None:
+ MonsterAddVectorOfEnums(builder, vectorOfEnums)
+ MonsterAddSignedEnum(builder, self.signedEnum)
+ monster = MonsterEnd(builder)
+ return monster
diff --git a/tests/MyGame/Example/MonsterStorageGrpc.java b/tests/MyGame/Example/MonsterStorageGrpc.java
index 9111328d..8e468d48 100644
--- a/tests/MyGame/Example/MonsterStorageGrpc.java
+++ b/tests/MyGame/Example/MonsterStorageGrpc.java
@@ -1,4 +1,4 @@
-//Generated by flatc compiler (version 1.10.0)
+//Generated by flatc compiler (version 1.12.0)
//If you make any local changes, they will be lost
//source: monster_test.fbs
diff --git a/tests/MyGame/Example/NestedStruct.cs b/tests/MyGame/Example/NestedStruct.cs
new file mode 100644
index 00000000..13e34984
--- /dev/null
+++ b/tests/MyGame/Example/NestedStruct.cs
@@ -0,0 +1,91 @@
+// <auto-generated>
+// automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+using global::System;
+using global::System.Collections.Generic;
+using global::FlatBuffers;
+
+public struct NestedStruct : IFlatbufferObject
+{
+ private Struct __p;
+ public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
+ public NestedStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+ public int A(int j) { return __p.bb.GetInt(__p.bb_pos + 0 + j * 4); }
+ public void MutateA(int j, int a) { __p.bb.PutInt(__p.bb_pos + 0 + j * 4, a); }
+ public MyGame.Example.TestEnum B { get { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 8); } }
+ public void MutateB(MyGame.Example.TestEnum b) { __p.bb.PutSbyte(__p.bb_pos + 8, (sbyte)b); }
+ public MyGame.Example.TestEnum C(int j) { return (MyGame.Example.TestEnum)__p.bb.GetSbyte(__p.bb_pos + 9 + j * 1); }
+ public void MutateC(int j, MyGame.Example.TestEnum c) { __p.bb.PutSbyte(__p.bb_pos + 9 + j * 1, (sbyte)c); }
+ public long D(int j) { return __p.bb.GetLong(__p.bb_pos + 16 + j * 8); }
+ public void MutateD(int j, long d) { __p.bb.PutLong(__p.bb_pos + 16 + j * 8, d); }
+
+ public static Offset<MyGame.Example.NestedStruct> CreateNestedStruct(FlatBufferBuilder builder, int[] A, MyGame.Example.TestEnum B, MyGame.Example.TestEnum[] C, long[] D) {
+ builder.Prep(8, 32);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.PutLong(D[_idx0-1]);
+ }
+ builder.Pad(5);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.PutSbyte((sbyte)C[_idx0-1]);
+ }
+ builder.PutSbyte((sbyte)B);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.PutInt(A[_idx0-1]);
+ }
+ return new Offset<MyGame.Example.NestedStruct>(builder.Offset);
+ }
+ public NestedStructT UnPack() {
+ var _o = new NestedStructT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(NestedStructT _o) {
+ _o.A = new int[2];
+ for (var _j = 0; _j < 2; ++_j) { _o.A[_j] = this.A(_j); }
+ _o.B = this.B;
+ _o.C = new MyGame.Example.TestEnum[2];
+ for (var _j = 0; _j < 2; ++_j) { _o.C[_j] = this.C(_j); }
+ _o.D = new long[2];
+ for (var _j = 0; _j < 2; ++_j) { _o.D[_j] = this.D(_j); }
+ }
+ public static Offset<MyGame.Example.NestedStruct> Pack(FlatBufferBuilder builder, NestedStructT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.NestedStruct>);
+ var _a = _o.A;
+ var _c = _o.C;
+ var _d = _o.D;
+ return CreateNestedStruct(
+ builder,
+ _a,
+ _o.B,
+ _c,
+ _d);
+ }
+};
+
+public class NestedStructT
+{
+ [Newtonsoft.Json.JsonProperty("a")]
+ public int[] A { get; set; }
+ [Newtonsoft.Json.JsonProperty("b")]
+ public MyGame.Example.TestEnum B { get; set; }
+ [Newtonsoft.Json.JsonProperty("c")]
+ public MyGame.Example.TestEnum[] C { get; set; }
+ [Newtonsoft.Json.JsonProperty("d")]
+ public long[] D { get; set; }
+
+ public NestedStructT() {
+ this.A = new int[2];
+ this.B = MyGame.Example.TestEnum.A;
+ this.C = new MyGame.Example.TestEnum[2];
+ this.D = new long[2];
+ }
+}
+
+
+}
diff --git a/tests/MyGame/Example/NestedStruct.java b/tests/MyGame/Example/NestedStruct.java
new file mode 100644
index 00000000..fbfedd8d
--- /dev/null
+++ b/tests/MyGame/Example/NestedStruct.java
@@ -0,0 +1,47 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+import java.nio.*;
+import java.lang.*;
+import java.util.*;
+import com.google.flatbuffers.*;
+
+@SuppressWarnings("unused")
+public final class NestedStruct extends Struct {
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
+ public NestedStruct __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
+
+ public int a(int j) { return bb.getInt(bb_pos + 0 + j * 4); }
+ public void mutateA(int j, int a) { bb.putInt(bb_pos + 0 + j * 4, a); }
+ public byte b() { return bb.get(bb_pos + 8); }
+ public void mutateB(byte b) { bb.put(bb_pos + 8, b); }
+ public byte c(int j) { return bb.get(bb_pos + 9 + j * 1); }
+ public void mutateC(int j, byte c) { bb.put(bb_pos + 9 + j * 1, c); }
+ public long d(int j) { return bb.getLong(bb_pos + 16 + j * 8); }
+ public void mutateD(int j, long d) { bb.putLong(bb_pos + 16 + j * 8, d); }
+
+ public static int createNestedStruct(FlatBufferBuilder builder, int[] a, byte b, byte[] c, long[] d) {
+ builder.prep(8, 32);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.putLong(d[_idx0-1]);
+ }
+ builder.pad(5);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.putByte(c[_idx0-1]);
+ }
+ builder.putByte(b);
+ for (int _idx0 = 2; _idx0 > 0; _idx0--) {
+ builder.putInt(a[_idx0-1]);
+ }
+ return builder.offset();
+ }
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public NestedStruct get(int j) { return get(new NestedStruct(), j); }
+ public NestedStruct get(NestedStruct obj, int j) { return obj.__assign(__element(j), bb); }
+ }
+}
+
diff --git a/tests/MyGame/Example/NestedStruct.py b/tests/MyGame/Example/NestedStruct.py
new file mode 100644
index 00000000..a66cee01
--- /dev/null
+++ b/tests/MyGame/Example/NestedStruct.py
@@ -0,0 +1,128 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
+
+class NestedStruct(object):
+ __slots__ = ['_tab']
+
+ # NestedStruct
+ def Init(self, buf, pos):
+ self._tab = flatbuffers.table.Table(buf, pos)
+
+ # NestedStruct
+ def A(self): return [self._tab.Get(flatbuffers.number_types.Int32Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(0 + i * 4)) for i in range(2)]
+ # NestedStruct
+ def ALength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(0))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # NestedStruct
+ def AIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(0))
+ return o == 0
+
+ # NestedStruct
+ def B(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(8))
+ # NestedStruct
+ def C(self): return [self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(9 + i * 1)) for i in range(2)]
+ # NestedStruct
+ def CLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(9))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # NestedStruct
+ def CIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(9))
+ return o == 0
+
+ # NestedStruct
+ def D(self): return [self._tab.Get(flatbuffers.number_types.Int64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(16 + i * 8)) for i in range(2)]
+ # NestedStruct
+ def DLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # NestedStruct
+ def DIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+ return o == 0
+
+
+def CreateNestedStruct(builder, a, b, c, d):
+ builder.Prep(8, 32)
+ for _idx0 in range(2 , 0, -1):
+ builder.PrependInt64(d[_idx0-1])
+ builder.Pad(5)
+ for _idx0 in range(2 , 0, -1):
+ builder.PrependInt8(c[_idx0-1])
+ builder.PrependInt8(b)
+ for _idx0 in range(2 , 0, -1):
+ builder.PrependInt32(a[_idx0-1])
+ return builder.Offset()
+
+try:
+ from typing import List
+except:
+ pass
+
+class NestedStructT(object):
+
+ # NestedStructT
+ def __init__(self):
+ self.a = None # type: List[int]
+ self.b = 0 # type: int
+ self.c = None # type: List[int]
+ self.d = None # type: List[int]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ nestedStruct = NestedStruct()
+ nestedStruct.Init(buf, pos)
+ return cls.InitFromObj(nestedStruct)
+
+ @classmethod
+ def InitFromObj(cls, nestedStruct):
+ x = NestedStructT()
+ x._UnPack(nestedStruct)
+ return x
+
+ # NestedStructT
+ def _UnPack(self, nestedStruct):
+ if nestedStruct is None:
+ return
+ if not nestedStruct.AIsNone():
+ if np is None:
+ self.a = []
+ for i in range(nestedStruct.ALength()):
+ self.a.append(nestedStruct.A(i))
+ else:
+ self.a = nestedStruct.AAsNumpy()
+ self.b = nestedStruct.B()
+ if not nestedStruct.CIsNone():
+ if np is None:
+ self.c = []
+ for i in range(nestedStruct.CLength()):
+ self.c.append(nestedStruct.C(i))
+ else:
+ self.c = nestedStruct.CAsNumpy()
+ if not nestedStruct.DIsNone():
+ if np is None:
+ self.d = []
+ for i in range(nestedStruct.DLength()):
+ self.d.append(nestedStruct.D(i))
+ else:
+ self.d = nestedStruct.DAsNumpy()
+
+ # NestedStructT
+ def Pack(self, builder):
+ return CreateNestedStruct(builder, self.a, self.b, self.c, self.d)
diff --git a/tests/MyGame/Example/Race.cs b/tests/MyGame/Example/Race.cs
new file mode 100644
index 00000000..8a1959a8
--- /dev/null
+++ b/tests/MyGame/Example/Race.cs
@@ -0,0 +1,18 @@
+// <auto-generated>
+// automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
+public enum Race : sbyte
+{
+ None = -1,
+ Human = 0,
+ Dwarf = 1,
+ Elf = 2,
+};
+
+
+}
diff --git a/tests/MyGame/Example/Race.go b/tests/MyGame/Example/Race.go
new file mode 100644
index 00000000..0762bca0
--- /dev/null
+++ b/tests/MyGame/Example/Race.go
@@ -0,0 +1,35 @@
+// Code generated by the FlatBuffers compiler. DO NOT EDIT.
+
+package Example
+
+import "strconv"
+
+type Race int8
+
+const (
+ RaceNone Race = -1
+ RaceHuman Race = 0
+ RaceDwarf Race = 1
+ RaceElf Race = 2
+)
+
+var EnumNamesRace = map[Race]string{
+ RaceNone: "None",
+ RaceHuman: "Human",
+ RaceDwarf: "Dwarf",
+ RaceElf: "Elf",
+}
+
+var EnumValuesRace = map[string]Race{
+ "None": RaceNone,
+ "Human": RaceHuman,
+ "Dwarf": RaceDwarf,
+ "Elf": RaceElf,
+}
+
+func (v Race) String() string {
+ if s, ok := EnumNamesRace[v]; ok {
+ return s
+ }
+ return "Race(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/tests/MyGame/Example/Race.java b/tests/MyGame/Example/Race.java
new file mode 100644
index 00000000..0dfd80bf
--- /dev/null
+++ b/tests/MyGame/Example/Race.java
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class Race {
+ private Race() { }
+ public static final byte None = -1;
+ public static final byte Human = 0;
+ public static final byte Dwarf = 1;
+ public static final byte Elf = 2;
+
+ public static final String[] names = { "None", "Human", "Dwarf", "Elf", };
+
+ public static String name(int e) { return names[e - None]; }
+}
+
diff --git a/tests/MyGame/Example/Race.kt b/tests/MyGame/Example/Race.kt
new file mode 100644
index 00000000..6eb95348
--- /dev/null
+++ b/tests/MyGame/Example/Race.kt
@@ -0,0 +1,16 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Race private constructor() {
+ companion object {
+ const val None: Byte = -1
+ const val Human: Byte = 0
+ const val Dwarf: Byte = 1
+ const val Elf: Byte = 2
+ val names : Array<String> = arrayOf("None", "Human", "Dwarf", "Elf")
+ fun name(e: Int) : String = names[e - None.toInt()]
+ }
+}
diff --git a/tests/MyGame/Example/Race.lua b/tests/MyGame/Example/Race.lua
new file mode 100644
index 00000000..646f374f
--- /dev/null
+++ b/tests/MyGame/Example/Race.lua
@@ -0,0 +1,12 @@
+-- automatically generated by the FlatBuffers compiler, do not modify
+
+-- namespace: Example
+
+local Race = {
+ None = -1,
+ Human = 0,
+ Dwarf = 1,
+ Elf = 2,
+}
+
+return Race -- return the module \ No newline at end of file
diff --git a/tests/MyGame/Example/Race.php b/tests/MyGame/Example/Race.php
new file mode 100644
index 00000000..3f05c43c
--- /dev/null
+++ b/tests/MyGame/Example/Race.php
@@ -0,0 +1,27 @@
+<?php
+// automatically generated by the FlatBuffers compiler, do not modify
+
+namespace MyGame\Example;
+
+class Race
+{
+ const None = -1;
+ const Human = 0;
+ const Dwarf = 1;
+ const Elf = 2;
+
+ private static $names = array(
+ Race::None=>"None",
+ Race::Human=>"Human",
+ Race::Dwarf=>"Dwarf",
+ Race::Elf=>"Elf",
+ );
+
+ public static function Name($e)
+ {
+ if (!isset(self::$names[$e])) {
+ throw new \Exception();
+ }
+ return self::$names[$e];
+ }
+}
diff --git a/tests/MyGame/Example/Race.py b/tests/MyGame/Example/Race.py
new file mode 100644
index 00000000..a39c6ead
--- /dev/null
+++ b/tests/MyGame/Example/Race.py
@@ -0,0 +1,10 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class Race(object):
+ None_ = -1
+ Human = 0
+ Dwarf = 1
+ Elf = 2
+
diff --git a/tests/MyGame/Example/Referrable.cs b/tests/MyGame/Example/Referrable.cs
index ce068087..81394ade 100644
--- a/tests/MyGame/Example/Referrable.cs
+++ b/tests/MyGame/Example/Referrable.cs
@@ -6,32 +6,34 @@ namespace MyGame.Example
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Referrable : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static Referrable GetRootAsReferrable(ByteBuffer _bb) { return GetRootAsReferrable(_bb, new Referrable()); }
public static Referrable GetRootAsReferrable(ByteBuffer _bb, Referrable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Referrable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public ulong Id { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
public bool MutateId(ulong id) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, id); return true; } else { return false; } }
- public static Offset<Referrable> CreateReferrable(FlatBufferBuilder builder,
+ public static Offset<MyGame.Example.Referrable> CreateReferrable(FlatBufferBuilder builder,
ulong id = 0) {
- builder.StartObject(1);
+ builder.StartTable(1);
Referrable.AddId(builder, id);
return Referrable.EndReferrable(builder);
}
- public static void StartReferrable(FlatBufferBuilder builder) { builder.StartObject(1); }
+ public static void StartReferrable(FlatBufferBuilder builder) { builder.StartTable(1); }
public static void AddId(FlatBufferBuilder builder, ulong id) { builder.AddUlong(0, id, 0); }
- public static Offset<Referrable> EndReferrable(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<Referrable>(o);
+ public static Offset<MyGame.Example.Referrable> EndReferrable(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<MyGame.Example.Referrable>(o);
}
public static VectorOffset CreateSortedVectorOfReferrable(FlatBufferBuilder builder, Offset<Referrable>[] offsets) {
@@ -58,7 +60,32 @@ public struct Referrable : IFlatbufferObject
}
return null;
}
+ public ReferrableT UnPack() {
+ var _o = new ReferrableT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(ReferrableT _o) {
+ _o.Id = this.Id;
+ }
+ public static Offset<MyGame.Example.Referrable> Pack(FlatBufferBuilder builder, ReferrableT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.Referrable>);
+ return CreateReferrable(
+ builder,
+ _o.Id);
+ }
};
+public class ReferrableT
+{
+ [Newtonsoft.Json.JsonProperty("id")]
+ [Newtonsoft.Json.JsonIgnore()]
+ public ulong Id { get; set; }
+
+ public ReferrableT() {
+ this.Id = 0;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Referrable.go b/tests/MyGame/Example/Referrable.go
index 0fb06fb2..8f21e910 100644
--- a/tests/MyGame/Example/Referrable.go
+++ b/tests/MyGame/Example/Referrable.go
@@ -6,6 +6,28 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type ReferrableT struct {
+ Id uint64
+}
+
+func (t *ReferrableT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ ReferrableStart(builder)
+ ReferrableAddId(builder, t.Id)
+ return ReferrableEnd(builder)
+}
+
+func (rcv *Referrable) UnPackTo(t *ReferrableT) {
+ t.Id = rcv.Id()
+}
+
+func (rcv *Referrable) UnPack() *ReferrableT {
+ if rcv == nil { return nil }
+ t := &ReferrableT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type Referrable struct {
_tab flatbuffers.Table
}
diff --git a/tests/MyGame/Example/Referrable.java b/tests/MyGame/Example/Referrable.java
index 6a117451..1f92958a 100644
--- a/tests/MyGame/Example/Referrable.java
+++ b/tests/MyGame/Example/Referrable.java
@@ -9,9 +9,10 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Referrable extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static Referrable getRootAsReferrable(ByteBuffer _bb) { return getRootAsReferrable(_bb, new Referrable()); }
public static Referrable getRootAsReferrable(ByteBuffer _bb, Referrable obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Referrable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public long id() { int o = __offset(4); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
@@ -19,15 +20,15 @@ public final class Referrable extends Table {
public static int createReferrable(FlatBufferBuilder builder,
long id) {
- builder.startObject(1);
+ builder.startTable(1);
Referrable.addId(builder, id);
return Referrable.endReferrable(builder);
}
- public static void startReferrable(FlatBufferBuilder builder) { builder.startObject(1); }
+ public static void startReferrable(FlatBufferBuilder builder) { builder.startTable(1); }
public static void addId(FlatBufferBuilder builder, long id) { builder.addLong(0, id, 0L); }
public static int endReferrable(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
@@ -58,5 +59,14 @@ public final class Referrable extends Table {
}
return null;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Referrable get(int j) { return get(new Referrable(), j); }
+ public Referrable get(Referrable obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ public Referrable getByKey(long key) { return __lookup_by_key(null, __vector(), key, bb); }
+ public Referrable getByKey(Referrable obj, long key) { return __lookup_by_key(obj, __vector(), key, bb); }
+ }
}
diff --git a/tests/MyGame/Example/Referrable.kt b/tests/MyGame/Example/Referrable.kt
new file mode 100644
index 00000000..2e78c934
--- /dev/null
+++ b/tests/MyGame/Example/Referrable.kt
@@ -0,0 +1,80 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Referrable : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Referrable {
+ __init(_i, _bb)
+ return this
+ }
+ val id : ULong
+ get() {
+ val o = __offset(4)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+ }
+ fun mutateId(id: ULong) : Boolean {
+ val o = __offset(4)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, id.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ override fun keysCompare(o1: Int, o2: Int, _bb: ByteBuffer) : Int {
+ val val_1 = _bb.getLong(__offset(4, o1, _bb))
+ val val_2 = _bb.getLong(__offset(4, o2, _bb))
+ return (val_1 - val_2).sign
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsReferrable(_bb: ByteBuffer): Referrable = getRootAsReferrable(_bb, Referrable())
+ fun getRootAsReferrable(_bb: ByteBuffer, obj: Referrable): Referrable {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createReferrable(builder: FlatBufferBuilder, id: ULong) : Int {
+ builder.startTable(1)
+ addId(builder, id)
+ return endReferrable(builder)
+ }
+ fun startReferrable(builder: FlatBufferBuilder) = builder.startTable(1)
+ fun addId(builder: FlatBufferBuilder, id: ULong) = builder.addLong(0, id.toLong(), 0)
+ fun endReferrable(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ fun __lookup_by_key(obj: Referrable?, vectorLocation: Int, key: ULong, bb: ByteBuffer) : Referrable? {
+ var span = bb.getInt(vectorLocation - 4)
+ var start = 0
+ while (span != 0) {
+ var middle = span / 2
+ val tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb)
+ val value = bb.getLong(__offset(4, bb.capacity() - tableOffset, bb)).toULong()
+ val comp = value.compareTo(key)
+ when {
+ comp > 0 -> span = middle
+ comp < 0 -> {
+ middle++
+ start += middle
+ span -= middle
+ }
+ else -> {
+ return (obj ?: Referrable()).__assign(tableOffset, bb)
+ }
+ }
+ }
+ return null
+ }
+ }
+}
diff --git a/tests/MyGame/Example/Referrable.py b/tests/MyGame/Example/Referrable.py
index 897b4ac4..44bf50f4 100644
--- a/tests/MyGame/Example/Referrable.py
+++ b/tests/MyGame/Example/Referrable.py
@@ -3,6 +3,8 @@
# namespace: Example
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class Referrable(object):
__slots__ = ['_tab']
@@ -14,6 +16,10 @@ class Referrable(object):
x.Init(buf, n + offset)
return x
+ @classmethod
+ def ReferrableBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
# Referrable
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
@@ -28,3 +34,35 @@ class Referrable(object):
def ReferrableStart(builder): builder.StartObject(1)
def ReferrableAddId(builder, id): builder.PrependUint64Slot(0, id, 0)
def ReferrableEnd(builder): return builder.EndObject()
+
+
+class ReferrableT(object):
+
+ # ReferrableT
+ def __init__(self):
+ self.id = 0 # type: int
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ referrable = Referrable()
+ referrable.Init(buf, pos)
+ return cls.InitFromObj(referrable)
+
+ @classmethod
+ def InitFromObj(cls, referrable):
+ x = ReferrableT()
+ x._UnPack(referrable)
+ return x
+
+ # ReferrableT
+ def _UnPack(self, referrable):
+ if referrable is None:
+ return
+ self.id = referrable.Id()
+
+ # ReferrableT
+ def Pack(self, builder):
+ ReferrableStart(builder)
+ ReferrableAddId(builder, self.id)
+ referrable = ReferrableEnd(builder)
+ return referrable
diff --git a/tests/MyGame/Example/Stat.cs b/tests/MyGame/Example/Stat.cs
index fdd7e856..6f19ed40 100644
--- a/tests/MyGame/Example/Stat.cs
+++ b/tests/MyGame/Example/Stat.cs
@@ -6,20 +6,22 @@ namespace MyGame.Example
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Stat : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static Stat GetRootAsStat(ByteBuffer _bb) { return GetRootAsStat(_bb, new Stat()); }
public static Stat GetRootAsStat(ByteBuffer _bb, Stat obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Stat __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public string Id { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
#if ENABLE_SPAN_T
- public Span<byte> GetIdBytes() { return __p.__vector_as_span(4); }
+ public Span<byte> GetIdBytes() { return __p.__vector_as_span<byte>(4, 1); }
#else
public ArraySegment<byte>? GetIdBytes() { return __p.__vector_as_arraysegment(4); }
#endif
@@ -29,26 +31,61 @@ public struct Stat : IFlatbufferObject
public ushort Count { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
public bool MutateCount(ushort count) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutUshort(o + __p.bb_pos, count); return true; } else { return false; } }
- public static Offset<Stat> CreateStat(FlatBufferBuilder builder,
+ public static Offset<MyGame.Example.Stat> CreateStat(FlatBufferBuilder builder,
StringOffset idOffset = default(StringOffset),
long val = 0,
ushort count = 0) {
- builder.StartObject(3);
+ builder.StartTable(3);
Stat.AddVal(builder, val);
Stat.AddId(builder, idOffset);
Stat.AddCount(builder, count);
return Stat.EndStat(builder);
}
- public static void StartStat(FlatBufferBuilder builder) { builder.StartObject(3); }
+ public static void StartStat(FlatBufferBuilder builder) { builder.StartTable(3); }
public static void AddId(FlatBufferBuilder builder, StringOffset idOffset) { builder.AddOffset(0, idOffset.Value, 0); }
public static void AddVal(FlatBufferBuilder builder, long val) { builder.AddLong(1, val, 0); }
public static void AddCount(FlatBufferBuilder builder, ushort count) { builder.AddUshort(2, count, 0); }
- public static Offset<Stat> EndStat(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<Stat>(o);
+ public static Offset<MyGame.Example.Stat> EndStat(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<MyGame.Example.Stat>(o);
+ }
+ public StatT UnPack() {
+ var _o = new StatT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(StatT _o) {
+ _o.Id = this.Id;
+ _o.Val = this.Val;
+ _o.Count = this.Count;
+ }
+ public static Offset<MyGame.Example.Stat> Pack(FlatBufferBuilder builder, StatT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.Stat>);
+ var _id = _o.Id == null ? default(StringOffset) : builder.CreateString(_o.Id);
+ return CreateStat(
+ builder,
+ _id,
+ _o.Val,
+ _o.Count);
}
};
+public class StatT
+{
+ [Newtonsoft.Json.JsonProperty("id")]
+ public string Id { get; set; }
+ [Newtonsoft.Json.JsonProperty("val")]
+ public long Val { get; set; }
+ [Newtonsoft.Json.JsonProperty("count")]
+ public ushort Count { get; set; }
+
+ public StatT() {
+ this.Id = null;
+ this.Val = 0;
+ this.Count = 0;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Stat.go b/tests/MyGame/Example/Stat.go
index 401712fb..6034e01c 100644
--- a/tests/MyGame/Example/Stat.go
+++ b/tests/MyGame/Example/Stat.go
@@ -6,6 +6,35 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type StatT struct {
+ Id string
+ Val int64
+ Count uint16
+}
+
+func (t *StatT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ idOffset := builder.CreateString(t.Id)
+ StatStart(builder)
+ StatAddId(builder, idOffset)
+ StatAddVal(builder, t.Val)
+ StatAddCount(builder, t.Count)
+ return StatEnd(builder)
+}
+
+func (rcv *Stat) UnPackTo(t *StatT) {
+ t.Id = string(rcv.Id())
+ t.Val = rcv.Val()
+ t.Count = rcv.Count()
+}
+
+func (rcv *Stat) UnPack() *StatT {
+ if rcv == nil { return nil }
+ t := &StatT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type Stat struct {
_tab flatbuffers.Table
}
diff --git a/tests/MyGame/Example/Stat.java b/tests/MyGame/Example/Stat.java
index c995eb1e..116c2111 100644
--- a/tests/MyGame/Example/Stat.java
+++ b/tests/MyGame/Example/Stat.java
@@ -9,9 +9,10 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Stat extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static Stat getRootAsStat(ByteBuffer _bb) { return getRootAsStat(_bb, new Stat()); }
public static Stat getRootAsStat(ByteBuffer _bb, Stat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Stat __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public String id() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
@@ -26,20 +27,27 @@ public final class Stat extends Table {
int idOffset,
long val,
int count) {
- builder.startObject(3);
+ builder.startTable(3);
Stat.addVal(builder, val);
Stat.addId(builder, idOffset);
Stat.addCount(builder, count);
return Stat.endStat(builder);
}
- public static void startStat(FlatBufferBuilder builder) { builder.startObject(3); }
+ public static void startStat(FlatBufferBuilder builder) { builder.startTable(3); }
public static void addId(FlatBufferBuilder builder, int idOffset) { builder.addOffset(0, idOffset, 0); }
public static void addVal(FlatBufferBuilder builder, long val) { builder.addLong(1, val, 0L); }
public static void addCount(FlatBufferBuilder builder, int count) { builder.addShort(2, (short)count, (short)0); }
public static int endStat(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Stat get(int j) { return get(new Stat(), j); }
+ public Stat get(Stat obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/MyGame/Example/Stat.kt b/tests/MyGame/Example/Stat.kt
new file mode 100644
index 00000000..e72f5533
--- /dev/null
+++ b/tests/MyGame/Example/Stat.kt
@@ -0,0 +1,78 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Stat : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Stat {
+ __init(_i, _bb)
+ return this
+ }
+ val id : String?
+ get() {
+ val o = __offset(4)
+ return if (o != 0) __string(o + bb_pos) else null
+ }
+ val idAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1)
+ fun idInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
+ val val_ : Long
+ get() {
+ val o = __offset(6)
+ return if(o != 0) bb.getLong(o + bb_pos) else 0L
+ }
+ fun mutateVal_(val_: Long) : Boolean {
+ val o = __offset(6)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, val_)
+ true
+ } else {
+ false
+ }
+ }
+ val count : UShort
+ get() {
+ val o = __offset(8)
+ return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
+ }
+ fun mutateCount(count: UShort) : Boolean {
+ val o = __offset(8)
+ return if (o != 0) {
+ bb.putShort(o + bb_pos, count.toShort())
+ true
+ } else {
+ false
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsStat(_bb: ByteBuffer): Stat = getRootAsStat(_bb, Stat())
+ fun getRootAsStat(_bb: ByteBuffer, obj: Stat): Stat {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createStat(builder: FlatBufferBuilder, idOffset: Int, val_: Long, count: UShort) : Int {
+ builder.startTable(3)
+ addVal_(builder, val_)
+ addId(builder, idOffset)
+ addCount(builder, count)
+ return endStat(builder)
+ }
+ fun startStat(builder: FlatBufferBuilder) = builder.startTable(3)
+ fun addId(builder: FlatBufferBuilder, id: Int) = builder.addOffset(0, id, 0)
+ fun addVal_(builder: FlatBufferBuilder, val_: Long) = builder.addLong(1, val_, 0L)
+ fun addCount(builder: FlatBufferBuilder, count: UShort) = builder.addShort(2, count.toShort(), 0)
+ fun endStat(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/MyGame/Example/Stat.py b/tests/MyGame/Example/Stat.py
index ae33aef3..7d3362fa 100644
--- a/tests/MyGame/Example/Stat.py
+++ b/tests/MyGame/Example/Stat.py
@@ -3,6 +3,8 @@
# namespace: Example
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class Stat(object):
__slots__ = ['_tab']
@@ -14,6 +16,10 @@ class Stat(object):
x.Init(buf, n + offset)
return x
+ @classmethod
+ def StatBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
# Stat
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
@@ -44,3 +50,44 @@ def StatAddId(builder, id): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.n
def StatAddVal(builder, val): builder.PrependInt64Slot(1, val, 0)
def StatAddCount(builder, count): builder.PrependUint16Slot(2, count, 0)
def StatEnd(builder): return builder.EndObject()
+
+
+class StatT(object):
+
+ # StatT
+ def __init__(self):
+ self.id = None # type: str
+ self.val = 0 # type: int
+ self.count = 0 # type: int
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ stat = Stat()
+ stat.Init(buf, pos)
+ return cls.InitFromObj(stat)
+
+ @classmethod
+ def InitFromObj(cls, stat):
+ x = StatT()
+ x._UnPack(stat)
+ return x
+
+ # StatT
+ def _UnPack(self, stat):
+ if stat is None:
+ return
+ self.id = stat.Id()
+ self.val = stat.Val()
+ self.count = stat.Count()
+
+ # StatT
+ def Pack(self, builder):
+ if self.id is not None:
+ id = builder.CreateString(self.id)
+ StatStart(builder)
+ if self.id is not None:
+ StatAddId(builder, id)
+ StatAddVal(builder, self.val)
+ StatAddCount(builder, self.count)
+ stat = StatEnd(builder)
+ return stat
diff --git a/tests/MyGame/Example/Test.cs b/tests/MyGame/Example/Test.cs
index 18421316..a6419ed2 100644
--- a/tests/MyGame/Example/Test.cs
+++ b/tests/MyGame/Example/Test.cs
@@ -6,13 +6,14 @@ namespace MyGame.Example
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Test : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
public Test __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public short A { get { return __p.bb.GetShort(__p.bb_pos + 0); } }
@@ -20,14 +21,43 @@ public struct Test : IFlatbufferObject
public sbyte B { get { return __p.bb.GetSbyte(__p.bb_pos + 2); } }
public void MutateB(sbyte b) { __p.bb.PutSbyte(__p.bb_pos + 2, b); }
- public static Offset<Test> CreateTest(FlatBufferBuilder builder, short A, sbyte B) {
+ public static Offset<MyGame.Example.Test> CreateTest(FlatBufferBuilder builder, short A, sbyte B) {
builder.Prep(2, 4);
builder.Pad(1);
builder.PutSbyte(B);
builder.PutShort(A);
- return new Offset<Test>(builder.Offset);
+ return new Offset<MyGame.Example.Test>(builder.Offset);
+ }
+ public TestT UnPack() {
+ var _o = new TestT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(TestT _o) {
+ _o.A = this.A;
+ _o.B = this.B;
+ }
+ public static Offset<MyGame.Example.Test> Pack(FlatBufferBuilder builder, TestT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.Test>);
+ return CreateTest(
+ builder,
+ _o.A,
+ _o.B);
}
};
+public class TestT
+{
+ [Newtonsoft.Json.JsonProperty("a")]
+ public short A { get; set; }
+ [Newtonsoft.Json.JsonProperty("b")]
+ public sbyte B { get; set; }
+
+ public TestT() {
+ this.A = 0;
+ this.B = 0;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Test.go b/tests/MyGame/Example/Test.go
index 53f53fd4..cbf7e29a 100644
--- a/tests/MyGame/Example/Test.go
+++ b/tests/MyGame/Example/Test.go
@@ -6,6 +6,27 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type TestT struct {
+ A int16
+ B int8
+}
+
+func (t *TestT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ return CreateTest(builder, t.A, t.B)
+}
+func (rcv *Test) UnPackTo(t *TestT) {
+ t.A = rcv.A()
+ t.B = rcv.B()
+}
+
+func (rcv *Test) UnPack() *TestT {
+ if rcv == nil { return nil }
+ t := &TestT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type Test struct {
_tab flatbuffers.Struct
}
diff --git a/tests/MyGame/Example/Test.java b/tests/MyGame/Example/Test.java
index f584c463..c4ffc410 100644
--- a/tests/MyGame/Example/Test.java
+++ b/tests/MyGame/Example/Test.java
@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Test extends Struct {
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Test __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public short a() { return bb.getShort(bb_pos + 0); }
@@ -24,5 +24,12 @@ public final class Test extends Struct {
builder.putShort(a);
return builder.offset();
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Test get(int j) { return get(new Test(), j); }
+ public Test get(Test obj, int j) { return obj.__assign(__element(j), bb); }
+ }
}
diff --git a/tests/MyGame/Example/Test.kt b/tests/MyGame/Example/Test.kt
new file mode 100644
index 00000000..f2ceed6f
--- /dev/null
+++ b/tests/MyGame/Example/Test.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Test : Struct() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Test {
+ __init(_i, _bb)
+ return this
+ }
+ val a : Short get() = bb.getShort(bb_pos + 0)
+ fun mutateA(a: Short) : ByteBuffer = bb.putShort(bb_pos + 0, a)
+ val b : Byte get() = bb.get(bb_pos + 2)
+ fun mutateB(b: Byte) : ByteBuffer = bb.put(bb_pos + 2, b)
+ companion object {
+ fun createTest(builder: FlatBufferBuilder, a: Short, b: Byte) : Int {
+ builder.prep(2, 4)
+ builder.pad(1)
+ builder.putByte(b)
+ builder.putShort(a)
+ return builder.offset()
+ }
+ }
+}
diff --git a/tests/MyGame/Example/Test.py b/tests/MyGame/Example/Test.py
index 3b2fd45f..576a656e 100644
--- a/tests/MyGame/Example/Test.py
+++ b/tests/MyGame/Example/Test.py
@@ -3,6 +3,8 @@
# namespace: Example
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class Test(object):
__slots__ = ['_tab']
@@ -22,3 +24,34 @@ def CreateTest(builder, a, b):
builder.PrependInt8(b)
builder.PrependInt16(a)
return builder.Offset()
+
+
+class TestT(object):
+
+ # TestT
+ def __init__(self):
+ self.a = 0 # type: int
+ self.b = 0 # type: int
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ test = Test()
+ test.Init(buf, pos)
+ return cls.InitFromObj(test)
+
+ @classmethod
+ def InitFromObj(cls, test):
+ x = TestT()
+ x._UnPack(test)
+ return x
+
+ # TestT
+ def _UnPack(self, test):
+ if test is None:
+ return
+ self.a = test.A()
+ self.b = test.B()
+
+ # TestT
+ def Pack(self, builder):
+ return CreateTest(builder, self.a, self.b)
diff --git a/tests/MyGame/Example/TestEnum.cs b/tests/MyGame/Example/TestEnum.cs
new file mode 100644
index 00000000..6dfd6b54
--- /dev/null
+++ b/tests/MyGame/Example/TestEnum.cs
@@ -0,0 +1,17 @@
+// <auto-generated>
+// automatically generated by the FlatBuffers compiler, do not modify
+// </auto-generated>
+
+namespace MyGame.Example
+{
+
+[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
+public enum TestEnum : sbyte
+{
+ A = 0,
+ B = 1,
+ C = 2,
+};
+
+
+}
diff --git a/tests/MyGame/Example/TestEnum.java b/tests/MyGame/Example/TestEnum.java
new file mode 100644
index 00000000..411bf8e3
--- /dev/null
+++ b/tests/MyGame/Example/TestEnum.java
@@ -0,0 +1,15 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example;
+
+public final class TestEnum {
+ private TestEnum() { }
+ public static final byte A = 0;
+ public static final byte B = 1;
+ public static final byte C = 2;
+
+ public static final String[] names = { "A", "B", "C", };
+
+ public static String name(int e) { return names[e]; }
+}
+
diff --git a/tests/MyGame/Example/TestEnum.kt b/tests/MyGame/Example/TestEnum.kt
new file mode 100644
index 00000000..ca4d7f87
--- /dev/null
+++ b/tests/MyGame/Example/TestEnum.kt
@@ -0,0 +1,14 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+@Suppress("unused")
+class TestEnum private constructor() {
+ companion object {
+ const val A: Byte = 0
+ const val B: Byte = 1
+ const val C: Byte = 2
+ val names : Array<String> = arrayOf("A", "B", "C")
+ fun name(e: Int) : String = names[e]
+ }
+}
diff --git a/tests/MyGame/Example/TestEnum.py b/tests/MyGame/Example/TestEnum.py
new file mode 100644
index 00000000..d49f10a1
--- /dev/null
+++ b/tests/MyGame/Example/TestEnum.py
@@ -0,0 +1,9 @@
+# automatically generated by the FlatBuffers compiler, do not modify
+
+# namespace: Example
+
+class TestEnum(object):
+ A = 0
+ B = 1
+ C = 2
+
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.cs b/tests/MyGame/Example/TestSimpleTableWithEnum.cs
index 9e405ef8..c8ef08ec 100644
--- a/tests/MyGame/Example/TestSimpleTableWithEnum.cs
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.cs
@@ -6,34 +6,60 @@ namespace MyGame.Example
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
internal partial struct TestSimpleTableWithEnum : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return GetRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public TestSimpleTableWithEnum __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public Color Color { get { int o = __p.__offset(4); return o != 0 ? (Color)__p.bb.GetSbyte(o + __p.bb_pos) : Color.Green; } }
- public bool MutateColor(Color color) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)color); return true; } else { return false; } }
+ public MyGame.Example.Color Color { get { int o = __p.__offset(4); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Green; } }
+ public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(4); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } }
- public static Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(FlatBufferBuilder builder,
- Color color = Color.Green) {
- builder.StartObject(1);
+ public static Offset<MyGame.Example.TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(FlatBufferBuilder builder,
+ MyGame.Example.Color color = MyGame.Example.Color.Green) {
+ builder.StartTable(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);
+ public static void StartTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.StartTable(1); }
+ public static void AddColor(FlatBufferBuilder builder, MyGame.Example.Color color) { builder.AddByte(0, (byte)color, 2); }
+ public static Offset<MyGame.Example.TestSimpleTableWithEnum> EndTestSimpleTableWithEnum(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<MyGame.Example.TestSimpleTableWithEnum>(o);
+ }
+ public TestSimpleTableWithEnumT UnPack() {
+ var _o = new TestSimpleTableWithEnumT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(TestSimpleTableWithEnumT _o) {
+ _o.Color = this.Color;
+ }
+ public static Offset<MyGame.Example.TestSimpleTableWithEnum> Pack(FlatBufferBuilder builder, TestSimpleTableWithEnumT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.TestSimpleTableWithEnum>);
+ return CreateTestSimpleTableWithEnum(
+ builder,
+ _o.Color);
}
};
+internal partial class TestSimpleTableWithEnumT
+{
+ [Newtonsoft.Json.JsonProperty("color")]
+ public MyGame.Example.Color Color { get; set; }
+
+ public TestSimpleTableWithEnumT() {
+ this.Color = MyGame.Example.Color.Green;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.go b/tests/MyGame/Example/TestSimpleTableWithEnum.go
index cf9da5e9..14805af7 100644
--- a/tests/MyGame/Example/TestSimpleTableWithEnum.go
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.go
@@ -6,6 +6,28 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type TestSimpleTableWithEnumT struct {
+ Color Color
+}
+
+func (t *TestSimpleTableWithEnumT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ TestSimpleTableWithEnumStart(builder)
+ TestSimpleTableWithEnumAddColor(builder, t.Color)
+ return TestSimpleTableWithEnumEnd(builder)
+}
+
+func (rcv *TestSimpleTableWithEnum) UnPackTo(t *TestSimpleTableWithEnumT) {
+ t.Color = rcv.Color()
+}
+
+func (rcv *TestSimpleTableWithEnum) UnPack() *TestSimpleTableWithEnumT {
+ if rcv == nil { return nil }
+ t := &TestSimpleTableWithEnumT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type TestSimpleTableWithEnum struct {
_tab flatbuffers.Table
}
@@ -29,20 +51,20 @@ func (rcv *TestSimpleTableWithEnum) Table() flatbuffers.Table {
func (rcv *TestSimpleTableWithEnum) Color() Color {
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
if o != 0 {
- return rcv._tab.GetInt8(o + rcv._tab.Pos)
+ return Color(rcv._tab.GetByte(o + rcv._tab.Pos))
}
return 2
}
func (rcv *TestSimpleTableWithEnum) MutateColor(n Color) bool {
- return rcv._tab.MutateInt8Slot(4, n)
+ return rcv._tab.MutateByteSlot(4, byte(n))
}
func TestSimpleTableWithEnumStart(builder *flatbuffers.Builder) {
builder.StartObject(1)
}
-func TestSimpleTableWithEnumAddColor(builder *flatbuffers.Builder, color int8) {
- builder.PrependInt8Slot(0, color, 2)
+func TestSimpleTableWithEnumAddColor(builder *flatbuffers.Builder, color Color) {
+ builder.PrependByteSlot(0, byte(color), 2)
}
func TestSimpleTableWithEnumEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
return builder.EndObject()
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.java b/tests/MyGame/Example/TestSimpleTableWithEnum.java
index 974e44ea..7e72c227 100644
--- a/tests/MyGame/Example/TestSimpleTableWithEnum.java
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.java
@@ -9,26 +9,34 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
final class TestSimpleTableWithEnum extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
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.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public TestSimpleTableWithEnum __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public byte color() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 2; }
- public boolean mutateColor(byte color) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, color); return true; } else { return false; } }
+ public int color() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 2; }
+ public boolean mutateColor(int color) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, (byte)color); return true; } else { return false; } }
public static int createTestSimpleTableWithEnum(FlatBufferBuilder builder,
- byte color) {
- builder.startObject(1);
+ int color) {
+ builder.startTable(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 void startTestSimpleTableWithEnum(FlatBufferBuilder builder) { builder.startTable(1); }
+ public static void addColor(FlatBufferBuilder builder, int color) { builder.addByte(0, (byte)color, (byte)2); }
public static int endTestSimpleTableWithEnum(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public TestSimpleTableWithEnum get(int j) { return get(new TestSimpleTableWithEnum(), j); }
+ public TestSimpleTableWithEnum get(TestSimpleTableWithEnum obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.kt b/tests/MyGame/Example/TestSimpleTableWithEnum.kt
new file mode 100644
index 00000000..125f889d
--- /dev/null
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.kt
@@ -0,0 +1,53 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TestSimpleTableWithEnum : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : TestSimpleTableWithEnum {
+ __init(_i, _bb)
+ return this
+ }
+ val color : UByte
+ get() {
+ val o = __offset(4)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 2u
+ }
+ fun mutateColor(color: UByte) : Boolean {
+ val o = __offset(4)
+ return if (o != 0) {
+ bb.put(o + bb_pos, color.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer): TestSimpleTableWithEnum = getRootAsTestSimpleTableWithEnum(_bb, TestSimpleTableWithEnum())
+ fun getRootAsTestSimpleTableWithEnum(_bb: ByteBuffer, obj: TestSimpleTableWithEnum): TestSimpleTableWithEnum {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createTestSimpleTableWithEnum(builder: FlatBufferBuilder, color: UByte) : Int {
+ builder.startTable(1)
+ addColor(builder, color)
+ return endTestSimpleTableWithEnum(builder)
+ }
+ fun startTestSimpleTableWithEnum(builder: FlatBufferBuilder) = builder.startTable(1)
+ fun addColor(builder: FlatBufferBuilder, color: UByte) = builder.addByte(0, color.toByte(), 2)
+ fun endTestSimpleTableWithEnum(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.lua b/tests/MyGame/Example/TestSimpleTableWithEnum.lua
index c17fb967..32c8251d 100644
--- a/tests/MyGame/Example/TestSimpleTableWithEnum.lua
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.lua
@@ -24,12 +24,12 @@ end
function TestSimpleTableWithEnum_mt:Color()
local o = self.view:Offset(4)
if o ~= 0 then
- return self.view:Get(flatbuffers.N.Int8, o + self.view.pos)
+ return self.view:Get(flatbuffers.N.Uint8, o + self.view.pos)
end
return 2
end
function TestSimpleTableWithEnum.Start(builder) builder:StartObject(1) end
-function TestSimpleTableWithEnum.AddColor(builder, color) builder:PrependInt8Slot(0, color, 2) end
+function TestSimpleTableWithEnum.AddColor(builder, color) builder:PrependUint8Slot(0, color, 2) end
function TestSimpleTableWithEnum.End(builder) return builder:EndObject() end
return TestSimpleTableWithEnum -- return the module \ No newline at end of file
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.php b/tests/MyGame/Example/TestSimpleTableWithEnum.php
index d37481fc..6429f8d8 100644
--- a/tests/MyGame/Example/TestSimpleTableWithEnum.php
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.php
@@ -48,12 +48,12 @@ class TestSimpleTableWithEnum extends Table
}
/**
- * @return sbyte
+ * @return byte
*/
public function getColor()
{
$o = $this->__offset(4);
- return $o != 0 ? $this->bb->getSbyte($o + $this->bb_pos) : \MyGame\Example\Color::Green;
+ return $o != 0 ? $this->bb->getByte($o + $this->bb_pos) : \MyGame\Example\Color::Green;
}
/**
@@ -79,12 +79,12 @@ class TestSimpleTableWithEnum extends Table
/**
* @param FlatBufferBuilder $builder
- * @param sbyte
+ * @param byte
* @return void
*/
public static function addColor(FlatBufferBuilder $builder, $color)
{
- $builder->addSbyteX(0, $color, 2);
+ $builder->addByteX(0, $color, 2);
}
/**
diff --git a/tests/MyGame/Example/TestSimpleTableWithEnum.py b/tests/MyGame/Example/TestSimpleTableWithEnum.py
index 8d64e971..d91947a3 100644
--- a/tests/MyGame/Example/TestSimpleTableWithEnum.py
+++ b/tests/MyGame/Example/TestSimpleTableWithEnum.py
@@ -3,6 +3,8 @@
# namespace: Example
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class TestSimpleTableWithEnum(object):
__slots__ = ['_tab']
@@ -14,6 +16,10 @@ class TestSimpleTableWithEnum(object):
x.Init(buf, n + offset)
return x
+ @classmethod
+ def TestSimpleTableWithEnumBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
# TestSimpleTableWithEnum
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
@@ -22,9 +28,41 @@ class TestSimpleTableWithEnum(object):
def Color(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Int8Flags, o + self._tab.Pos)
+ return self._tab.Get(flatbuffers.number_types.Uint8Flags, o + self._tab.Pos)
return 2
def TestSimpleTableWithEnumStart(builder): builder.StartObject(1)
-def TestSimpleTableWithEnumAddColor(builder, color): builder.PrependInt8Slot(0, color, 2)
+def TestSimpleTableWithEnumAddColor(builder, color): builder.PrependUint8Slot(0, color, 2)
def TestSimpleTableWithEnumEnd(builder): return builder.EndObject()
+
+
+class TestSimpleTableWithEnumT(object):
+
+ # TestSimpleTableWithEnumT
+ def __init__(self):
+ self.color = 2 # type: int
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ testSimpleTableWithEnum = TestSimpleTableWithEnum()
+ testSimpleTableWithEnum.Init(buf, pos)
+ return cls.InitFromObj(testSimpleTableWithEnum)
+
+ @classmethod
+ def InitFromObj(cls, testSimpleTableWithEnum):
+ x = TestSimpleTableWithEnumT()
+ x._UnPack(testSimpleTableWithEnum)
+ return x
+
+ # TestSimpleTableWithEnumT
+ def _UnPack(self, testSimpleTableWithEnum):
+ if testSimpleTableWithEnum is None:
+ return
+ self.color = testSimpleTableWithEnum.Color()
+
+ # TestSimpleTableWithEnumT
+ def Pack(self, builder):
+ TestSimpleTableWithEnumStart(builder)
+ TestSimpleTableWithEnumAddColor(builder, self.color)
+ testSimpleTableWithEnum = TestSimpleTableWithEnumEnd(builder)
+ return testSimpleTableWithEnum
diff --git a/tests/MyGame/Example/TypeAliases.cs b/tests/MyGame/Example/TypeAliases.cs
index 5ff10117..79ffb070 100644
--- a/tests/MyGame/Example/TypeAliases.cs
+++ b/tests/MyGame/Example/TypeAliases.cs
@@ -6,15 +6,17 @@ namespace MyGame.Example
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct TypeAliases : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb) { return GetRootAsTypeAliases(_bb, new TypeAliases()); }
public static TypeAliases GetRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public TypeAliases __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public sbyte I8 { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetSbyte(o + __p.bb_pos) : (sbyte)0; } }
@@ -40,7 +42,7 @@ 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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetV8Bytes() { return __p.__vector_as_span(24); }
+ public Span<sbyte> GetV8Bytes() { return __p.__vector_as_span<sbyte>(24, 1); }
#else
public ArraySegment<byte>? GetV8Bytes() { return __p.__vector_as_arraysegment(24); }
#endif
@@ -49,14 +51,14 @@ public struct TypeAliases : IFlatbufferObject
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; } }
#if ENABLE_SPAN_T
- public Span<byte> GetVf64Bytes() { return __p.__vector_as_span(26); }
+ public Span<double> GetVf64Bytes() { return __p.__vector_as_span<double>(26, 8); }
#else
public ArraySegment<byte>? GetVf64Bytes() { return __p.__vector_as_arraysegment(26); }
#endif
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,
+ public static Offset<MyGame.Example.TypeAliases> CreateTypeAliases(FlatBufferBuilder builder,
sbyte i8 = 0,
byte u8 = 0,
short i16 = 0,
@@ -69,7 +71,7 @@ public struct TypeAliases : IFlatbufferObject
double f64 = 0.0,
VectorOffset v8Offset = default(VectorOffset),
VectorOffset vf64Offset = default(VectorOffset)) {
- builder.StartObject(12);
+ builder.StartTable(12);
TypeAliases.AddF64(builder, f64);
TypeAliases.AddU64(builder, u64);
TypeAliases.AddI64(builder, i64);
@@ -85,7 +87,7 @@ public struct TypeAliases : IFlatbufferObject
return TypeAliases.EndTypeAliases(builder);
}
- public static void StartTypeAliases(FlatBufferBuilder builder) { builder.StartObject(12); }
+ public static void StartTypeAliases(FlatBufferBuilder builder) { builder.StartTable(12); }
public static void AddI8(FlatBufferBuilder builder, sbyte i8) { builder.AddSbyte(0, i8, 0); }
public static void AddU8(FlatBufferBuilder builder, byte u8) { builder.AddByte(1, u8, 0); }
public static void AddI16(FlatBufferBuilder builder, short i16) { builder.AddShort(2, i16, 0); }
@@ -104,11 +106,102 @@ public struct TypeAliases : IFlatbufferObject
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();
- return new Offset<TypeAliases>(o);
+ public static Offset<MyGame.Example.TypeAliases> EndTypeAliases(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<MyGame.Example.TypeAliases>(o);
+ }
+ public TypeAliasesT UnPack() {
+ var _o = new TypeAliasesT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(TypeAliasesT _o) {
+ _o.I8 = this.I8;
+ _o.U8 = this.U8;
+ _o.I16 = this.I16;
+ _o.U16 = this.U16;
+ _o.I32 = this.I32;
+ _o.U32 = this.U32;
+ _o.I64 = this.I64;
+ _o.U64 = this.U64;
+ _o.F32 = this.F32;
+ _o.F64 = this.F64;
+ _o.V8 = new List<sbyte>();
+ for (var _j = 0; _j < this.V8Length; ++_j) {_o.V8.Add(this.V8(_j));}
+ _o.Vf64 = new List<double>();
+ for (var _j = 0; _j < this.Vf64Length; ++_j) {_o.Vf64.Add(this.Vf64(_j));}
+ }
+ public static Offset<MyGame.Example.TypeAliases> Pack(FlatBufferBuilder builder, TypeAliasesT _o) {
+ if (_o == null) return default(Offset<MyGame.Example.TypeAliases>);
+ var _v8 = default(VectorOffset);
+ if (_o.V8 != null) {
+ var __v8 = _o.V8.ToArray();
+ _v8 = CreateV8Vector(builder, __v8);
+ }
+ var _vf64 = default(VectorOffset);
+ if (_o.Vf64 != null) {
+ var __vf64 = _o.Vf64.ToArray();
+ _vf64 = CreateVf64Vector(builder, __vf64);
+ }
+ return CreateTypeAliases(
+ builder,
+ _o.I8,
+ _o.U8,
+ _o.I16,
+ _o.U16,
+ _o.I32,
+ _o.U32,
+ _o.I64,
+ _o.U64,
+ _o.F32,
+ _o.F64,
+ _v8,
+ _vf64);
}
};
+public class TypeAliasesT
+{
+ [Newtonsoft.Json.JsonProperty("i8")]
+ public sbyte I8 { get; set; }
+ [Newtonsoft.Json.JsonProperty("u8")]
+ public byte U8 { get; set; }
+ [Newtonsoft.Json.JsonProperty("i16")]
+ public short I16 { get; set; }
+ [Newtonsoft.Json.JsonProperty("u16")]
+ public ushort U16 { get; set; }
+ [Newtonsoft.Json.JsonProperty("i32")]
+ public int I32 { get; set; }
+ [Newtonsoft.Json.JsonProperty("u32")]
+ public uint U32 { get; set; }
+ [Newtonsoft.Json.JsonProperty("i64")]
+ public long I64 { get; set; }
+ [Newtonsoft.Json.JsonProperty("u64")]
+ public ulong U64 { get; set; }
+ [Newtonsoft.Json.JsonProperty("f32")]
+ public float F32 { get; set; }
+ [Newtonsoft.Json.JsonProperty("f64")]
+ public double F64 { get; set; }
+ [Newtonsoft.Json.JsonProperty("v8")]
+ public List<sbyte> V8 { get; set; }
+ [Newtonsoft.Json.JsonProperty("vf64")]
+ public List<double> Vf64 { get; set; }
+
+ public TypeAliasesT() {
+ this.I8 = 0;
+ this.U8 = 0;
+ this.I16 = 0;
+ this.U16 = 0;
+ this.I32 = 0;
+ this.U32 = 0;
+ this.I64 = 0;
+ this.U64 = 0;
+ this.F32 = 0.0f;
+ this.F64 = 0.0;
+ this.V8 = null;
+ this.Vf64 = null;
+ }
+}
+
}
diff --git a/tests/MyGame/Example/TypeAliases.go b/tests/MyGame/Example/TypeAliases.go
index d017b5bc..1c259aa5 100644
--- a/tests/MyGame/Example/TypeAliases.go
+++ b/tests/MyGame/Example/TypeAliases.go
@@ -6,6 +6,87 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type TypeAliasesT struct {
+ I8 int8
+ U8 byte
+ I16 int16
+ U16 uint16
+ I32 int32
+ U32 uint32
+ I64 int64
+ U64 uint64
+ F32 float32
+ F64 float64
+ V8 []int8
+ Vf64 []float64
+}
+
+func (t *TypeAliasesT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ v8Offset := flatbuffers.UOffsetT(0)
+ if t.V8 != nil {
+ v8Length := len(t.V8)
+ TypeAliasesStartV8Vector(builder, v8Length)
+ for j := v8Length - 1; j >= 0; j-- {
+ builder.PrependInt8(t.V8[j])
+ }
+ v8Offset = builder.EndVector(v8Length)
+ }
+ vf64Offset := flatbuffers.UOffsetT(0)
+ if t.Vf64 != nil {
+ vf64Length := len(t.Vf64)
+ TypeAliasesStartVf64Vector(builder, vf64Length)
+ for j := vf64Length - 1; j >= 0; j-- {
+ builder.PrependFloat64(t.Vf64[j])
+ }
+ vf64Offset = builder.EndVector(vf64Length)
+ }
+ TypeAliasesStart(builder)
+ TypeAliasesAddI8(builder, t.I8)
+ TypeAliasesAddU8(builder, t.U8)
+ TypeAliasesAddI16(builder, t.I16)
+ TypeAliasesAddU16(builder, t.U16)
+ TypeAliasesAddI32(builder, t.I32)
+ TypeAliasesAddU32(builder, t.U32)
+ TypeAliasesAddI64(builder, t.I64)
+ TypeAliasesAddU64(builder, t.U64)
+ TypeAliasesAddF32(builder, t.F32)
+ TypeAliasesAddF64(builder, t.F64)
+ TypeAliasesAddV8(builder, v8Offset)
+ TypeAliasesAddVf64(builder, vf64Offset)
+ return TypeAliasesEnd(builder)
+}
+
+func (rcv *TypeAliases) UnPackTo(t *TypeAliasesT) {
+ t.I8 = rcv.I8()
+ t.U8 = rcv.U8()
+ t.I16 = rcv.I16()
+ t.U16 = rcv.U16()
+ t.I32 = rcv.I32()
+ t.U32 = rcv.U32()
+ t.I64 = rcv.I64()
+ t.U64 = rcv.U64()
+ t.F32 = rcv.F32()
+ t.F64 = rcv.F64()
+ v8Length := rcv.V8Length()
+ t.V8 = make([]int8, v8Length)
+ for j := 0; j < v8Length; j++ {
+ t.V8[j] = rcv.V8(j)
+ }
+ vf64Length := rcv.Vf64Length()
+ t.Vf64 = make([]float64, vf64Length)
+ for j := 0; j < vf64Length; j++ {
+ t.Vf64[j] = rcv.Vf64(j)
+ }
+}
+
+func (rcv *TypeAliases) UnPack() *TypeAliasesT {
+ if rcv == nil { return nil }
+ t := &TypeAliasesT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type TypeAliases struct {
_tab flatbuffers.Table
}
diff --git a/tests/MyGame/Example/TypeAliases.java b/tests/MyGame/Example/TypeAliases.java
index cccb722a..1112658a 100644
--- a/tests/MyGame/Example/TypeAliases.java
+++ b/tests/MyGame/Example/TypeAliases.java
@@ -9,9 +9,10 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class TypeAliases extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb) { return getRootAsTypeAliases(_bb, new TypeAliases()); }
public static TypeAliases getRootAsTypeAliases(ByteBuffer _bb, TypeAliases obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public TypeAliases __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public byte i8() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }
@@ -36,11 +37,15 @@ public final class TypeAliases extends Table {
public boolean mutateF64(double f64) { int o = __offset(22); if (o != 0) { bb.putDouble(o + bb_pos, f64); return true; } else { return false; } }
public byte v8(int j) { int o = __offset(24); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
public int v8Length() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
+ public ByteVector v8Vector() { return v8Vector(new ByteVector()); }
+ public ByteVector v8Vector(ByteVector obj) { int o = __offset(24); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer v8AsByteBuffer() { return __vector_as_bytebuffer(24, 1); }
public ByteBuffer v8InByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 24, 1); }
public boolean mutateV8(int j, byte v8) { int o = __offset(24); if (o != 0) { bb.put(__vector(o) + j * 1, v8); return true; } else { return false; } }
public double vf64(int j) { int o = __offset(26); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
public int vf64Length() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
+ public DoubleVector vf64Vector() { return vf64Vector(new DoubleVector()); }
+ public DoubleVector vf64Vector(DoubleVector obj) { int o = __offset(26); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer vf64AsByteBuffer() { return __vector_as_bytebuffer(26, 8); }
public ByteBuffer vf64InByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 26, 8); }
public boolean mutateVf64(int j, double vf64) { int o = __offset(26); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vf64); return true; } else { return false; } }
@@ -58,7 +63,7 @@ public final class TypeAliases extends Table {
double f64,
int v8Offset,
int vf64Offset) {
- builder.startObject(12);
+ builder.startTable(12);
TypeAliases.addF64(builder, f64);
TypeAliases.addU64(builder, u64);
TypeAliases.addI64(builder, i64);
@@ -74,7 +79,7 @@ public final class TypeAliases extends Table {
return TypeAliases.endTypeAliases(builder);
}
- public static void startTypeAliases(FlatBufferBuilder builder) { builder.startObject(12); }
+ public static void startTypeAliases(FlatBufferBuilder builder) { builder.startTable(12); }
public static void addI8(FlatBufferBuilder builder, byte i8) { builder.addByte(0, i8, 0); }
public static void addU8(FlatBufferBuilder builder, int u8) { builder.addByte(1, (byte)u8, (byte)0); }
public static void addI16(FlatBufferBuilder builder, short i16) { builder.addShort(2, i16, 0); }
@@ -86,14 +91,22 @@ public final class TypeAliases extends Table {
public static void addF32(FlatBufferBuilder builder, float f32) { builder.addFloat(8, f32, 0.0f); }
public static void addF64(FlatBufferBuilder builder, double f64) { builder.addDouble(9, f64, 0.0); }
public static void addV8(FlatBufferBuilder builder, int v8Offset) { builder.addOffset(10, v8Offset, 0); }
- public static int createV8Vector(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 int createV8Vector(FlatBufferBuilder builder, byte[] data) { return builder.createByteVector(data); }
+ public static int createV8Vector(FlatBufferBuilder builder, ByteBuffer data) { return builder.createByteVector(data); }
public static void startV8Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
public static void addVf64(FlatBufferBuilder builder, int vf64Offset) { builder.addOffset(11, vf64Offset, 0); }
public static int 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 void startVf64Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
public static int endTypeAliases(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public TypeAliases get(int j) { return get(new TypeAliases(), j); }
+ public TypeAliases get(TypeAliases obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/MyGame/Example/TypeAliases.kt b/tests/MyGame/Example/TypeAliases.kt
new file mode 100644
index 00000000..d279d147
--- /dev/null
+++ b/tests/MyGame/Example/TypeAliases.kt
@@ -0,0 +1,263 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TypeAliases : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : TypeAliases {
+ __init(_i, _bb)
+ return this
+ }
+ val i8 : Byte
+ get() {
+ val o = __offset(4)
+ return if(o != 0) bb.get(o + bb_pos) else 0
+ }
+ fun mutateI8(i8: Byte) : Boolean {
+ val o = __offset(4)
+ return if (o != 0) {
+ bb.put(o + bb_pos, i8)
+ true
+ } else {
+ false
+ }
+ }
+ val u8 : UByte
+ get() {
+ val o = __offset(6)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+ }
+ fun mutateU8(u8: UByte) : Boolean {
+ val o = __offset(6)
+ return if (o != 0) {
+ bb.put(o + bb_pos, u8.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ val i16 : Short
+ get() {
+ val o = __offset(8)
+ return if(o != 0) bb.getShort(o + bb_pos) else 0
+ }
+ fun mutateI16(i16: Short) : Boolean {
+ val o = __offset(8)
+ return if (o != 0) {
+ bb.putShort(o + bb_pos, i16)
+ true
+ } else {
+ false
+ }
+ }
+ val u16 : UShort
+ get() {
+ val o = __offset(10)
+ return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
+ }
+ fun mutateU16(u16: UShort) : Boolean {
+ val o = __offset(10)
+ return if (o != 0) {
+ bb.putShort(o + bb_pos, u16.toShort())
+ true
+ } else {
+ false
+ }
+ }
+ val i32 : Int
+ get() {
+ val o = __offset(12)
+ return if(o != 0) bb.getInt(o + bb_pos) else 0
+ }
+ fun mutateI32(i32: Int) : Boolean {
+ val o = __offset(12)
+ return if (o != 0) {
+ bb.putInt(o + bb_pos, i32)
+ true
+ } else {
+ false
+ }
+ }
+ val u32 : UInt
+ get() {
+ val o = __offset(14)
+ return if(o != 0) bb.getInt(o + bb_pos).toUInt() else 0u
+ }
+ fun mutateU32(u32: UInt) : Boolean {
+ val o = __offset(14)
+ return if (o != 0) {
+ bb.putInt(o + bb_pos, u32.toInt())
+ true
+ } else {
+ false
+ }
+ }
+ val i64 : Long
+ get() {
+ val o = __offset(16)
+ return if(o != 0) bb.getLong(o + bb_pos) else 0L
+ }
+ fun mutateI64(i64: Long) : Boolean {
+ val o = __offset(16)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, i64)
+ true
+ } else {
+ false
+ }
+ }
+ val u64 : ULong
+ get() {
+ val o = __offset(18)
+ return if(o != 0) bb.getLong(o + bb_pos).toULong() else 0UL
+ }
+ fun mutateU64(u64: ULong) : Boolean {
+ val o = __offset(18)
+ return if (o != 0) {
+ bb.putLong(o + bb_pos, u64.toLong())
+ true
+ } else {
+ false
+ }
+ }
+ val f32 : Float
+ get() {
+ val o = __offset(20)
+ return if(o != 0) bb.getFloat(o + bb_pos) else 0.0f
+ }
+ fun mutateF32(f32: Float) : Boolean {
+ val o = __offset(20)
+ return if (o != 0) {
+ bb.putFloat(o + bb_pos, f32)
+ true
+ } else {
+ false
+ }
+ }
+ val f64 : Double
+ get() {
+ val o = __offset(22)
+ return if(o != 0) bb.getDouble(o + bb_pos) else 0.0
+ }
+ fun mutateF64(f64: Double) : Boolean {
+ val o = __offset(22)
+ return if (o != 0) {
+ bb.putDouble(o + bb_pos, f64)
+ true
+ } else {
+ false
+ }
+ }
+ fun v8(j: Int) : Byte {
+ val o = __offset(24)
+ return if (o != 0) {
+ bb.get(__vector(o) + j * 1)
+ } else {
+ 0
+ }
+ }
+ val v8Length : Int
+ get() {
+ val o = __offset(24); return if (o != 0) __vector_len(o) else 0
+ }
+ val v8AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(24, 1)
+ fun v8InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 24, 1)
+ fun mutateV8(j: Int, v8: Byte) : Boolean {
+ val o = __offset(24)
+ return if (o != 0) {
+ bb.put(__vector(o) + j * 1, v8)
+ true
+ } else {
+ false
+ }
+ }
+ fun vf64(j: Int) : Double {
+ val o = __offset(26)
+ return if (o != 0) {
+ bb.getDouble(__vector(o) + j * 8)
+ } else {
+ 0.0
+ }
+ }
+ val vf64Length : Int
+ get() {
+ val o = __offset(26); return if (o != 0) __vector_len(o) else 0
+ }
+ val vf64AsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(26, 8)
+ fun vf64InByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 26, 8)
+ fun mutateVf64(j: Int, vf64: Double) : Boolean {
+ val o = __offset(26)
+ return if (o != 0) {
+ bb.putDouble(__vector(o) + j * 8, vf64)
+ true
+ } else {
+ false
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsTypeAliases(_bb: ByteBuffer): TypeAliases = getRootAsTypeAliases(_bb, TypeAliases())
+ fun getRootAsTypeAliases(_bb: ByteBuffer, obj: TypeAliases): TypeAliases {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createTypeAliases(builder: FlatBufferBuilder, i8: Byte, u8: UByte, i16: Short, u16: UShort, i32: Int, u32: UInt, i64: Long, u64: ULong, f32: Float, f64: Double, v8Offset: Int, vf64Offset: Int) : Int {
+ builder.startTable(12)
+ addF64(builder, f64)
+ addU64(builder, u64)
+ addI64(builder, i64)
+ addVf64(builder, vf64Offset)
+ addV8(builder, v8Offset)
+ addF32(builder, f32)
+ addU32(builder, u32)
+ addI32(builder, i32)
+ addU16(builder, u16)
+ addI16(builder, i16)
+ addU8(builder, u8)
+ addI8(builder, i8)
+ return endTypeAliases(builder)
+ }
+ fun startTypeAliases(builder: FlatBufferBuilder) = builder.startTable(12)
+ fun addI8(builder: FlatBufferBuilder, i8: Byte) = builder.addByte(0, i8, 0)
+ fun addU8(builder: FlatBufferBuilder, u8: UByte) = builder.addByte(1, u8.toByte(), 0)
+ fun addI16(builder: FlatBufferBuilder, i16: Short) = builder.addShort(2, i16, 0)
+ fun addU16(builder: FlatBufferBuilder, u16: UShort) = builder.addShort(3, u16.toShort(), 0)
+ fun addI32(builder: FlatBufferBuilder, i32: Int) = builder.addInt(4, i32, 0)
+ fun addU32(builder: FlatBufferBuilder, u32: UInt) = builder.addInt(5, u32.toInt(), 0)
+ fun addI64(builder: FlatBufferBuilder, i64: Long) = builder.addLong(6, i64, 0L)
+ fun addU64(builder: FlatBufferBuilder, u64: ULong) = builder.addLong(7, u64.toLong(), 0)
+ fun addF32(builder: FlatBufferBuilder, f32: Float) = builder.addFloat(8, f32, 0.0)
+ fun addF64(builder: FlatBufferBuilder, f64: Double) = builder.addDouble(9, f64, 0.0)
+ fun addV8(builder: FlatBufferBuilder, v8: Int) = builder.addOffset(10, v8, 0)
+ fun createV8Vector(builder: FlatBufferBuilder, data: ByteArray) : Int {
+ builder.startVector(1, data.size, 1)
+ for (i in data.size - 1 downTo 0) {
+ builder.addByte(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startV8Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+ fun addVf64(builder: FlatBufferBuilder, vf64: Int) = builder.addOffset(11, vf64, 0)
+ fun createVf64Vector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+ builder.startVector(8, data.size, 8)
+ for (i in data.size - 1 downTo 0) {
+ builder.addDouble(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startVf64Vector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+ fun endTypeAliases(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/MyGame/Example/TypeAliases.py b/tests/MyGame/Example/TypeAliases.py
index 707e53f1..0567212e 100644
--- a/tests/MyGame/Example/TypeAliases.py
+++ b/tests/MyGame/Example/TypeAliases.py
@@ -3,6 +3,8 @@
# namespace: Example
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class TypeAliases(object):
__slots__ = ['_tab']
@@ -14,6 +16,10 @@ class TypeAliases(object):
x.Init(buf, n + offset)
return x
+ @classmethod
+ def TypeAliasesBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
# TypeAliases
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
@@ -111,6 +117,11 @@ class TypeAliases(object):
return 0
# TypeAliases
+ def V8IsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(24))
+ return o == 0
+
+ # TypeAliases
def Vf64(self, j):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
if o != 0:
@@ -132,6 +143,11 @@ class TypeAliases(object):
return self._tab.VectorLen(o)
return 0
+ # TypeAliases
+ def Vf64IsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(26))
+ return o == 0
+
def TypeAliasesStart(builder): builder.StartObject(12)
def TypeAliasesAddI8(builder, i8): builder.PrependInt8Slot(0, i8, 0)
def TypeAliasesAddU8(builder, u8): builder.PrependUint8Slot(1, u8, 0)
@@ -148,3 +164,102 @@ def TypeAliasesStartV8Vector(builder, numElems): return builder.StartVector(1, n
def TypeAliasesAddVf64(builder, vf64): builder.PrependUOffsetTRelativeSlot(11, flatbuffers.number_types.UOffsetTFlags.py_type(vf64), 0)
def TypeAliasesStartVf64Vector(builder, numElems): return builder.StartVector(8, numElems, 8)
def TypeAliasesEnd(builder): return builder.EndObject()
+
+try:
+ from typing import List
+except:
+ pass
+
+class TypeAliasesT(object):
+
+ # TypeAliasesT
+ def __init__(self):
+ self.i8 = 0 # type: int
+ self.u8 = 0 # type: int
+ self.i16 = 0 # type: int
+ self.u16 = 0 # type: int
+ self.i32 = 0 # type: int
+ self.u32 = 0 # type: int
+ self.i64 = 0 # type: int
+ self.u64 = 0 # type: int
+ self.f32 = 0.0 # type: float
+ self.f64 = 0.0 # type: float
+ self.v8 = None # type: List[int]
+ self.vf64 = None # type: List[float]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ typeAliases = TypeAliases()
+ typeAliases.Init(buf, pos)
+ return cls.InitFromObj(typeAliases)
+
+ @classmethod
+ def InitFromObj(cls, typeAliases):
+ x = TypeAliasesT()
+ x._UnPack(typeAliases)
+ return x
+
+ # TypeAliasesT
+ def _UnPack(self, typeAliases):
+ if typeAliases is None:
+ return
+ self.i8 = typeAliases.I8()
+ self.u8 = typeAliases.U8()
+ self.i16 = typeAliases.I16()
+ self.u16 = typeAliases.U16()
+ self.i32 = typeAliases.I32()
+ self.u32 = typeAliases.U32()
+ self.i64 = typeAliases.I64()
+ self.u64 = typeAliases.U64()
+ self.f32 = typeAliases.F32()
+ self.f64 = typeAliases.F64()
+ if not typeAliases.V8IsNone():
+ if np is None:
+ self.v8 = []
+ for i in range(typeAliases.V8Length()):
+ self.v8.append(typeAliases.V8(i))
+ else:
+ self.v8 = typeAliases.V8AsNumpy()
+ if not typeAliases.Vf64IsNone():
+ if np is None:
+ self.vf64 = []
+ for i in range(typeAliases.Vf64Length()):
+ self.vf64.append(typeAliases.Vf64(i))
+ else:
+ self.vf64 = typeAliases.Vf64AsNumpy()
+
+ # TypeAliasesT
+ def Pack(self, builder):
+ if self.v8 is not None:
+ if np is not None and type(self.v8) is np.ndarray:
+ v8 = builder.CreateNumpyVector(self.v8)
+ else:
+ TypeAliasesStartV8Vector(builder, len(self.v8))
+ for i in reversed(range(len(self.v8))):
+ builder.PrependByte(self.v8[i])
+ v8 = builder.EndVector(len(self.v8))
+ if self.vf64 is not None:
+ if np is not None and type(self.vf64) is np.ndarray:
+ vf64 = builder.CreateNumpyVector(self.vf64)
+ else:
+ TypeAliasesStartVf64Vector(builder, len(self.vf64))
+ for i in reversed(range(len(self.vf64))):
+ builder.PrependFloat64(self.vf64[i])
+ vf64 = builder.EndVector(len(self.vf64))
+ TypeAliasesStart(builder)
+ TypeAliasesAddI8(builder, self.i8)
+ TypeAliasesAddU8(builder, self.u8)
+ TypeAliasesAddI16(builder, self.i16)
+ TypeAliasesAddU16(builder, self.u16)
+ TypeAliasesAddI32(builder, self.i32)
+ TypeAliasesAddU32(builder, self.u32)
+ TypeAliasesAddI64(builder, self.i64)
+ TypeAliasesAddU64(builder, self.u64)
+ TypeAliasesAddF32(builder, self.f32)
+ TypeAliasesAddF64(builder, self.f64)
+ if self.v8 is not None:
+ TypeAliasesAddV8(builder, v8)
+ if self.vf64 is not None:
+ TypeAliasesAddVf64(builder, vf64)
+ typeAliases = TypeAliasesEnd(builder)
+ return typeAliases
diff --git a/tests/MyGame/Example/Vec3.cs b/tests/MyGame/Example/Vec3.cs
index b0f95a09..4a9bf0d1 100644
--- a/tests/MyGame/Example/Vec3.cs
+++ b/tests/MyGame/Example/Vec3.cs
@@ -6,13 +6,14 @@ namespace MyGame.Example
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Vec3 : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
public Vec3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public float X { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
@@ -23,11 +24,11 @@ public struct Vec3 : IFlatbufferObject
public void MutateZ(float z) { __p.bb.PutFloat(__p.bb_pos + 8, z); }
public double Test1 { get { return __p.bb.GetDouble(__p.bb_pos + 16); } }
public void MutateTest1(double test1) { __p.bb.PutDouble(__p.bb_pos + 16, test1); }
- public Color Test2 { get { return (Color)__p.bb.GetSbyte(__p.bb_pos + 24); } }
- public void MutateTest2(Color test2) { __p.bb.PutSbyte(__p.bb_pos + 24, (sbyte)test2); }
- public Test Test3 { get { return (new Test()).__assign(__p.bb_pos + 26, __p.bb); } }
+ public MyGame.Example.Color Test2 { get { return (MyGame.Example.Color)__p.bb.Get(__p.bb_pos + 24); } }
+ public void MutateTest2(MyGame.Example.Color test2) { __p.bb.Put(__p.bb_pos + 24, (byte)test2); }
+ public MyGame.Example.Test Test3 { get { return (new MyGame.Example.Test()).__assign(__p.bb_pos + 26, __p.bb); } }
- public static Offset<Vec3> CreateVec3(FlatBufferBuilder builder, float X, float Y, float Z, double Test1, Color Test2, short test3_A, sbyte test3_B) {
+ public static Offset<MyGame.Example.Vec3> CreateVec3(FlatBufferBuilder builder, float X, float Y, float Z, double Test1, MyGame.Example.Color Test2, short test3_A, sbyte test3_B) {
builder.Prep(8, 32);
builder.Pad(2);
builder.Prep(2, 4);
@@ -35,15 +36,65 @@ public struct Vec3 : IFlatbufferObject
builder.PutSbyte(test3_B);
builder.PutShort(test3_A);
builder.Pad(1);
- builder.PutSbyte((sbyte)Test2);
+ builder.PutByte((byte)Test2);
builder.PutDouble(Test1);
builder.Pad(4);
builder.PutFloat(Z);
builder.PutFloat(Y);
builder.PutFloat(X);
- return new Offset<Vec3>(builder.Offset);
+ return new Offset<MyGame.Example.Vec3>(builder.Offset);
+ }
+ public Vec3T UnPack() {
+ var _o = new Vec3T();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(Vec3T _o) {
+ _o.X = this.X;
+ _o.Y = this.Y;
+ _o.Z = this.Z;
+ _o.Test1 = this.Test1;
+ _o.Test2 = this.Test2;
+ _o.Test3 = this.Test3.UnPack();
+ }
+ public static Offset<MyGame.Example.Vec3> Pack(FlatBufferBuilder builder, Vec3T _o) {
+ if (_o == null) return default(Offset<MyGame.Example.Vec3>);
+ return CreateVec3(
+ builder,
+ _o.X,
+ _o.Y,
+ _o.Z,
+ _o.Test1,
+ _o.Test2,
+ _o.Test3.A,
+ _o.Test3.B);
}
};
+public class Vec3T
+{
+ [Newtonsoft.Json.JsonProperty("x")]
+ public float X { get; set; }
+ [Newtonsoft.Json.JsonProperty("y")]
+ public float Y { get; set; }
+ [Newtonsoft.Json.JsonProperty("z")]
+ public float Z { get; set; }
+ [Newtonsoft.Json.JsonProperty("test1")]
+ public double Test1 { get; set; }
+ [Newtonsoft.Json.JsonProperty("test2")]
+ public MyGame.Example.Color Test2 { get; set; }
+ [Newtonsoft.Json.JsonProperty("test3")]
+ public MyGame.Example.TestT Test3 { get; set; }
+
+ public Vec3T() {
+ this.X = 0.0f;
+ this.Y = 0.0f;
+ this.Z = 0.0f;
+ this.Test1 = 0.0;
+ this.Test2 = 0;
+ this.Test3 = new MyGame.Example.TestT();
+ }
+}
+
}
diff --git a/tests/MyGame/Example/Vec3.go b/tests/MyGame/Example/Vec3.go
index 520b9cc4..08311ed0 100644
--- a/tests/MyGame/Example/Vec3.go
+++ b/tests/MyGame/Example/Vec3.go
@@ -6,6 +6,35 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type Vec3T struct {
+ X float32
+ Y float32
+ Z float32
+ Test1 float64
+ Test2 Color
+ Test3 *TestT
+}
+
+func (t *Vec3T) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ return CreateVec3(builder, t.X, t.Y, t.Z, t.Test1, t.Test2, t.Test3.A, t.Test3.B)
+}
+func (rcv *Vec3) UnPackTo(t *Vec3T) {
+ t.X = rcv.X()
+ t.Y = rcv.Y()
+ t.Z = rcv.Z()
+ t.Test1 = rcv.Test1()
+ t.Test2 = rcv.Test2()
+ t.Test3 = rcv.Test3(nil).UnPack()
+}
+
+func (rcv *Vec3) UnPack() *Vec3T {
+ if rcv == nil { return nil }
+ t := &Vec3T{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type Vec3 struct {
_tab flatbuffers.Struct
}
@@ -48,10 +77,10 @@ func (rcv *Vec3) MutateTest1(n float64) bool {
}
func (rcv *Vec3) Test2() Color {
- return rcv._tab.GetInt8(rcv._tab.Pos + flatbuffers.UOffsetT(24))
+ return Color(rcv._tab.GetByte(rcv._tab.Pos + flatbuffers.UOffsetT(24)))
}
func (rcv *Vec3) MutateTest2(n Color) bool {
- return rcv._tab.MutateInt8(rcv._tab.Pos+flatbuffers.UOffsetT(24), n)
+ return rcv._tab.MutateByte(rcv._tab.Pos+flatbuffers.UOffsetT(24), byte(n))
}
func (rcv *Vec3) Test3(obj *Test) *Test {
@@ -62,7 +91,7 @@ func (rcv *Vec3) Test3(obj *Test) *Test {
return obj
}
-func CreateVec3(builder *flatbuffers.Builder, x float32, y float32, z float32, test1 float64, test2 int8, test3_a int16, test3_b int8) flatbuffers.UOffsetT {
+func CreateVec3(builder *flatbuffers.Builder, x float32, y float32, z float32, test1 float64, test2 Color, test3_a int16, test3_b int8) flatbuffers.UOffsetT {
builder.Prep(8, 32)
builder.Pad(2)
builder.Prep(2, 4)
@@ -70,7 +99,7 @@ func CreateVec3(builder *flatbuffers.Builder, x float32, y float32, z float32, t
builder.PrependInt8(test3_b)
builder.PrependInt16(test3_a)
builder.Pad(1)
- builder.PrependInt8(test2)
+ builder.PrependByte(byte(test2))
builder.PrependFloat64(test1)
builder.Pad(4)
builder.PrependFloat32(z)
diff --git a/tests/MyGame/Example/Vec3.java b/tests/MyGame/Example/Vec3.java
index 2e43f051..89d38a12 100644
--- a/tests/MyGame/Example/Vec3.java
+++ b/tests/MyGame/Example/Vec3.java
@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Vec3 extends Struct {
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Vec3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public float x() { return bb.getFloat(bb_pos + 0); }
@@ -20,12 +20,12 @@ public final class Vec3 extends Struct {
public void mutateZ(float z) { bb.putFloat(bb_pos + 8, z); }
public double test1() { return bb.getDouble(bb_pos + 16); }
public void mutateTest1(double test1) { bb.putDouble(bb_pos + 16, test1); }
- public byte test2() { return bb.get(bb_pos + 24); }
- public void mutateTest2(byte test2) { bb.put(bb_pos + 24, test2); }
- public Test test3() { return test3(new Test()); }
- public Test test3(Test obj) { return obj.__assign(bb_pos + 26, bb); }
+ public int test2() { return bb.get(bb_pos + 24) & 0xFF; }
+ public void mutateTest2(int test2) { bb.put(bb_pos + 24, (byte)test2); }
+ public MyGame.Example.Test test3() { return test3(new MyGame.Example.Test()); }
+ public MyGame.Example.Test test3(MyGame.Example.Test obj) { return obj.__assign(bb_pos + 26, bb); }
- public static int createVec3(FlatBufferBuilder builder, float x, float y, float z, double test1, byte test2, short test3_a, byte test3_b) {
+ public static int createVec3(FlatBufferBuilder builder, float x, float y, float z, double test1, int test2, short test3_a, byte test3_b) {
builder.prep(8, 32);
builder.pad(2);
builder.prep(2, 4);
@@ -33,7 +33,7 @@ public final class Vec3 extends Struct {
builder.putByte(test3_b);
builder.putShort(test3_a);
builder.pad(1);
- builder.putByte(test2);
+ builder.putByte((byte)test2);
builder.putDouble(test1);
builder.pad(4);
builder.putFloat(z);
@@ -41,5 +41,12 @@ public final class Vec3 extends Struct {
builder.putFloat(x);
return builder.offset();
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Vec3 get(int j) { return get(new Vec3(), j); }
+ public Vec3 get(Vec3 obj, int j) { return obj.__assign(__element(j), bb); }
+ }
}
diff --git a/tests/MyGame/Example/Vec3.kt b/tests/MyGame/Example/Vec3.kt
new file mode 100644
index 00000000..90f1b4ad
--- /dev/null
+++ b/tests/MyGame/Example/Vec3.kt
@@ -0,0 +1,50 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Vec3 : Struct() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Vec3 {
+ __init(_i, _bb)
+ return this
+ }
+ val x : Float get() = bb.getFloat(bb_pos + 0)
+ fun mutateX(x: Float) : ByteBuffer = bb.putFloat(bb_pos + 0, x)
+ val y : Float get() = bb.getFloat(bb_pos + 4)
+ fun mutateY(y: Float) : ByteBuffer = bb.putFloat(bb_pos + 4, y)
+ val z : Float get() = bb.getFloat(bb_pos + 8)
+ fun mutateZ(z: Float) : ByteBuffer = bb.putFloat(bb_pos + 8, z)
+ val test1 : Double get() = bb.getDouble(bb_pos + 16)
+ fun mutateTest1(test1: Double) : ByteBuffer = bb.putDouble(bb_pos + 16, test1)
+ val test2 : UByte get() = bb.get(bb_pos + 24).toUByte()
+ fun mutateTest2(test2: UByte) : ByteBuffer = bb.put(bb_pos + 24, test2.toByte())
+ val test3 : MyGame.Example.Test? get() = test3(MyGame.Example.Test())
+ fun test3(obj: MyGame.Example.Test) : MyGame.Example.Test? = obj.__assign(bb_pos + 26, bb)
+ companion object {
+ fun createVec3(builder: FlatBufferBuilder, x: Float, y: Float, z: Float, test1: Double, test2: UByte, test3_a: Short, test3_b: Byte) : Int {
+ builder.prep(8, 32)
+ builder.pad(2)
+ builder.prep(2, 4)
+ builder.pad(1)
+ builder.putByte(test3_b)
+ builder.putShort(test3_a)
+ builder.pad(1)
+ builder.putByte(test2.toByte())
+ builder.putDouble(test1)
+ builder.pad(4)
+ builder.putFloat(z)
+ builder.putFloat(y)
+ builder.putFloat(x)
+ return builder.offset()
+ }
+ }
+}
diff --git a/tests/MyGame/Example/Vec3.lua b/tests/MyGame/Example/Vec3.lua
index 85e02d70..24d4cc14 100644
--- a/tests/MyGame/Example/Vec3.lua
+++ b/tests/MyGame/Example/Vec3.lua
@@ -28,7 +28,7 @@ function Vec3_mt:Test1()
return self.view:Get(flatbuffers.N.Float64, self.view.pos + 16)
end
function Vec3_mt:Test2()
- return self.view:Get(flatbuffers.N.Int8, self.view.pos + 24)
+ return self.view:Get(flatbuffers.N.Uint8, self.view.pos + 24)
end
function Vec3_mt:Test3(obj)
obj:Init(self.view.bytes, self.view.pos + 26)
@@ -42,7 +42,7 @@ function Vec3.CreateVec3(builder, x, y, z, test1, test2, test3_a, test3_b)
builder:PrependInt8(test3_b)
builder:PrependInt16(test3_a)
builder:Pad(1)
- builder:PrependInt8(test2)
+ builder:PrependUint8(test2)
builder:PrependFloat64(test1)
builder:Pad(4)
builder:PrependFloat32(z)
diff --git a/tests/MyGame/Example/Vec3.php b/tests/MyGame/Example/Vec3.php
index 288c1834..4d149e6f 100644
--- a/tests/MyGame/Example/Vec3.php
+++ b/tests/MyGame/Example/Vec3.php
@@ -55,11 +55,11 @@ class Vec3 extends Struct
}
/**
- * @return sbyte
+ * @return byte
*/
public function GetTest2()
{
- return $this->bb->getSbyte($this->bb_pos + 24);
+ return $this->bb->getByte($this->bb_pos + 24);
}
/**
@@ -85,7 +85,7 @@ class Vec3 extends Struct
$builder->putSbyte($test3_b);
$builder->putShort($test3_a);
$builder->pad(1);
- $builder->putSbyte($test2);
+ $builder->putByte($test2);
$builder->putDouble($test1);
$builder->pad(4);
$builder->putFloat($z);
diff --git a/tests/MyGame/Example/Vec3.py b/tests/MyGame/Example/Vec3.py
index 20399edd..5c91a7d3 100644
--- a/tests/MyGame/Example/Vec3.py
+++ b/tests/MyGame/Example/Vec3.py
@@ -3,6 +3,8 @@
# namespace: Example
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class Vec3(object):
__slots__ = ['_tab']
@@ -20,7 +22,7 @@ class Vec3(object):
# Vec3
def Test1(self): return self._tab.Get(flatbuffers.number_types.Float64Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(16))
# Vec3
- def Test2(self): return self._tab.Get(flatbuffers.number_types.Int8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(24))
+ def Test2(self): return self._tab.Get(flatbuffers.number_types.Uint8Flags, self._tab.Pos + flatbuffers.number_types.UOffsetTFlags.py_type(24))
# Vec3
def Test3(self, obj):
obj.Init(self._tab.Bytes, self._tab.Pos + 26)
@@ -35,10 +37,55 @@ def CreateVec3(builder, x, y, z, test1, test2, test3_a, test3_b):
builder.PrependInt8(test3_b)
builder.PrependInt16(test3_a)
builder.Pad(1)
- builder.PrependInt8(test2)
+ builder.PrependUint8(test2)
builder.PrependFloat64(test1)
builder.Pad(4)
builder.PrependFloat32(z)
builder.PrependFloat32(y)
builder.PrependFloat32(x)
return builder.Offset()
+
+import MyGame.Example.Test
+try:
+ from typing import Optional
+except:
+ pass
+
+class Vec3T(object):
+
+ # Vec3T
+ def __init__(self):
+ self.x = 0.0 # type: float
+ self.y = 0.0 # type: float
+ self.z = 0.0 # type: float
+ self.test1 = 0.0 # type: float
+ self.test2 = 0 # type: int
+ self.test3 = None # type: Optional[MyGame.Example.Test.TestT]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ vec3 = Vec3()
+ vec3.Init(buf, pos)
+ return cls.InitFromObj(vec3)
+
+ @classmethod
+ def InitFromObj(cls, vec3):
+ x = Vec3T()
+ x._UnPack(vec3)
+ return x
+
+ # Vec3T
+ def _UnPack(self, vec3):
+ if vec3 is None:
+ return
+ self.x = vec3.X()
+ self.y = vec3.Y()
+ self.z = vec3.Z()
+ self.test1 = vec3.Test1()
+ self.test2 = vec3.Test2()
+ if vec3.Test3(MyGame.Example.Test.Test()) is not None:
+ self.test3 = MyGame.Example.Test.TestT.InitFromObj(vec3.Test3(MyGame.Example.Test.Test()))
+
+ # Vec3T
+ def Pack(self, builder):
+ return CreateVec3(builder, self.x, self.y, self.z, self.test1, self.test2, self.test3.a, self.test3.b)
diff --git a/tests/MyGame/Example/monster_test_grpc_fb.py b/tests/MyGame/Example/monster_test_grpc_fb.py
new file mode 100644
index 00000000..8375c982
--- /dev/null
+++ b/tests/MyGame/Example/monster_test_grpc_fb.py
@@ -0,0 +1,241 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+
+class MonsterStorageStub(object):
+
+ def __init__(self, channel):
+ """Constructor.
+
+ Args:
+ channel: A grpc.Channel.
+ """
+ self.Store = channel.unary_unary(
+ '/MyGame.Example.MonsterStorage/Store',
+
+
+ )
+ self.Retrieve = channel.unary_stream(
+ '/MyGame.Example.MonsterStorage/Retrieve',
+
+
+ )
+ self.GetMaxHitPoint = channel.stream_unary(
+ '/MyGame.Example.MonsterStorage/GetMaxHitPoint',
+
+
+ )
+ self.GetMinMaxHitPoints = channel.unary_unary(
+ '/MyGame.Example.MonsterStorage/GetMinMaxHitPoints',
+
+
+ )
+
+
+class MonsterStorageServicer(object):
+
+ def Store(self, request, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def Retrieve(self, request, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def GetMaxHitPoint(self, request_iterator, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def GetMinMaxHitPoints(self, request, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+
+def add_MonsterStorageServicer_to_server(servicer, server):
+ rpc_method_handlers = {
+ 'Store': grpc.unary_unary_rpc_method_handler(
+ servicer.Store,
+
+
+ ),
+ 'Retrieve': grpc.unary_stream_rpc_method_handler(
+ servicer.Retrieve,
+
+
+ ),
+ 'GetMaxHitPoint': grpc.stream_unary_rpc_method_handler(
+ servicer.GetMaxHitPoint,
+
+
+ ),
+ 'GetMinMaxHitPoints': grpc.unary_unary_rpc_method_handler(
+ servicer.GetMinMaxHitPoints,
+
+
+ ),
+ }
+ generic_handler = grpc.method_handlers_generic_handler(
+ 'MyGame.Example.MonsterStorage', rpc_method_handlers)
+ server.add_generic_rpc_handlers((generic_handler,))
+try:
+ # THESE ELEMENTS WILL BE DEPRECATED.
+ # Please use the generated *_pb2_grpc.py files instead.
+ import grpc
+ from grpc.beta import implementations as beta_implementations
+ from grpc.beta import interfaces as beta_interfaces
+ from grpc.framework.common import cardinality
+ from grpc.framework.interfaces.face import utilities as face_utilities
+
+
+ class MonsterStorageStub(object):
+
+ def __init__(self, channel):
+ """Constructor.
+
+ Args:
+ channel: A grpc.Channel.
+ """
+ self.Store = channel.unary_unary(
+ '/MyGame.Example.MonsterStorage/Store',
+
+
+ )
+ self.Retrieve = channel.unary_stream(
+ '/MyGame.Example.MonsterStorage/Retrieve',
+
+
+ )
+ self.GetMaxHitPoint = channel.stream_unary(
+ '/MyGame.Example.MonsterStorage/GetMaxHitPoint',
+
+
+ )
+ self.GetMinMaxHitPoints = channel.unary_unary(
+ '/MyGame.Example.MonsterStorage/GetMinMaxHitPoints',
+
+
+ )
+
+
+ class MonsterStorageServicer(object):
+
+ def Store(self, request, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def Retrieve(self, request, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def GetMaxHitPoint(self, request_iterator, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+ def GetMinMaxHitPoints(self, request, context):
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+
+ def add_MonsterStorageServicer_to_server(servicer, server):
+ rpc_method_handlers = {
+ 'Store': grpc.unary_unary_rpc_method_handler(
+ servicer.Store,
+
+
+ ),
+ 'Retrieve': grpc.unary_stream_rpc_method_handler(
+ servicer.Retrieve,
+
+
+ ),
+ 'GetMaxHitPoint': grpc.stream_unary_rpc_method_handler(
+ servicer.GetMaxHitPoint,
+
+
+ ),
+ 'GetMinMaxHitPoints': grpc.unary_unary_rpc_method_handler(
+ servicer.GetMinMaxHitPoints,
+
+
+ ),
+ }
+ generic_handler = grpc.method_handlers_generic_handler(
+ 'MyGame.Example.MonsterStorage', rpc_method_handlers)
+ server.add_generic_rpc_handlers((generic_handler,))
+
+
+ class BetaMonsterStorageServicer(object):
+ """The Beta API is deprecated for 0.15.0 and later.
+
+ It is recommended to use the GA API (classes and functions in this
+ file not marked beta) for all further purposes. This class was generated
+ only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+ def Store(self, request, context):
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+ def Retrieve(self, request, context):
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+ def GetMaxHitPoint(self, request_iterator, context):
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+ def GetMinMaxHitPoints(self, request, context):
+ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
+
+ class BetaMonsterStorageStub(object):
+ """The Beta API is deprecated for 0.15.0 and later.
+
+ It is recommended to use the GA API (classes and functions in this
+ file not marked beta) for all further purposes. This class was generated
+ only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+ def Store(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+ raise NotImplementedError()
+ Store.future = None
+ def Retrieve(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+ raise NotImplementedError()
+ def GetMaxHitPoint(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
+ raise NotImplementedError()
+ GetMaxHitPoint.future = None
+ def GetMinMaxHitPoints(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+ raise NotImplementedError()
+ GetMinMaxHitPoints.future = None
+
+
+ def beta_create_MonsterStorage_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+ """The Beta API is deprecated for 0.15.0 and later.
+
+ It is recommended to use the GA API (classes and functions in this
+ file not marked beta) for all further purposes. This function was
+ generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+ method_implementations = {
+ ('MyGame.Example.MonsterStorage', 'GetMaxHitPoint'): face_utilities.stream_unary_inline(servicer.GetMaxHitPoint),
+ ('MyGame.Example.MonsterStorage', 'GetMinMaxHitPoints'): face_utilities.unary_unary_inline(servicer.GetMinMaxHitPoints),
+ ('MyGame.Example.MonsterStorage', 'Retrieve'): face_utilities.unary_stream_inline(servicer.Retrieve),
+ ('MyGame.Example.MonsterStorage', 'Store'): face_utilities.unary_unary_inline(servicer.Store),
+ }
+ server_options = beta_implementations.server_options(thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+ return beta_implementations.server(method_implementations, options=server_options)
+
+
+ def beta_create_MonsterStorage_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+ """The Beta API is deprecated for 0.15.0 and later.
+
+ It is recommended to use the GA API (classes and functions in this
+ file not marked beta) for all further purposes. This function was
+ generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+ cardinalities = {
+ 'GetMaxHitPoint': cardinality.Cardinality.STREAM_UNARY,
+ 'GetMinMaxHitPoints': cardinality.Cardinality.UNARY_UNARY,
+ 'Retrieve': cardinality.Cardinality.UNARY_STREAM,
+ 'Store': cardinality.Cardinality.UNARY_UNARY,
+ }
+ stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, thread_pool=pool, thread_pool_size=pool_size)
+ return beta_implementations.dynamic_stub(channel, 'MyGame.Example.MonsterStorage', cardinalities, options=stub_options)
+except ImportError:
+ pass \ No newline at end of file
diff --git a/tests/MyGame/Example2/Monster.cs b/tests/MyGame/Example2/Monster.cs
index e880ebbe..3291ee8e 100644
--- a/tests/MyGame/Example2/Monster.cs
+++ b/tests/MyGame/Example2/Monster.cs
@@ -6,24 +6,45 @@ namespace MyGame.Example2
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Monster : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(0); }
- public static Offset<Monster> EndMonster(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<Monster>(o);
+ public static void StartMonster(FlatBufferBuilder builder) { builder.StartTable(0); }
+ public static Offset<MyGame.Example2.Monster> EndMonster(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<MyGame.Example2.Monster>(o);
+ }
+ public MonsterT UnPack() {
+ var _o = new MonsterT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(MonsterT _o) {
+ }
+ public static Offset<MyGame.Example2.Monster> Pack(FlatBufferBuilder builder, MonsterT _o) {
+ if (_o == null) return default(Offset<MyGame.Example2.Monster>);
+ StartMonster(builder);
+ return EndMonster(builder);
}
};
+public class MonsterT
+{
+
+ public MonsterT() {
+ }
+}
+
}
diff --git a/tests/MyGame/Example2/Monster.go b/tests/MyGame/Example2/Monster.go
index d0fae94d..33309f8b 100644
--- a/tests/MyGame/Example2/Monster.go
+++ b/tests/MyGame/Example2/Monster.go
@@ -6,6 +6,25 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type MonsterT struct {
+}
+
+func (t *MonsterT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ MonsterStart(builder)
+ return MonsterEnd(builder)
+}
+
+func (rcv *Monster) UnPackTo(t *MonsterT) {
+}
+
+func (rcv *Monster) UnPack() *MonsterT {
+ if rcv == nil { return nil }
+ t := &MonsterT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type Monster struct {
_tab flatbuffers.Table
}
diff --git a/tests/MyGame/Example2/Monster.java b/tests/MyGame/Example2/Monster.java
index f65e7d4c..950c4278 100644
--- a/tests/MyGame/Example2/Monster.java
+++ b/tests/MyGame/Example2/Monster.java
@@ -9,16 +9,24 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Monster extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public static void startMonster(FlatBufferBuilder builder) { builder.startObject(0); }
+ public static void startMonster(FlatBufferBuilder builder) { builder.startTable(0); }
public static int endMonster(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Monster get(int j) { return get(new Monster(), j); }
+ public Monster get(Monster obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/MyGame/Example2/Monster.kt b/tests/MyGame/Example2/Monster.kt
new file mode 100644
index 00000000..f1df2e0e
--- /dev/null
+++ b/tests/MyGame/Example2/Monster.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame.Example2
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Monster : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Monster {
+ __init(_i, _bb)
+ return this
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsMonster(_bb: ByteBuffer): Monster = getRootAsMonster(_bb, Monster())
+ fun getRootAsMonster(_bb: ByteBuffer, obj: Monster): Monster {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun startMonster(builder: FlatBufferBuilder) = builder.startTable(0)
+ fun endMonster(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/MyGame/Example2/Monster.py b/tests/MyGame/Example2/Monster.py
index d334f8ea..538b0354 100644
--- a/tests/MyGame/Example2/Monster.py
+++ b/tests/MyGame/Example2/Monster.py
@@ -3,6 +3,8 @@
# namespace: Example2
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class Monster(object):
__slots__ = ['_tab']
@@ -14,9 +16,43 @@ class Monster(object):
x.Init(buf, n + offset)
return x
+ @classmethod
+ def MonsterBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
# Monster
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
def MonsterStart(builder): builder.StartObject(0)
def MonsterEnd(builder): return builder.EndObject()
+
+
+class MonsterT(object):
+
+ # MonsterT
+ def __init__(self):
+ pass
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ monster = Monster()
+ monster.Init(buf, pos)
+ return cls.InitFromObj(monster)
+
+ @classmethod
+ def InitFromObj(cls, monster):
+ x = MonsterT()
+ x._UnPack(monster)
+ return x
+
+ # MonsterT
+ def _UnPack(self, monster):
+ if monster is None:
+ return
+
+ # MonsterT
+ def Pack(self, builder):
+ MonsterStart(builder)
+ monster = MonsterEnd(builder)
+ return monster
diff --git a/tests/MyGame/InParentNamespace.cs b/tests/MyGame/InParentNamespace.cs
index 7b8ffc2d..efefa341 100644
--- a/tests/MyGame/InParentNamespace.cs
+++ b/tests/MyGame/InParentNamespace.cs
@@ -6,24 +6,45 @@ namespace MyGame
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct InParentNamespace : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb) { return GetRootAsInParentNamespace(_bb, new InParentNamespace()); }
public static InParentNamespace GetRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public InParentNamespace __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public static void StartInParentNamespace(FlatBufferBuilder builder) { builder.StartObject(0); }
- public static Offset<InParentNamespace> EndInParentNamespace(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<InParentNamespace>(o);
+ public static void StartInParentNamespace(FlatBufferBuilder builder) { builder.StartTable(0); }
+ public static Offset<MyGame.InParentNamespace> EndInParentNamespace(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<MyGame.InParentNamespace>(o);
+ }
+ public InParentNamespaceT UnPack() {
+ var _o = new InParentNamespaceT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(InParentNamespaceT _o) {
+ }
+ public static Offset<MyGame.InParentNamespace> Pack(FlatBufferBuilder builder, InParentNamespaceT _o) {
+ if (_o == null) return default(Offset<MyGame.InParentNamespace>);
+ StartInParentNamespace(builder);
+ return EndInParentNamespace(builder);
}
};
+public class InParentNamespaceT
+{
+
+ public InParentNamespaceT() {
+ }
+}
+
}
diff --git a/tests/MyGame/InParentNamespace.go b/tests/MyGame/InParentNamespace.go
index fc6ce326..9c5adf72 100644
--- a/tests/MyGame/InParentNamespace.go
+++ b/tests/MyGame/InParentNamespace.go
@@ -6,6 +6,25 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type InParentNamespaceT struct {
+}
+
+func (t *InParentNamespaceT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ InParentNamespaceStart(builder)
+ return InParentNamespaceEnd(builder)
+}
+
+func (rcv *InParentNamespace) UnPackTo(t *InParentNamespaceT) {
+}
+
+func (rcv *InParentNamespace) UnPack() *InParentNamespaceT {
+ if rcv == nil { return nil }
+ t := &InParentNamespaceT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type InParentNamespace struct {
_tab flatbuffers.Table
}
diff --git a/tests/MyGame/InParentNamespace.java b/tests/MyGame/InParentNamespace.java
index 42784b79..20a1ea8e 100644
--- a/tests/MyGame/InParentNamespace.java
+++ b/tests/MyGame/InParentNamespace.java
@@ -9,16 +9,24 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class InParentNamespace extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb) { return getRootAsInParentNamespace(_bb, new InParentNamespace()); }
public static InParentNamespace getRootAsInParentNamespace(ByteBuffer _bb, InParentNamespace obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public InParentNamespace __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public static void startInParentNamespace(FlatBufferBuilder builder) { builder.startObject(0); }
+ public static void startInParentNamespace(FlatBufferBuilder builder) { builder.startTable(0); }
public static int endInParentNamespace(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public InParentNamespace get(int j) { return get(new InParentNamespace(), j); }
+ public InParentNamespace get(InParentNamespace obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/MyGame/InParentNamespace.kt b/tests/MyGame/InParentNamespace.kt
new file mode 100644
index 00000000..02f078e2
--- /dev/null
+++ b/tests/MyGame/InParentNamespace.kt
@@ -0,0 +1,33 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class InParentNamespace : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : InParentNamespace {
+ __init(_i, _bb)
+ return this
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsInParentNamespace(_bb: ByteBuffer): InParentNamespace = getRootAsInParentNamespace(_bb, InParentNamespace())
+ fun getRootAsInParentNamespace(_bb: ByteBuffer, obj: InParentNamespace): InParentNamespace {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun startInParentNamespace(builder: FlatBufferBuilder) = builder.startTable(0)
+ fun endInParentNamespace(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/MyGame/InParentNamespace.py b/tests/MyGame/InParentNamespace.py
index 428d9a94..e78ea6a1 100644
--- a/tests/MyGame/InParentNamespace.py
+++ b/tests/MyGame/InParentNamespace.py
@@ -3,6 +3,8 @@
# namespace: MyGame
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class InParentNamespace(object):
__slots__ = ['_tab']
@@ -14,9 +16,43 @@ class InParentNamespace(object):
x.Init(buf, n + offset)
return x
+ @classmethod
+ def InParentNamespaceBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x53", size_prefixed=size_prefixed)
+
# InParentNamespace
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
def InParentNamespaceStart(builder): builder.StartObject(0)
def InParentNamespaceEnd(builder): return builder.EndObject()
+
+
+class InParentNamespaceT(object):
+
+ # InParentNamespaceT
+ def __init__(self):
+ pass
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ inParentNamespace = InParentNamespace()
+ inParentNamespace.Init(buf, pos)
+ return cls.InitFromObj(inParentNamespace)
+
+ @classmethod
+ def InitFromObj(cls, inParentNamespace):
+ x = InParentNamespaceT()
+ x._UnPack(inParentNamespace)
+ return x
+
+ # InParentNamespaceT
+ def _UnPack(self, inParentNamespace):
+ if inParentNamespace is None:
+ return
+
+ # InParentNamespaceT
+ def Pack(self, builder):
+ InParentNamespaceStart(builder)
+ inParentNamespace = InParentNamespaceEnd(builder)
+ return inParentNamespace
diff --git a/tests/MyGame/MonsterExtra.cs b/tests/MyGame/MonsterExtra.cs
index fc9a3234..f2f49314 100644
--- a/tests/MyGame/MonsterExtra.cs
+++ b/tests/MyGame/MonsterExtra.cs
@@ -6,59 +6,200 @@ namespace MyGame
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct MonsterExtra : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb) { return GetRootAsMonsterExtra(_bb, new MonsterExtra()); }
public static MonsterExtra GetRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public static bool MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONE"); }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public float TestfNan { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
- public bool MutateTestfNan(float testf_nan) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf_nan); return true; } else { return false; } }
- public float TestfPinf { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
- public bool MutateTestfPinf(float testf_pinf) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf_pinf); return true; } else { return false; } }
- public float TestfNinf { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
- public bool MutateTestfNinf(float testf_ninf) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf_ninf); return true; } else { return false; } }
- public double TestdNan { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
- public bool MutateTestdNan(double testd_nan) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, testd_nan); return true; } else { return false; } }
- public double TestdPinf { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.PositiveInfinity; } }
- public bool MutateTestdPinf(double testd_pinf) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, testd_pinf); return true; } else { return false; } }
- public double TestdNinf { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NegativeInfinity; } }
- public bool MutateTestdNinf(double testd_ninf) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, testd_ninf); return true; } else { return false; } }
+ public double D0 { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
+ public bool MutateD0(double d0) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d0); return true; } else { return false; } }
+ public double D1 { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NaN; } }
+ public bool MutateD1(double d1) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d1); return true; } else { return false; } }
+ public double D2 { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.PositiveInfinity; } }
+ public bool MutateD2(double d2) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d2); return true; } else { return false; } }
+ public double D3 { get { int o = __p.__offset(10); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)Double.NegativeInfinity; } }
+ public bool MutateD3(double d3) { int o = __p.__offset(10); if (o != 0) { __p.bb.PutDouble(o + __p.bb_pos, d3); return true; } else { return false; } }
+ public float F0 { get { int o = __p.__offset(12); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
+ public bool MutateF0(float f0) { int o = __p.__offset(12); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f0); return true; } else { return false; } }
+ public float F1 { get { int o = __p.__offset(14); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NaN; } }
+ public bool MutateF1(float f1) { int o = __p.__offset(14); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f1); return true; } else { return false; } }
+ public float F2 { get { int o = __p.__offset(16); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.PositiveInfinity; } }
+ public bool MutateF2(float f2) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f2); return true; } else { return false; } }
+ public float F3 { get { int o = __p.__offset(18); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)Single.NegativeInfinity; } }
+ public bool MutateF3(float f3) { int o = __p.__offset(18); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, f3); return true; } else { return false; } }
+ public double Dvec(int j) { int o = __p.__offset(20); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
+ public int DvecLength { get { int o = __p.__offset(20); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+ public Span<double> GetDvecBytes() { return __p.__vector_as_span<double>(20, 8); }
+#else
+ public ArraySegment<byte>? GetDvecBytes() { return __p.__vector_as_arraysegment(20); }
+#endif
+ public double[] GetDvecArray() { return __p.__vector_as_array<double>(20); }
+ public bool MutateDvec(int j, double dvec) { int o = __p.__offset(20); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, dvec); return true; } else { return false; } }
+ public float Fvec(int j) { int o = __p.__offset(22); return o != 0 ? __p.bb.GetFloat(__p.__vector(o) + j * 4) : (float)0; }
+ public int FvecLength { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
+#if ENABLE_SPAN_T
+ public Span<float> GetFvecBytes() { return __p.__vector_as_span<float>(22, 4); }
+#else
+ public ArraySegment<byte>? GetFvecBytes() { return __p.__vector_as_arraysegment(22); }
+#endif
+ public float[] GetFvecArray() { return __p.__vector_as_array<float>(22); }
+ public bool MutateFvec(int j, float fvec) { int o = __p.__offset(22); if (o != 0) { __p.bb.PutFloat(__p.__vector(o) + j * 4, fvec); return true; } else { return false; } }
- public static Offset<MonsterExtra> CreateMonsterExtra(FlatBufferBuilder builder,
- float testf_nan = Single.NaN,
- float testf_pinf = Single.PositiveInfinity,
- float testf_ninf = Single.NegativeInfinity,
- double testd_nan = Double.NaN,
- double testd_pinf = Double.PositiveInfinity,
- double testd_ninf = Double.NegativeInfinity) {
- builder.StartObject(6);
- MonsterExtra.AddTestdNinf(builder, testd_ninf);
- MonsterExtra.AddTestdPinf(builder, testd_pinf);
- MonsterExtra.AddTestdNan(builder, testd_nan);
- MonsterExtra.AddTestfNinf(builder, testf_ninf);
- MonsterExtra.AddTestfPinf(builder, testf_pinf);
- MonsterExtra.AddTestfNan(builder, testf_nan);
+ public static Offset<MyGame.MonsterExtra> CreateMonsterExtra(FlatBufferBuilder builder,
+ double d0 = Double.NaN,
+ double d1 = Double.NaN,
+ double d2 = Double.PositiveInfinity,
+ double d3 = Double.NegativeInfinity,
+ float f0 = Single.NaN,
+ float f1 = Single.NaN,
+ float f2 = Single.PositiveInfinity,
+ float f3 = Single.NegativeInfinity,
+ VectorOffset dvecOffset = default(VectorOffset),
+ VectorOffset fvecOffset = default(VectorOffset)) {
+ builder.StartTable(11);
+ MonsterExtra.AddD3(builder, d3);
+ MonsterExtra.AddD2(builder, d2);
+ MonsterExtra.AddD1(builder, d1);
+ MonsterExtra.AddD0(builder, d0);
+ MonsterExtra.AddFvec(builder, fvecOffset);
+ MonsterExtra.AddDvec(builder, dvecOffset);
+ MonsterExtra.AddF3(builder, f3);
+ MonsterExtra.AddF2(builder, f2);
+ MonsterExtra.AddF1(builder, f1);
+ MonsterExtra.AddF0(builder, f0);
return MonsterExtra.EndMonsterExtra(builder);
}
- public static void StartMonsterExtra(FlatBufferBuilder builder) { builder.StartObject(6); }
- public static void AddTestfNan(FlatBufferBuilder builder, float testfNan) { builder.AddFloat(0, testfNan, Single.NaN); }
- public static void AddTestfPinf(FlatBufferBuilder builder, float testfPinf) { builder.AddFloat(1, testfPinf, Single.PositiveInfinity); }
- public static void AddTestfNinf(FlatBufferBuilder builder, float testfNinf) { builder.AddFloat(2, testfNinf, Single.NegativeInfinity); }
- public static void AddTestdNan(FlatBufferBuilder builder, double testdNan) { builder.AddDouble(3, testdNan, Double.NaN); }
- public static void AddTestdPinf(FlatBufferBuilder builder, double testdPinf) { builder.AddDouble(4, testdPinf, Double.PositiveInfinity); }
- public static void AddTestdNinf(FlatBufferBuilder builder, double testdNinf) { builder.AddDouble(5, testdNinf, Double.NegativeInfinity); }
- public static Offset<MonsterExtra> EndMonsterExtra(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<MonsterExtra>(o);
+ public static void StartMonsterExtra(FlatBufferBuilder builder) { builder.StartTable(11); }
+ public static void AddD0(FlatBufferBuilder builder, double d0) { builder.AddDouble(0, d0, Double.NaN); }
+ public static void AddD1(FlatBufferBuilder builder, double d1) { builder.AddDouble(1, d1, Double.NaN); }
+ public static void AddD2(FlatBufferBuilder builder, double d2) { builder.AddDouble(2, d2, Double.PositiveInfinity); }
+ public static void AddD3(FlatBufferBuilder builder, double d3) { builder.AddDouble(3, d3, Double.NegativeInfinity); }
+ public static void AddF0(FlatBufferBuilder builder, float f0) { builder.AddFloat(4, f0, Single.NaN); }
+ public static void AddF1(FlatBufferBuilder builder, float f1) { builder.AddFloat(5, f1, Single.NaN); }
+ public static void AddF2(FlatBufferBuilder builder, float f2) { builder.AddFloat(6, f2, Single.PositiveInfinity); }
+ public static void AddF3(FlatBufferBuilder builder, float f3) { builder.AddFloat(7, f3, Single.NegativeInfinity); }
+ public static void AddDvec(FlatBufferBuilder builder, VectorOffset dvecOffset) { builder.AddOffset(8, dvecOffset.Value, 0); }
+ public static VectorOffset CreateDvecVector(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 CreateDvecVectorBlock(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); builder.Add(data); return builder.EndVector(); }
+ public static void StartDvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
+ public static void AddFvec(FlatBufferBuilder builder, VectorOffset fvecOffset) { builder.AddOffset(9, fvecOffset.Value, 0); }
+ public static VectorOffset CreateFvecVector(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddFloat(data[i]); return builder.EndVector(); }
+ public static VectorOffset CreateFvecVectorBlock(FlatBufferBuilder builder, float[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
+ public static void StartFvecVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
+ public static Offset<MyGame.MonsterExtra> EndMonsterExtra(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<MyGame.MonsterExtra>(o);
+ }
+ public static void FinishMonsterExtraBuffer(FlatBufferBuilder builder, Offset<MyGame.MonsterExtra> offset) { builder.Finish(offset.Value, "MONE"); }
+ public static void FinishSizePrefixedMonsterExtraBuffer(FlatBufferBuilder builder, Offset<MyGame.MonsterExtra> offset) { builder.FinishSizePrefixed(offset.Value, "MONE"); }
+ public MonsterExtraT UnPack() {
+ var _o = new MonsterExtraT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(MonsterExtraT _o) {
+ _o.D0 = this.D0;
+ _o.D1 = this.D1;
+ _o.D2 = this.D2;
+ _o.D3 = this.D3;
+ _o.F0 = this.F0;
+ _o.F1 = this.F1;
+ _o.F2 = this.F2;
+ _o.F3 = this.F3;
+ _o.Dvec = new List<double>();
+ for (var _j = 0; _j < this.DvecLength; ++_j) {_o.Dvec.Add(this.Dvec(_j));}
+ _o.Fvec = new List<float>();
+ for (var _j = 0; _j < this.FvecLength; ++_j) {_o.Fvec.Add(this.Fvec(_j));}
+ }
+ public static Offset<MyGame.MonsterExtra> Pack(FlatBufferBuilder builder, MonsterExtraT _o) {
+ if (_o == null) return default(Offset<MyGame.MonsterExtra>);
+ var _dvec = default(VectorOffset);
+ if (_o.Dvec != null) {
+ var __dvec = _o.Dvec.ToArray();
+ _dvec = CreateDvecVector(builder, __dvec);
+ }
+ var _fvec = default(VectorOffset);
+ if (_o.Fvec != null) {
+ var __fvec = _o.Fvec.ToArray();
+ _fvec = CreateFvecVector(builder, __fvec);
+ }
+ return CreateMonsterExtra(
+ builder,
+ _o.D0,
+ _o.D1,
+ _o.D2,
+ _o.D3,
+ _o.F0,
+ _o.F1,
+ _o.F2,
+ _o.F3,
+ _dvec,
+ _fvec);
}
};
+public class MonsterExtraT
+{
+ [Newtonsoft.Json.JsonProperty("d0")]
+ public double D0 { get; set; }
+ [Newtonsoft.Json.JsonProperty("d1")]
+ public double D1 { get; set; }
+ [Newtonsoft.Json.JsonProperty("d2")]
+ public double D2 { get; set; }
+ [Newtonsoft.Json.JsonProperty("d3")]
+ public double D3 { get; set; }
+ [Newtonsoft.Json.JsonProperty("f0")]
+ public float F0 { get; set; }
+ [Newtonsoft.Json.JsonProperty("f1")]
+ public float F1 { get; set; }
+ [Newtonsoft.Json.JsonProperty("f2")]
+ public float F2 { get; set; }
+ [Newtonsoft.Json.JsonProperty("f3")]
+ public float F3 { get; set; }
+ [Newtonsoft.Json.JsonProperty("dvec")]
+ public List<double> Dvec { get; set; }
+ [Newtonsoft.Json.JsonProperty("fvec")]
+ public List<float> Fvec { get; set; }
+
+ public MonsterExtraT() {
+ this.D0 = Double.NaN;
+ this.D1 = Double.NaN;
+ this.D2 = Double.PositiveInfinity;
+ this.D3 = Double.NegativeInfinity;
+ this.F0 = Single.NaN;
+ this.F1 = Single.NaN;
+ this.F2 = Single.PositiveInfinity;
+ this.F3 = Single.NegativeInfinity;
+ this.Dvec = null;
+ this.Fvec = null;
+ }
+
+ public static MonsterExtraT DeserializeFromJson(string jsonText) {
+ return Newtonsoft.Json.JsonConvert.DeserializeObject<MonsterExtraT>(jsonText);
+ }
+ public string SerializeToJson() {
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ }
+ public static MonsterExtraT DeserializeFromBinary(byte[] fbBuffer) {
+ return MonsterExtra.GetRootAsMonsterExtra(new ByteBuffer(fbBuffer)).UnPack();
+ }
+ public byte[] SerializeToBinary() {
+ var fbb = new FlatBufferBuilder(0x10000);
+ fbb.Finish(MonsterExtra.Pack(fbb, this).Value);
+ return fbb.DataBuffer.ToSizedArray();
+ }
+}
+
}
diff --git a/tests/MyGame/MonsterExtra.java b/tests/MyGame/MonsterExtra.java
index fecfadde..8a5fe75e 100644
--- a/tests/MyGame/MonsterExtra.java
+++ b/tests/MyGame/MonsterExtra.java
@@ -9,51 +9,96 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class MonsterExtra extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb) { return getRootAsMonsterExtra(_bb, new MonsterExtra()); }
public static MonsterExtra getRootAsMonsterExtra(ByteBuffer _bb, MonsterExtra obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public static boolean MonsterExtraBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONE"); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public MonsterExtra __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
- public float testfNan() { int o = __offset(4); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
- public boolean mutateTestfNan(float testf_nan) { int o = __offset(4); if (o != 0) { bb.putFloat(o + bb_pos, testf_nan); return true; } else { return false; } }
- public float testfPinf() { int o = __offset(6); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
- public boolean mutateTestfPinf(float testf_pinf) { int o = __offset(6); if (o != 0) { bb.putFloat(o + bb_pos, testf_pinf); return true; } else { return false; } }
- public float testfNinf() { int o = __offset(8); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; }
- public boolean mutateTestfNinf(float testf_ninf) { int o = __offset(8); if (o != 0) { bb.putFloat(o + bb_pos, testf_ninf); return true; } else { return false; } }
- public double testdNan() { int o = __offset(10); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
- public boolean mutateTestdNan(double testd_nan) { int o = __offset(10); if (o != 0) { bb.putDouble(o + bb_pos, testd_nan); return true; } else { return false; } }
- public double testdPinf() { int o = __offset(12); return o != 0 ? bb.getDouble(o + bb_pos) : Double.POSITIVE_INFINITY; }
- public boolean mutateTestdPinf(double testd_pinf) { int o = __offset(12); if (o != 0) { bb.putDouble(o + bb_pos, testd_pinf); return true; } else { return false; } }
- public double testdNinf() { int o = __offset(14); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NEGATIVE_INFINITY; }
- public boolean mutateTestdNinf(double testd_ninf) { int o = __offset(14); if (o != 0) { bb.putDouble(o + bb_pos, testd_ninf); return true; } else { return false; } }
+ public double d0() { int o = __offset(4); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
+ public boolean mutateD0(double d0) { int o = __offset(4); if (o != 0) { bb.putDouble(o + bb_pos, d0); return true; } else { return false; } }
+ public double d1() { int o = __offset(6); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NaN; }
+ public boolean mutateD1(double d1) { int o = __offset(6); if (o != 0) { bb.putDouble(o + bb_pos, d1); return true; } else { return false; } }
+ public double d2() { int o = __offset(8); return o != 0 ? bb.getDouble(o + bb_pos) : Double.POSITIVE_INFINITY; }
+ public boolean mutateD2(double d2) { int o = __offset(8); if (o != 0) { bb.putDouble(o + bb_pos, d2); return true; } else { return false; } }
+ public double d3() { int o = __offset(10); return o != 0 ? bb.getDouble(o + bb_pos) : Double.NEGATIVE_INFINITY; }
+ public boolean mutateD3(double d3) { int o = __offset(10); if (o != 0) { bb.putDouble(o + bb_pos, d3); return true; } else { return false; } }
+ public float f0() { int o = __offset(12); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
+ public boolean mutateF0(float f0) { int o = __offset(12); if (o != 0) { bb.putFloat(o + bb_pos, f0); return true; } else { return false; } }
+ public float f1() { int o = __offset(14); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NaN; }
+ public boolean mutateF1(float f1) { int o = __offset(14); if (o != 0) { bb.putFloat(o + bb_pos, f1); return true; } else { return false; } }
+ public float f2() { int o = __offset(16); return o != 0 ? bb.getFloat(o + bb_pos) : Float.POSITIVE_INFINITY; }
+ public boolean mutateF2(float f2) { int o = __offset(16); if (o != 0) { bb.putFloat(o + bb_pos, f2); return true; } else { return false; } }
+ public float f3() { int o = __offset(18); return o != 0 ? bb.getFloat(o + bb_pos) : Float.NEGATIVE_INFINITY; }
+ public boolean mutateF3(float f3) { int o = __offset(18); if (o != 0) { bb.putFloat(o + bb_pos, f3); return true; } else { return false; } }
+ public double dvec(int j) { int o = __offset(20); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
+ public int dvecLength() { int o = __offset(20); return o != 0 ? __vector_len(o) : 0; }
+ public DoubleVector dvecVector() { return dvecVector(new DoubleVector()); }
+ public DoubleVector dvecVector(DoubleVector obj) { int o = __offset(20); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
+ public ByteBuffer dvecAsByteBuffer() { return __vector_as_bytebuffer(20, 8); }
+ public ByteBuffer dvecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 20, 8); }
+ public boolean mutateDvec(int j, double dvec) { int o = __offset(20); if (o != 0) { bb.putDouble(__vector(o) + j * 8, dvec); return true; } else { return false; } }
+ public float fvec(int j) { int o = __offset(22); return o != 0 ? bb.getFloat(__vector(o) + j * 4) : 0; }
+ public int fvecLength() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
+ public FloatVector fvecVector() { return fvecVector(new FloatVector()); }
+ public FloatVector fvecVector(FloatVector obj) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
+ public ByteBuffer fvecAsByteBuffer() { return __vector_as_bytebuffer(22, 4); }
+ public ByteBuffer fvecInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 22, 4); }
+ public boolean mutateFvec(int j, float fvec) { int o = __offset(22); if (o != 0) { bb.putFloat(__vector(o) + j * 4, fvec); return true; } else { return false; } }
public static int createMonsterExtra(FlatBufferBuilder builder,
- float testf_nan,
- float testf_pinf,
- float testf_ninf,
- double testd_nan,
- double testd_pinf,
- double testd_ninf) {
- builder.startObject(6);
- MonsterExtra.addTestdNinf(builder, testd_ninf);
- MonsterExtra.addTestdPinf(builder, testd_pinf);
- MonsterExtra.addTestdNan(builder, testd_nan);
- MonsterExtra.addTestfNinf(builder, testf_ninf);
- MonsterExtra.addTestfPinf(builder, testf_pinf);
- MonsterExtra.addTestfNan(builder, testf_nan);
+ double d0,
+ double d1,
+ double d2,
+ double d3,
+ float f0,
+ float f1,
+ float f2,
+ float f3,
+ int dvecOffset,
+ int fvecOffset) {
+ builder.startTable(11);
+ MonsterExtra.addD3(builder, d3);
+ MonsterExtra.addD2(builder, d2);
+ MonsterExtra.addD1(builder, d1);
+ MonsterExtra.addD0(builder, d0);
+ MonsterExtra.addFvec(builder, fvecOffset);
+ MonsterExtra.addDvec(builder, dvecOffset);
+ MonsterExtra.addF3(builder, f3);
+ MonsterExtra.addF2(builder, f2);
+ MonsterExtra.addF1(builder, f1);
+ MonsterExtra.addF0(builder, f0);
return MonsterExtra.endMonsterExtra(builder);
}
- public static void startMonsterExtra(FlatBufferBuilder builder) { builder.startObject(6); }
- public static void addTestfNan(FlatBufferBuilder builder, float testfNan) { builder.addFloat(0, testfNan, Float.NaN); }
- public static void addTestfPinf(FlatBufferBuilder builder, float testfPinf) { builder.addFloat(1, testfPinf, Float.POSITIVE_INFINITY); }
- public static void addTestfNinf(FlatBufferBuilder builder, float testfNinf) { builder.addFloat(2, testfNinf, Float.NEGATIVE_INFINITY); }
- public static void addTestdNan(FlatBufferBuilder builder, double testdNan) { builder.addDouble(3, testdNan, Double.NaN); }
- public static void addTestdPinf(FlatBufferBuilder builder, double testdPinf) { builder.addDouble(4, testdPinf, Double.POSITIVE_INFINITY); }
- public static void addTestdNinf(FlatBufferBuilder builder, double testdNinf) { builder.addDouble(5, testdNinf, Double.NEGATIVE_INFINITY); }
+ public static void startMonsterExtra(FlatBufferBuilder builder) { builder.startTable(11); }
+ public static void addD0(FlatBufferBuilder builder, double d0) { builder.addDouble(0, d0, Double.NaN); }
+ public static void addD1(FlatBufferBuilder builder, double d1) { builder.addDouble(1, d1, Double.NaN); }
+ public static void addD2(FlatBufferBuilder builder, double d2) { builder.addDouble(2, d2, Double.POSITIVE_INFINITY); }
+ public static void addD3(FlatBufferBuilder builder, double d3) { builder.addDouble(3, d3, Double.NEGATIVE_INFINITY); }
+ public static void addF0(FlatBufferBuilder builder, float f0) { builder.addFloat(4, f0, Float.NaN); }
+ public static void addF1(FlatBufferBuilder builder, float f1) { builder.addFloat(5, f1, Float.NaN); }
+ public static void addF2(FlatBufferBuilder builder, float f2) { builder.addFloat(6, f2, Float.POSITIVE_INFINITY); }
+ public static void addF3(FlatBufferBuilder builder, float f3) { builder.addFloat(7, f3, Float.NEGATIVE_INFINITY); }
+ public static void addDvec(FlatBufferBuilder builder, int dvecOffset) { builder.addOffset(8, dvecOffset, 0); }
+ public static int createDvecVector(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 void startDvecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
+ public static void addFvec(FlatBufferBuilder builder, int fvecOffset) { builder.addOffset(9, fvecOffset, 0); }
+ public static int createFvecVector(FlatBufferBuilder builder, float[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addFloat(data[i]); return builder.endVector(); }
+ public static void startFvecVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endMonsterExtra(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+ public static void finishMonsterExtraBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONE"); }
+ public static void finishSizePrefixedMonsterExtraBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MONE"); }
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public MonsterExtra get(int j) { return get(new MonsterExtra(), j); }
+ public MonsterExtra get(MonsterExtra obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/MyGame/MonsterExtra.kt b/tests/MyGame/MonsterExtra.kt
new file mode 100644
index 00000000..e025c2f9
--- /dev/null
+++ b/tests/MyGame/MonsterExtra.kt
@@ -0,0 +1,234 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package MyGame
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class MonsterExtra : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : MonsterExtra {
+ __init(_i, _bb)
+ return this
+ }
+ val d0 : Double
+ get() {
+ val o = __offset(4)
+ return if(o != 0) bb.getDouble(o + bb_pos) else Double.NaN
+ }
+ fun mutateD0(d0: Double) : Boolean {
+ val o = __offset(4)
+ return if (o != 0) {
+ bb.putDouble(o + bb_pos, d0)
+ true
+ } else {
+ false
+ }
+ }
+ val d1 : Double
+ get() {
+ val o = __offset(6)
+ return if(o != 0) bb.getDouble(o + bb_pos) else Double.NaN
+ }
+ fun mutateD1(d1: Double) : Boolean {
+ val o = __offset(6)
+ return if (o != 0) {
+ bb.putDouble(o + bb_pos, d1)
+ true
+ } else {
+ false
+ }
+ }
+ val d2 : Double
+ get() {
+ val o = __offset(8)
+ return if(o != 0) bb.getDouble(o + bb_pos) else Double.POSITIVE_INFINITY
+ }
+ fun mutateD2(d2: Double) : Boolean {
+ val o = __offset(8)
+ return if (o != 0) {
+ bb.putDouble(o + bb_pos, d2)
+ true
+ } else {
+ false
+ }
+ }
+ val d3 : Double
+ get() {
+ val o = __offset(10)
+ return if(o != 0) bb.getDouble(o + bb_pos) else Double.NEGATIVE_INFINITY
+ }
+ fun mutateD3(d3: Double) : Boolean {
+ val o = __offset(10)
+ return if (o != 0) {
+ bb.putDouble(o + bb_pos, d3)
+ true
+ } else {
+ false
+ }
+ }
+ val f0 : Float
+ get() {
+ val o = __offset(12)
+ return if(o != 0) bb.getFloat(o + bb_pos) else Float.NaN
+ }
+ fun mutateF0(f0: Float) : Boolean {
+ val o = __offset(12)
+ return if (o != 0) {
+ bb.putFloat(o + bb_pos, f0)
+ true
+ } else {
+ false
+ }
+ }
+ val f1 : Float
+ get() {
+ val o = __offset(14)
+ return if(o != 0) bb.getFloat(o + bb_pos) else Float.NaN
+ }
+ fun mutateF1(f1: Float) : Boolean {
+ val o = __offset(14)
+ return if (o != 0) {
+ bb.putFloat(o + bb_pos, f1)
+ true
+ } else {
+ false
+ }
+ }
+ val f2 : Float
+ get() {
+ val o = __offset(16)
+ return if(o != 0) bb.getFloat(o + bb_pos) else Float.POSITIVE_INFINITY
+ }
+ fun mutateF2(f2: Float) : Boolean {
+ val o = __offset(16)
+ return if (o != 0) {
+ bb.putFloat(o + bb_pos, f2)
+ true
+ } else {
+ false
+ }
+ }
+ val f3 : Float
+ get() {
+ val o = __offset(18)
+ return if(o != 0) bb.getFloat(o + bb_pos) else Float.NEGATIVE_INFINITY
+ }
+ fun mutateF3(f3: Float) : Boolean {
+ val o = __offset(18)
+ return if (o != 0) {
+ bb.putFloat(o + bb_pos, f3)
+ true
+ } else {
+ false
+ }
+ }
+ fun dvec(j: Int) : Double {
+ val o = __offset(20)
+ return if (o != 0) {
+ bb.getDouble(__vector(o) + j * 8)
+ } else {
+ 0.0
+ }
+ }
+ val dvecLength : Int
+ get() {
+ val o = __offset(20); return if (o != 0) __vector_len(o) else 0
+ }
+ val dvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(20, 8)
+ fun dvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 20, 8)
+ fun mutateDvec(j: Int, dvec: Double) : Boolean {
+ val o = __offset(20)
+ return if (o != 0) {
+ bb.putDouble(__vector(o) + j * 8, dvec)
+ true
+ } else {
+ false
+ }
+ }
+ fun fvec(j: Int) : Float {
+ val o = __offset(22)
+ return if (o != 0) {
+ bb.getFloat(__vector(o) + j * 4)
+ } else {
+ 0.0f
+ }
+ }
+ val fvecLength : Int
+ get() {
+ val o = __offset(22); return if (o != 0) __vector_len(o) else 0
+ }
+ val fvecAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(22, 4)
+ fun fvecInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 22, 4)
+ fun mutateFvec(j: Int, fvec: Float) : Boolean {
+ val o = __offset(22)
+ return if (o != 0) {
+ bb.putFloat(__vector(o) + j * 4, fvec)
+ true
+ } else {
+ false
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsMonsterExtra(_bb: ByteBuffer): MonsterExtra = getRootAsMonsterExtra(_bb, MonsterExtra())
+ fun getRootAsMonsterExtra(_bb: ByteBuffer, obj: MonsterExtra): MonsterExtra {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun MonsterExtraBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MONE")
+ fun createMonsterExtra(builder: FlatBufferBuilder, d0: Double, d1: Double, d2: Double, d3: Double, f0: Float, f1: Float, f2: Float, f3: Float, dvecOffset: Int, fvecOffset: Int) : Int {
+ builder.startTable(11)
+ addD3(builder, d3)
+ addD2(builder, d2)
+ addD1(builder, d1)
+ addD0(builder, d0)
+ addFvec(builder, fvecOffset)
+ addDvec(builder, dvecOffset)
+ addF3(builder, f3)
+ addF2(builder, f2)
+ addF1(builder, f1)
+ addF0(builder, f0)
+ return endMonsterExtra(builder)
+ }
+ fun startMonsterExtra(builder: FlatBufferBuilder) = builder.startTable(11)
+ fun addD0(builder: FlatBufferBuilder, d0: Double) = builder.addDouble(0, d0, Double.NaN)
+ fun addD1(builder: FlatBufferBuilder, d1: Double) = builder.addDouble(1, d1, Double.NaN)
+ fun addD2(builder: FlatBufferBuilder, d2: Double) = builder.addDouble(2, d2, Double.POSITIVE_INFINITY)
+ fun addD3(builder: FlatBufferBuilder, d3: Double) = builder.addDouble(3, d3, Double.NEGATIVE_INFINITY)
+ fun addF0(builder: FlatBufferBuilder, f0: Float) = builder.addFloat(4, f0, Double.NaN)
+ fun addF1(builder: FlatBufferBuilder, f1: Float) = builder.addFloat(5, f1, Double.NaN)
+ fun addF2(builder: FlatBufferBuilder, f2: Float) = builder.addFloat(6, f2, Double.POSITIVE_INFINITY)
+ fun addF3(builder: FlatBufferBuilder, f3: Float) = builder.addFloat(7, f3, Double.NEGATIVE_INFINITY)
+ fun addDvec(builder: FlatBufferBuilder, dvec: Int) = builder.addOffset(8, dvec, 0)
+ fun createDvecVector(builder: FlatBufferBuilder, data: DoubleArray) : Int {
+ builder.startVector(8, data.size, 8)
+ for (i in data.size - 1 downTo 0) {
+ builder.addDouble(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startDvecVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(8, numElems, 8)
+ fun addFvec(builder: FlatBufferBuilder, fvec: Int) = builder.addOffset(9, fvec, 0)
+ fun createFvecVector(builder: FlatBufferBuilder, data: FloatArray) : Int {
+ builder.startVector(4, data.size, 4)
+ for (i in data.size - 1 downTo 0) {
+ builder.addFloat(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startFvecVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+ fun endMonsterExtra(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ fun finishMonsterExtraBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MONE")
+ fun finishSizePrefixedMonsterExtraBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MONE")
+ }
+}
diff --git a/tests/MyGame/MonsterExtra.py b/tests/MyGame/MonsterExtra.py
index 3e8b26d3..eafea7cf 100644
--- a/tests/MyGame/MonsterExtra.py
+++ b/tests/MyGame/MonsterExtra.py
@@ -3,6 +3,8 @@
# namespace: MyGame
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class MonsterExtra(object):
__slots__ = ['_tab']
@@ -14,57 +16,228 @@ class MonsterExtra(object):
x.Init(buf, n + offset)
return x
+ @classmethod
+ def MonsterExtraBufferHasIdentifier(cls, buf, offset, size_prefixed=False):
+ return flatbuffers.util.BufferHasIdentifier(buf, offset, b"\x4D\x4F\x4E\x45", size_prefixed=size_prefixed)
+
# MonsterExtra
def Init(self, buf, pos):
self._tab = flatbuffers.table.Table(buf, pos)
# MonsterExtra
- def TestfNan(self):
+ def D0(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+ return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
return float('nan')
# MonsterExtra
- def TestfPinf(self):
+ def D1(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
- return float('inf')
+ return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+ return float('nan')
# MonsterExtra
- def TestfNinf(self):
+ def D2(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
- return float('-inf')
+ return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+ return float('inf')
# MonsterExtra
- def TestdNan(self):
+ def D3(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(10))
if o != 0:
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
- return float('nan')
+ return float('-inf')
# MonsterExtra
- def TestdPinf(self):
+ def F0(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(12))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
- return float('inf')
+ return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+ return float('nan')
# MonsterExtra
- def TestdNinf(self):
+ def F1(self):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(14))
if o != 0:
- return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
+ return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+ return float('nan')
+
+ # MonsterExtra
+ def F2(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(16))
+ if o != 0:
+ return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
+ return float('inf')
+
+ # MonsterExtra
+ def F3(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(18))
+ if o != 0:
+ return self._tab.Get(flatbuffers.number_types.Float32Flags, o + self._tab.Pos)
return float('-inf')
-def MonsterExtraStart(builder): builder.StartObject(6)
-def MonsterExtraAddTestfNan(builder, testfNan): builder.PrependFloat32Slot(0, testfNan, float('nan'))
-def MonsterExtraAddTestfPinf(builder, testfPinf): builder.PrependFloat32Slot(1, testfPinf, float('inf'))
-def MonsterExtraAddTestfNinf(builder, testfNinf): builder.PrependFloat32Slot(2, testfNinf, float('-inf'))
-def MonsterExtraAddTestdNan(builder, testdNan): builder.PrependFloat64Slot(3, testdNan, float('nan'))
-def MonsterExtraAddTestdPinf(builder, testdPinf): builder.PrependFloat64Slot(4, testdPinf, float('inf'))
-def MonsterExtraAddTestdNinf(builder, testdNinf): builder.PrependFloat64Slot(5, testdNinf, float('-inf'))
+ # MonsterExtra
+ def Dvec(self, j):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+ if o != 0:
+ a = self._tab.Vector(o)
+ return self._tab.Get(flatbuffers.number_types.Float64Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 8))
+ return 0
+
+ # MonsterExtra
+ def DvecAsNumpy(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+ if o != 0:
+ return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float64Flags, o)
+ return 0
+
+ # MonsterExtra
+ def DvecLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # MonsterExtra
+ def DvecIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(20))
+ return o == 0
+
+ # MonsterExtra
+ def Fvec(self, j):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+ if o != 0:
+ a = self._tab.Vector(o)
+ return self._tab.Get(flatbuffers.number_types.Float32Flags, a + flatbuffers.number_types.UOffsetTFlags.py_type(j * 4))
+ return 0
+
+ # MonsterExtra
+ def FvecAsNumpy(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+ if o != 0:
+ return self._tab.GetVectorAsNumpy(flatbuffers.number_types.Float32Flags, o)
+ return 0
+
+ # MonsterExtra
+ def FvecLength(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+ if o != 0:
+ return self._tab.VectorLen(o)
+ return 0
+
+ # MonsterExtra
+ def FvecIsNone(self):
+ o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(22))
+ return o == 0
+
+def MonsterExtraStart(builder): builder.StartObject(11)
+def MonsterExtraAddD0(builder, d0): builder.PrependFloat64Slot(0, d0, float('nan'))
+def MonsterExtraAddD1(builder, d1): builder.PrependFloat64Slot(1, d1, float('nan'))
+def MonsterExtraAddD2(builder, d2): builder.PrependFloat64Slot(2, d2, float('inf'))
+def MonsterExtraAddD3(builder, d3): builder.PrependFloat64Slot(3, d3, float('-inf'))
+def MonsterExtraAddF0(builder, f0): builder.PrependFloat32Slot(4, f0, float('nan'))
+def MonsterExtraAddF1(builder, f1): builder.PrependFloat32Slot(5, f1, float('nan'))
+def MonsterExtraAddF2(builder, f2): builder.PrependFloat32Slot(6, f2, float('inf'))
+def MonsterExtraAddF3(builder, f3): builder.PrependFloat32Slot(7, f3, float('-inf'))
+def MonsterExtraAddDvec(builder, dvec): builder.PrependUOffsetTRelativeSlot(8, flatbuffers.number_types.UOffsetTFlags.py_type(dvec), 0)
+def MonsterExtraStartDvecVector(builder, numElems): return builder.StartVector(8, numElems, 8)
+def MonsterExtraAddFvec(builder, fvec): builder.PrependUOffsetTRelativeSlot(9, flatbuffers.number_types.UOffsetTFlags.py_type(fvec), 0)
+def MonsterExtraStartFvecVector(builder, numElems): return builder.StartVector(4, numElems, 4)
def MonsterExtraEnd(builder): return builder.EndObject()
+
+try:
+ from typing import List
+except:
+ pass
+
+class MonsterExtraT(object):
+
+ # MonsterExtraT
+ def __init__(self):
+ self.d0 = float('nan') # type: float
+ self.d1 = float('nan') # type: float
+ self.d2 = float('inf') # type: float
+ self.d3 = float('-inf') # type: float
+ self.f0 = float('nan') # type: float
+ self.f1 = float('nan') # type: float
+ self.f2 = float('inf') # type: float
+ self.f3 = float('-inf') # type: float
+ self.dvec = None # type: List[float]
+ self.fvec = None # type: List[float]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ monsterExtra = MonsterExtra()
+ monsterExtra.Init(buf, pos)
+ return cls.InitFromObj(monsterExtra)
+
+ @classmethod
+ def InitFromObj(cls, monsterExtra):
+ x = MonsterExtraT()
+ x._UnPack(monsterExtra)
+ return x
+
+ # MonsterExtraT
+ def _UnPack(self, monsterExtra):
+ if monsterExtra is None:
+ return
+ self.d0 = monsterExtra.D0()
+ self.d1 = monsterExtra.D1()
+ self.d2 = monsterExtra.D2()
+ self.d3 = monsterExtra.D3()
+ self.f0 = monsterExtra.F0()
+ self.f1 = monsterExtra.F1()
+ self.f2 = monsterExtra.F2()
+ self.f3 = monsterExtra.F3()
+ if not monsterExtra.DvecIsNone():
+ if np is None:
+ self.dvec = []
+ for i in range(monsterExtra.DvecLength()):
+ self.dvec.append(monsterExtra.Dvec(i))
+ else:
+ self.dvec = monsterExtra.DvecAsNumpy()
+ if not monsterExtra.FvecIsNone():
+ if np is None:
+ self.fvec = []
+ for i in range(monsterExtra.FvecLength()):
+ self.fvec.append(monsterExtra.Fvec(i))
+ else:
+ self.fvec = monsterExtra.FvecAsNumpy()
+
+ # MonsterExtraT
+ def Pack(self, builder):
+ if self.dvec is not None:
+ if np is not None and type(self.dvec) is np.ndarray:
+ dvec = builder.CreateNumpyVector(self.dvec)
+ else:
+ MonsterExtraStartDvecVector(builder, len(self.dvec))
+ for i in reversed(range(len(self.dvec))):
+ builder.PrependFloat64(self.dvec[i])
+ dvec = builder.EndVector(len(self.dvec))
+ if self.fvec is not None:
+ if np is not None and type(self.fvec) is np.ndarray:
+ fvec = builder.CreateNumpyVector(self.fvec)
+ else:
+ MonsterExtraStartFvecVector(builder, len(self.fvec))
+ for i in reversed(range(len(self.fvec))):
+ builder.PrependFloat32(self.fvec[i])
+ fvec = builder.EndVector(len(self.fvec))
+ MonsterExtraStart(builder)
+ MonsterExtraAddD0(builder, self.d0)
+ MonsterExtraAddD1(builder, self.d1)
+ MonsterExtraAddD2(builder, self.d2)
+ MonsterExtraAddD3(builder, self.d3)
+ MonsterExtraAddF0(builder, self.f0)
+ MonsterExtraAddF1(builder, self.f1)
+ MonsterExtraAddF2(builder, self.f2)
+ MonsterExtraAddF3(builder, self.f3)
+ if self.dvec is not None:
+ MonsterExtraAddDvec(builder, dvec)
+ if self.fvec is not None:
+ MonsterExtraAddFvec(builder, fvec)
+ monsterExtra = MonsterExtraEnd(builder)
+ return monsterExtra
diff --git a/tests/PythonTest.sh b/tests/PythonTest.sh
index e4dbe8da..17133b00 100755
--- a/tests/PythonTest.sh
+++ b/tests/PythonTest.sh
@@ -20,7 +20,7 @@ gen_code_path=${test_dir}
runtime_library_dir=${test_dir}/../python
# Emit Python code for the example schema in the test dir:
-${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs
+${test_dir}/../flatc -p -o ${gen_code_path} -I include_test monster_test.fbs --gen-object-api
# Syntax: run_tests <interpreter> <benchmark vtable dedupes>
# <benchmark read count> <benchmark build count>
diff --git a/tests/TestAll.sh b/tests/TestAll.sh
index e36d079a..e20431c3 100644
--- a/tests/TestAll.sh
+++ b/tests/TestAll.sh
@@ -2,6 +2,10 @@ echo "************************ Java:"
sh JavaTest.sh
+echo "************************ Kotlin:"
+
+sh KotlinTest.sh
+
echo "************************ Go:"
sh GoTest.sh
@@ -56,4 +60,6 @@ echo "(in a different repo)"
echo "************************ Swift:"
-echo "(in a different repo)"
+cd FlatBuffers.Test.Swift
+sh SwiftTest.sh
+cd .. \ No newline at end of file
diff --git a/tests/arrays_test.bfbs b/tests/arrays_test.bfbs
new file mode 100644
index 00000000..d4860720
--- /dev/null
+++ b/tests/arrays_test.bfbs
Binary files differ
diff --git a/tests/arrays_test.fbs b/tests/arrays_test.fbs
new file mode 100644
index 00000000..90cb0d72
--- /dev/null
+++ b/tests/arrays_test.fbs
@@ -0,0 +1,27 @@
+namespace MyGame.Example;
+
+enum TestEnum : byte { A, B, C }
+
+struct NestedStruct{
+ a:[int:2];
+ b:TestEnum;
+ c:[TestEnum:2];
+ d:[int64:2];
+}
+
+struct ArrayStruct{
+ a:float;
+ b:[int:0xF];
+ c:byte;
+ d:[NestedStruct:2];
+ e:int32;
+ f:[int64:2];
+}
+
+table ArrayTable{
+ a:ArrayStruct;
+}
+
+root_type ArrayTable;
+file_identifier "ARRT";
+file_extension "mon";
diff --git a/tests/arrays_test.golden b/tests/arrays_test.golden
new file mode 100644
index 00000000..c7037d7a
--- /dev/null
+++ b/tests/arrays_test.golden
@@ -0,0 +1,23 @@
+{
+ a : {
+ a: 12.34,
+ b: [1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF],
+ c: -127,
+ d: [
+ {
+ a : [-1,2],
+ b : A,
+ c : [C, B],
+ d : [0x1122334455667788, -0x1122334455667788]
+ },
+ {
+ a : [3,-4],
+ b : B,
+ c : [B, A],
+ d : [-0x1122334455667788, 0x1122334455667788]
+ }
+ ],
+ e: 1,
+ f: [-0x8000000000000000, 0x7FFFFFFFFFFFFFFF]
+ }
+} \ No newline at end of file
diff --git a/tests/arrays_test.schema.json b/tests/arrays_test.schema.json
new file mode 100644
index 00000000..1ef5110d
--- /dev/null
+++ b/tests/arrays_test.schema.json
@@ -0,0 +1,73 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "definitions": {
+ "MyGame_Example_TestEnum" : {
+ "type" : "string",
+ "enum": ["A", "B", "C"]
+ },
+ "MyGame_Example_NestedStruct" : {
+ "type" : "object",
+ "properties" : {
+ "a" : {
+ "type" : "array", "items" : { "type" : "number" },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "b" : {
+ "$ref" : "#/definitions/MyGame_Example_TestEnum"
+ },
+ "c" : {
+ "$ref" : "#/definitions/MyGame_Example_TestEnum",
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "d" : {
+ "type" : "array", "items" : { "type" : "number" },
+ "minItems": 2,
+ "maxItems": 2
+ }
+ },
+ "additionalProperties" : false
+ },
+ "MyGame_Example_ArrayStruct" : {
+ "type" : "object",
+ "properties" : {
+ "a" : {
+ "type" : "number"
+ },
+ "b" : {
+ "type" : "array", "items" : { "type" : "number" },
+ "minItems": 15,
+ "maxItems": 15
+ },
+ "c" : {
+ "type" : "number"
+ },
+ "d" : {
+ "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_NestedStruct" },
+ "minItems": 2,
+ "maxItems": 2
+ },
+ "e" : {
+ "type" : "number"
+ },
+ "f" : {
+ "type" : "array", "items" : { "type" : "number" },
+ "minItems": 2,
+ "maxItems": 2
+ }
+ },
+ "additionalProperties" : false
+ },
+ "MyGame_Example_ArrayTable" : {
+ "type" : "object",
+ "properties" : {
+ "a" : {
+ "$ref" : "#/definitions/MyGame_Example_ArrayStruct"
+ }
+ },
+ "additionalProperties" : false
+ }
+ },
+ "$ref" : "#/definitions/MyGame_Example_ArrayTable"
+}
diff --git a/tests/arrays_test_generated.h b/tests/arrays_test_generated.h
new file mode 100644
index 00000000..30e78846
--- /dev/null
+++ b/tests/arrays_test_generated.h
@@ -0,0 +1,459 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
+#define FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace MyGame {
+namespace Example {
+
+struct NestedStruct;
+
+struct ArrayStruct;
+
+struct ArrayTable;
+struct ArrayTableBuilder;
+struct ArrayTableT;
+
+bool operator==(const NestedStruct &lhs, const NestedStruct &rhs);
+bool operator!=(const NestedStruct &lhs, const NestedStruct &rhs);
+bool operator==(const ArrayStruct &lhs, const ArrayStruct &rhs);
+bool operator!=(const ArrayStruct &lhs, const ArrayStruct &rhs);
+bool operator==(const ArrayTableT &lhs, const ArrayTableT &rhs);
+bool operator!=(const ArrayTableT &lhs, const ArrayTableT &rhs);
+
+inline const flatbuffers::TypeTable *NestedStructTypeTable();
+
+inline const flatbuffers::TypeTable *ArrayStructTypeTable();
+
+inline const flatbuffers::TypeTable *ArrayTableTypeTable();
+
+enum class TestEnum : int8_t {
+ A = 0,
+ B = 1,
+ C = 2,
+ MIN = A,
+ MAX = C
+};
+
+inline const TestEnum (&EnumValuesTestEnum())[3] {
+ static const TestEnum values[] = {
+ TestEnum::A,
+ TestEnum::B,
+ TestEnum::C
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesTestEnum() {
+ static const char * const names[4] = {
+ "A",
+ "B",
+ "C",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameTestEnum(TestEnum e) {
+ if (flatbuffers::IsOutRange(e, TestEnum::A, TestEnum::C)) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesTestEnum()[index];
+}
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) NestedStruct FLATBUFFERS_FINAL_CLASS {
+ private:
+ int32_t a_[2];
+ int8_t b_;
+ int8_t c_[2];
+ int8_t padding0__; int32_t padding1__;
+ int64_t d_[2];
+
+ public:
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return NestedStructTypeTable();
+ }
+ NestedStruct() {
+ memset(static_cast<void *>(this), 0, sizeof(NestedStruct));
+ }
+ NestedStruct(MyGame::Example::TestEnum _b)
+ : b_(flatbuffers::EndianScalar(static_cast<int8_t>(_b))) {
+ std::memset(a_, 0, sizeof(a_));
+ std::memset(c_, 0, sizeof(c_));
+ (void)padding0__; (void)padding1__;
+ std::memset(d_, 0, sizeof(d_));
+ }
+ const flatbuffers::Array<int32_t, 2> *a() const {
+ return reinterpret_cast<const flatbuffers::Array<int32_t, 2> *>(a_);
+ }
+ flatbuffers::Array<int32_t, 2> *mutable_a() {
+ return reinterpret_cast<flatbuffers::Array<int32_t, 2> *>(a_);
+ }
+ MyGame::Example::TestEnum b() const {
+ return static_cast<MyGame::Example::TestEnum>(flatbuffers::EndianScalar(b_));
+ }
+ void mutate_b(MyGame::Example::TestEnum _b) {
+ flatbuffers::WriteScalar(&b_, static_cast<int8_t>(_b));
+ }
+ const flatbuffers::Array<MyGame::Example::TestEnum, 2> *c() const {
+ return reinterpret_cast<const flatbuffers::Array<MyGame::Example::TestEnum, 2> *>(c_);
+ }
+ flatbuffers::Array<MyGame::Example::TestEnum, 2> *mutable_c() {
+ return reinterpret_cast<flatbuffers::Array<MyGame::Example::TestEnum, 2> *>(c_);
+ }
+ const flatbuffers::Array<int64_t, 2> *d() const {
+ return reinterpret_cast<const flatbuffers::Array<int64_t, 2> *>(d_);
+ }
+ flatbuffers::Array<int64_t, 2> *mutable_d() {
+ return reinterpret_cast<flatbuffers::Array<int64_t, 2> *>(d_);
+ }
+};
+FLATBUFFERS_STRUCT_END(NestedStruct, 32);
+
+inline bool operator==(const NestedStruct &lhs, const NestedStruct &rhs) {
+ return
+ (lhs.a() == rhs.a()) &&
+ (lhs.b() == rhs.b()) &&
+ (lhs.c() == rhs.c()) &&
+ (lhs.d() == rhs.d());
+}
+
+inline bool operator!=(const NestedStruct &lhs, const NestedStruct &rhs) {
+ return !(lhs == rhs);
+}
+
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) ArrayStruct FLATBUFFERS_FINAL_CLASS {
+ private:
+ float a_;
+ int32_t b_[15];
+ int8_t c_;
+ int8_t padding0__; int16_t padding1__; int32_t padding2__;
+ MyGame::Example::NestedStruct d_[2];
+ int32_t e_;
+ int32_t padding3__;
+ int64_t f_[2];
+
+ public:
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return ArrayStructTypeTable();
+ }
+ ArrayStruct() {
+ memset(static_cast<void *>(this), 0, sizeof(ArrayStruct));
+ }
+ ArrayStruct(float _a, int8_t _c, int32_t _e)
+ : a_(flatbuffers::EndianScalar(_a)),
+ c_(flatbuffers::EndianScalar(_c)),
+ padding0__(0),
+ padding1__(0),
+ padding2__(0),
+ e_(flatbuffers::EndianScalar(_e)),
+ padding3__(0) {
+ std::memset(b_, 0, sizeof(b_));
+ (void)padding0__; (void)padding1__; (void)padding2__;
+ std::memset(d_, 0, sizeof(d_));
+ (void)padding3__;
+ std::memset(f_, 0, sizeof(f_));
+ }
+ float a() const {
+ return flatbuffers::EndianScalar(a_);
+ }
+ void mutate_a(float _a) {
+ flatbuffers::WriteScalar(&a_, _a);
+ }
+ const flatbuffers::Array<int32_t, 15> *b() const {
+ return reinterpret_cast<const flatbuffers::Array<int32_t, 15> *>(b_);
+ }
+ flatbuffers::Array<int32_t, 15> *mutable_b() {
+ return reinterpret_cast<flatbuffers::Array<int32_t, 15> *>(b_);
+ }
+ int8_t c() const {
+ return flatbuffers::EndianScalar(c_);
+ }
+ void mutate_c(int8_t _c) {
+ flatbuffers::WriteScalar(&c_, _c);
+ }
+ const flatbuffers::Array<MyGame::Example::NestedStruct, 2> *d() const {
+ return reinterpret_cast<const flatbuffers::Array<MyGame::Example::NestedStruct, 2> *>(d_);
+ }
+ flatbuffers::Array<MyGame::Example::NestedStruct, 2> *mutable_d() {
+ return reinterpret_cast<flatbuffers::Array<MyGame::Example::NestedStruct, 2> *>(d_);
+ }
+ int32_t e() const {
+ return flatbuffers::EndianScalar(e_);
+ }
+ void mutate_e(int32_t _e) {
+ flatbuffers::WriteScalar(&e_, _e);
+ }
+ const flatbuffers::Array<int64_t, 2> *f() const {
+ return reinterpret_cast<const flatbuffers::Array<int64_t, 2> *>(f_);
+ }
+ flatbuffers::Array<int64_t, 2> *mutable_f() {
+ return reinterpret_cast<flatbuffers::Array<int64_t, 2> *>(f_);
+ }
+};
+FLATBUFFERS_STRUCT_END(ArrayStruct, 160);
+
+inline bool operator==(const ArrayStruct &lhs, const ArrayStruct &rhs) {
+ return
+ (lhs.a() == rhs.a()) &&
+ (lhs.b() == rhs.b()) &&
+ (lhs.c() == rhs.c()) &&
+ (lhs.d() == rhs.d()) &&
+ (lhs.e() == rhs.e()) &&
+ (lhs.f() == rhs.f());
+}
+
+inline bool operator!=(const ArrayStruct &lhs, const ArrayStruct &rhs) {
+ return !(lhs == rhs);
+}
+
+
+struct ArrayTableT : public flatbuffers::NativeTable {
+ typedef ArrayTable TableType;
+ flatbuffers::unique_ptr<MyGame::Example::ArrayStruct> a;
+ ArrayTableT() {
+ }
+};
+
+inline bool operator==(const ArrayTableT &lhs, const ArrayTableT &rhs) {
+ return
+ (lhs.a == rhs.a);
+}
+
+inline bool operator!=(const ArrayTableT &lhs, const ArrayTableT &rhs) {
+ return !(lhs == rhs);
+}
+
+
+struct ArrayTable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef ArrayTableT NativeTableType;
+ typedef ArrayTableBuilder Builder;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return ArrayTableTypeTable();
+ }
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_A = 4
+ };
+ const MyGame::Example::ArrayStruct *a() const {
+ return GetStruct<const MyGame::Example::ArrayStruct *>(VT_A);
+ }
+ MyGame::Example::ArrayStruct *mutable_a() {
+ return GetStruct<MyGame::Example::ArrayStruct *>(VT_A);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<MyGame::Example::ArrayStruct>(verifier, VT_A) &&
+ verifier.EndTable();
+ }
+ ArrayTableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(ArrayTableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<ArrayTable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ArrayTableBuilder {
+ typedef ArrayTable Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_a(const MyGame::Example::ArrayStruct *a) {
+ fbb_.AddStruct(ArrayTable::VT_A, a);
+ }
+ explicit ArrayTableBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ ArrayTableBuilder &operator=(const ArrayTableBuilder &);
+ flatbuffers::Offset<ArrayTable> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<ArrayTable>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<ArrayTable> CreateArrayTable(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const MyGame::Example::ArrayStruct *a = 0) {
+ ArrayTableBuilder builder_(_fbb);
+ builder_.add_a(a);
+ return builder_.Finish();
+}
+
+flatbuffers::Offset<ArrayTable> CreateArrayTable(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline ArrayTableT *ArrayTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ flatbuffers::unique_ptr<MyGame::Example::ArrayTableT> _o = flatbuffers::unique_ptr<MyGame::Example::ArrayTableT>(new ArrayTableT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void ArrayTable::UnPackTo(ArrayTableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = a(); if (_e) _o->a = flatbuffers::unique_ptr<MyGame::Example::ArrayStruct>(new MyGame::Example::ArrayStruct(*_e)); }
+}
+
+inline flatbuffers::Offset<ArrayTable> ArrayTable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateArrayTable(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<ArrayTable> CreateArrayTable(flatbuffers::FlatBufferBuilder &_fbb, const ArrayTableT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ArrayTableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _a = _o->a ? _o->a.get() : 0;
+ return MyGame::Example::CreateArrayTable(
+ _fbb,
+ _a);
+}
+
+inline const flatbuffers::TypeTable *TestEnumTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_CHAR, 0, 0 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::TestEnumTypeTable
+ };
+ static const char * const names[] = {
+ "A",
+ "B",
+ "C"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *NestedStructTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_SEQUENCE, 0, -1 },
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_SEQUENCE, 0, 0 },
+ { flatbuffers::ET_SEQUENCE, 0, -1 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::TestEnumTypeTable
+ };
+ static const int64_t values[] = { 0, 8, 9, 16, 32 };
+ static const char * const names[] = {
+ "a",
+ "b",
+ "c",
+ "d"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_STRUCT, 4, type_codes, type_refs, values, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *ArrayStructTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_SEQUENCE, 0, -1 },
+ { flatbuffers::ET_CHAR, 0, -1 },
+ { flatbuffers::ET_SEQUENCE, 0, 0 },
+ { flatbuffers::ET_INT, 0, -1 },
+ { flatbuffers::ET_SEQUENCE, 0, -1 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::NestedStructTypeTable
+ };
+ static const int64_t values[] = { 0, 4, 64, 72, 136, 144, 160 };
+ static const char * const names[] = {
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_STRUCT, 6, type_codes, type_refs, values, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *ArrayTableTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_SEQUENCE, 0, 0 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::ArrayStructTypeTable
+ };
+ static const char * const names[] = {
+ "a"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+ };
+ return &tt;
+}
+
+inline const MyGame::Example::ArrayTable *GetArrayTable(const void *buf) {
+ return flatbuffers::GetRoot<MyGame::Example::ArrayTable>(buf);
+}
+
+inline const MyGame::Example::ArrayTable *GetSizePrefixedArrayTable(const void *buf) {
+ return flatbuffers::GetSizePrefixedRoot<MyGame::Example::ArrayTable>(buf);
+}
+
+inline ArrayTable *GetMutableArrayTable(void *buf) {
+ return flatbuffers::GetMutableRoot<ArrayTable>(buf);
+}
+
+inline const char *ArrayTableIdentifier() {
+ return "ARRT";
+}
+
+inline bool ArrayTableBufferHasIdentifier(const void *buf) {
+ return flatbuffers::BufferHasIdentifier(
+ buf, ArrayTableIdentifier());
+}
+
+inline bool VerifyArrayTableBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifyBuffer<MyGame::Example::ArrayTable>(ArrayTableIdentifier());
+}
+
+inline bool VerifySizePrefixedArrayTableBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifySizePrefixedBuffer<MyGame::Example::ArrayTable>(ArrayTableIdentifier());
+}
+
+inline const char *ArrayTableExtension() {
+ return "mon";
+}
+
+inline void FinishArrayTableBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<MyGame::Example::ArrayTable> root) {
+ fbb.Finish(root, ArrayTableIdentifier());
+}
+
+inline void FinishSizePrefixedArrayTableBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<MyGame::Example::ArrayTable> root) {
+ fbb.FinishSizePrefixed(root, ArrayTableIdentifier());
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::ArrayTableT> UnPackArrayTable(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<MyGame::Example::ArrayTableT>(GetArrayTable(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::ArrayTableT> UnPackSizePrefixedArrayTable(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<MyGame::Example::ArrayTableT>(GetSizePrefixedArrayTable(buf)->UnPack(res));
+}
+
+} // namespace Example
+} // namespace MyGame
+
+#endif // FLATBUFFERS_GENERATED_ARRAYSTEST_MYGAME_EXAMPLE_H_
diff --git a/tests/cpp17/generated_cpp17/monster_test_generated.h b/tests/cpp17/generated_cpp17/monster_test_generated.h
new file mode 100644
index 00000000..359fd1a9
--- /dev/null
+++ b/tests/cpp17/generated_cpp17/monster_test_generated.h
@@ -0,0 +1,3359 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
+#define FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flexbuffers.h"
+
+namespace MyGame {
+
+struct InParentNamespace;
+struct InParentNamespaceBuilder;
+struct InParentNamespaceT;
+
+namespace Example2 {
+
+struct Monster;
+struct MonsterBuilder;
+struct MonsterT;
+
+} // namespace Example2
+
+namespace Example {
+
+struct Test;
+
+struct TestSimpleTableWithEnum;
+struct TestSimpleTableWithEnumBuilder;
+struct TestSimpleTableWithEnumT;
+
+struct Vec3;
+
+struct Ability;
+
+struct Stat;
+struct StatBuilder;
+struct StatT;
+
+struct Referrable;
+struct ReferrableBuilder;
+struct ReferrableT;
+
+struct Monster;
+struct MonsterBuilder;
+struct MonsterT;
+
+struct TypeAliases;
+struct TypeAliasesBuilder;
+struct TypeAliasesT;
+
+} // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable();
+
+namespace Example2 {
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+} // namespace Example2
+
+namespace Example {
+
+inline const flatbuffers::TypeTable *TestTypeTable();
+
+inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable();
+
+inline const flatbuffers::TypeTable *Vec3TypeTable();
+
+inline const flatbuffers::TypeTable *AbilityTypeTable();
+
+inline const flatbuffers::TypeTable *StatTypeTable();
+
+inline const flatbuffers::TypeTable *ReferrableTypeTable();
+
+inline const flatbuffers::TypeTable *MonsterTypeTable();
+
+inline const flatbuffers::TypeTable *TypeAliasesTypeTable();
+
+/// Composite components of Monster color.
+enum class Color : uint8_t {
+ Red = 1,
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
+ Green = 2,
+ /// \brief color Blue (1u << 3)
+ Blue = 8,
+ NONE = 0,
+ ANY = 11
+};
+FLATBUFFERS_DEFINE_BITMASK_OPERATORS(Color, uint8_t)
+
+inline const Color (&EnumValuesColor())[3] {
+ static const Color values[] = {
+ Color::Red,
+ Color::Green,
+ Color::Blue
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesColor() {
+ static const char * const names[9] = {
+ "Red",
+ "Green",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Blue",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameColor(Color e) {
+ if (flatbuffers::IsOutRange(e, Color::Red, Color::Blue)) return "";
+ const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Color::Red);
+ return EnumNamesColor()[index];
+}
+
+enum class Race : int8_t {
+ None = -1,
+ Human = 0,
+ Dwarf = 1,
+ Elf = 2,
+ MIN = None,
+ MAX = Elf
+};
+
+inline const Race (&EnumValuesRace())[4] {
+ static const Race values[] = {
+ Race::None,
+ Race::Human,
+ Race::Dwarf,
+ Race::Elf
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesRace() {
+ static const char * const names[5] = {
+ "None",
+ "Human",
+ "Dwarf",
+ "Elf",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameRace(Race e) {
+ if (flatbuffers::IsOutRange(e, Race::None, Race::Elf)) return "";
+ const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Race::None);
+ return EnumNamesRace()[index];
+}
+
+enum class Any : uint8_t {
+ NONE = 0,
+ Monster = 1,
+ TestSimpleTableWithEnum = 2,
+ MyGame_Example2_Monster = 3,
+ MIN = NONE,
+ MAX = MyGame_Example2_Monster
+};
+
+inline const Any (&EnumValuesAny())[4] {
+ static const Any values[] = {
+ Any::NONE,
+ Any::Monster,
+ Any::TestSimpleTableWithEnum,
+ Any::MyGame_Example2_Monster
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesAny() {
+ static const char * const names[5] = {
+ "NONE",
+ "Monster",
+ "TestSimpleTableWithEnum",
+ "MyGame_Example2_Monster",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameAny(Any e) {
+ if (flatbuffers::IsOutRange(e, Any::NONE, Any::MyGame_Example2_Monster)) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesAny()[index];
+}
+
+template<typename T> struct AnyTraits {
+ static const Any enum_value = Any::NONE;
+};
+
+template<> struct AnyTraits<MyGame::Example::Monster> {
+ static const Any enum_value = Any::Monster;
+};
+
+template<> struct AnyTraits<MyGame::Example::TestSimpleTableWithEnum> {
+ static const Any enum_value = Any::TestSimpleTableWithEnum;
+};
+
+template<> struct AnyTraits<MyGame::Example2::Monster> {
+ static const Any enum_value = Any::MyGame_Example2_Monster;
+};
+
+struct AnyUnion {
+ Any type;
+ void *value;
+
+ AnyUnion() : type(Any::NONE), value(nullptr) {}
+ AnyUnion(AnyUnion&& u) FLATBUFFERS_NOEXCEPT :
+ type(Any::NONE), value(nullptr)
+ { std::swap(type, u.type); std::swap(value, u.value); }
+ AnyUnion(const AnyUnion &);
+ AnyUnion &operator=(const AnyUnion &u)
+ { AnyUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+ AnyUnion &operator=(AnyUnion &&u) FLATBUFFERS_NOEXCEPT
+ { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+ ~AnyUnion() { Reset(); }
+
+ void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+ template <typename T>
+ void Set(T&& val) {
+ using RT = typename std::remove_reference<T>::type;
+ Reset();
+ type = AnyTraits<typename RT::TableType>::enum_value;
+ if (type != Any::NONE) {
+ value = new RT(std::forward<T>(val));
+ }
+ }
+#endif // FLATBUFFERS_CPP98_STL
+
+ static void *UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver);
+ flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+ MyGame::Example::MonsterT *AsMonster() {
+ return type == Any::Monster ?
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ const MyGame::Example::MonsterT *AsMonster() const {
+ return type == Any::Monster ?
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() {
+ return type == Any::TestSimpleTableWithEnum ?
+ reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+ }
+ const MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() const {
+ return type == Any::TestSimpleTableWithEnum ?
+ reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+ }
+ MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() {
+ return type == Any::MyGame_Example2_Monster ?
+ reinterpret_cast<MyGame::Example2::MonsterT *>(value) : nullptr;
+ }
+ const MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() const {
+ return type == Any::MyGame_Example2_Monster ?
+ reinterpret_cast<const MyGame::Example2::MonsterT *>(value) : nullptr;
+ }
+};
+
+bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type);
+bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+enum class AnyUniqueAliases : uint8_t {
+ NONE = 0,
+ M = 1,
+ TS = 2,
+ M2 = 3,
+ MIN = NONE,
+ MAX = M2
+};
+
+inline const AnyUniqueAliases (&EnumValuesAnyUniqueAliases())[4] {
+ static const AnyUniqueAliases values[] = {
+ AnyUniqueAliases::NONE,
+ AnyUniqueAliases::M,
+ AnyUniqueAliases::TS,
+ AnyUniqueAliases::M2
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesAnyUniqueAliases() {
+ static const char * const names[5] = {
+ "NONE",
+ "M",
+ "TS",
+ "M2",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameAnyUniqueAliases(AnyUniqueAliases e) {
+ if (flatbuffers::IsOutRange(e, AnyUniqueAliases::NONE, AnyUniqueAliases::M2)) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesAnyUniqueAliases()[index];
+}
+
+template<typename T> struct AnyUniqueAliasesTraits {
+ static const AnyUniqueAliases enum_value = AnyUniqueAliases::NONE;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::Monster> {
+ static const AnyUniqueAliases enum_value = AnyUniqueAliases::M;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::TestSimpleTableWithEnum> {
+ static const AnyUniqueAliases enum_value = AnyUniqueAliases::TS;
+};
+
+template<> struct AnyUniqueAliasesTraits<MyGame::Example2::Monster> {
+ static const AnyUniqueAliases enum_value = AnyUniqueAliases::M2;
+};
+
+struct AnyUniqueAliasesUnion {
+ AnyUniqueAliases type;
+ void *value;
+
+ AnyUniqueAliasesUnion() : type(AnyUniqueAliases::NONE), value(nullptr) {}
+ AnyUniqueAliasesUnion(AnyUniqueAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
+ type(AnyUniqueAliases::NONE), value(nullptr)
+ { std::swap(type, u.type); std::swap(value, u.value); }
+ AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &);
+ AnyUniqueAliasesUnion &operator=(const AnyUniqueAliasesUnion &u)
+ { AnyUniqueAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+ AnyUniqueAliasesUnion &operator=(AnyUniqueAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
+ { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+ ~AnyUniqueAliasesUnion() { Reset(); }
+
+ void Reset();
+
+#ifndef FLATBUFFERS_CPP98_STL
+ template <typename T>
+ void Set(T&& val) {
+ using RT = typename std::remove_reference<T>::type;
+ Reset();
+ type = AnyUniqueAliasesTraits<typename RT::TableType>::enum_value;
+ if (type != AnyUniqueAliases::NONE) {
+ value = new RT(std::forward<T>(val));
+ }
+ }
+#endif // FLATBUFFERS_CPP98_STL
+
+ static void *UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver);
+ flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+ MyGame::Example::MonsterT *AsM() {
+ return type == AnyUniqueAliases::M ?
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ const MyGame::Example::MonsterT *AsM() const {
+ return type == AnyUniqueAliases::M ?
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ MyGame::Example::TestSimpleTableWithEnumT *AsTS() {
+ return type == AnyUniqueAliases::TS ?
+ reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+ }
+ const MyGame::Example::TestSimpleTableWithEnumT *AsTS() const {
+ return type == AnyUniqueAliases::TS ?
+ reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
+ }
+ MyGame::Example2::MonsterT *AsM2() {
+ return type == AnyUniqueAliases::M2 ?
+ reinterpret_cast<MyGame::Example2::MonsterT *>(value) : nullptr;
+ }
+ const MyGame::Example2::MonsterT *AsM2() const {
+ return type == AnyUniqueAliases::M2 ?
+ reinterpret_cast<const MyGame::Example2::MonsterT *>(value) : nullptr;
+ }
+};
+
+bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *obj, AnyUniqueAliases type);
+bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+enum class AnyAmbiguousAliases : uint8_t {
+ NONE = 0,
+ M1 = 1,
+ M2 = 2,
+ M3 = 3,
+ MIN = NONE,
+ MAX = M3
+};
+
+inline const AnyAmbiguousAliases (&EnumValuesAnyAmbiguousAliases())[4] {
+ static const AnyAmbiguousAliases values[] = {
+ AnyAmbiguousAliases::NONE,
+ AnyAmbiguousAliases::M1,
+ AnyAmbiguousAliases::M2,
+ AnyAmbiguousAliases::M3
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesAnyAmbiguousAliases() {
+ static const char * const names[5] = {
+ "NONE",
+ "M1",
+ "M2",
+ "M3",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameAnyAmbiguousAliases(AnyAmbiguousAliases e) {
+ if (flatbuffers::IsOutRange(e, AnyAmbiguousAliases::NONE, AnyAmbiguousAliases::M3)) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesAnyAmbiguousAliases()[index];
+}
+
+struct AnyAmbiguousAliasesUnion {
+ AnyAmbiguousAliases type;
+ void *value;
+
+ AnyAmbiguousAliasesUnion() : type(AnyAmbiguousAliases::NONE), value(nullptr) {}
+ AnyAmbiguousAliasesUnion(AnyAmbiguousAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
+ type(AnyAmbiguousAliases::NONE), value(nullptr)
+ { std::swap(type, u.type); std::swap(value, u.value); }
+ AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &);
+ AnyAmbiguousAliasesUnion &operator=(const AnyAmbiguousAliasesUnion &u)
+ { AnyAmbiguousAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
+ AnyAmbiguousAliasesUnion &operator=(AnyAmbiguousAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
+ { std::swap(type, u.type); std::swap(value, u.value); return *this; }
+ ~AnyAmbiguousAliasesUnion() { Reset(); }
+
+ void Reset();
+
+ static void *UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver);
+ flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
+
+ MyGame::Example::MonsterT *AsM1() {
+ return type == AnyAmbiguousAliases::M1 ?
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ const MyGame::Example::MonsterT *AsM1() const {
+ return type == AnyAmbiguousAliases::M1 ?
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ MyGame::Example::MonsterT *AsM2() {
+ return type == AnyAmbiguousAliases::M2 ?
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ const MyGame::Example::MonsterT *AsM2() const {
+ return type == AnyAmbiguousAliases::M2 ?
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ MyGame::Example::MonsterT *AsM3() {
+ return type == AnyAmbiguousAliases::M3 ?
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+ const MyGame::Example::MonsterT *AsM3() const {
+ return type == AnyAmbiguousAliases::M3 ?
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
+ }
+};
+
+bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const void *obj, AnyAmbiguousAliases type);
+bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(2) Test FLATBUFFERS_FINAL_CLASS {
+ private:
+ int16_t a_;
+ int8_t b_;
+ int8_t padding0__;
+
+ public:
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return TestTypeTable();
+ }
+ Test() {
+ memset(static_cast<void *>(this), 0, sizeof(Test));
+ }
+ Test(int16_t _a, int8_t _b)
+ : a_(flatbuffers::EndianScalar(_a)),
+ b_(flatbuffers::EndianScalar(_b)),
+ padding0__(0) {
+ (void)padding0__;
+ }
+ int16_t a() const {
+ return flatbuffers::EndianScalar(a_);
+ }
+ void mutate_a(int16_t _a) {
+ flatbuffers::WriteScalar(&a_, _a);
+ }
+ int8_t b() const {
+ return flatbuffers::EndianScalar(b_);
+ }
+ void mutate_b(int8_t _b) {
+ flatbuffers::WriteScalar(&b_, _b);
+ }
+};
+FLATBUFFERS_STRUCT_END(Test, 4);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
+ private:
+ float x_;
+ float y_;
+ float z_;
+ int32_t padding0__;
+ double test1_;
+ uint8_t test2_;
+ int8_t padding1__;
+ MyGame::Example::Test test3_;
+ int16_t padding2__;
+
+ public:
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return Vec3TypeTable();
+ }
+ Vec3() {
+ memset(static_cast<void *>(this), 0, sizeof(Vec3));
+ }
+ Vec3(float _x, float _y, float _z, double _test1, MyGame::Example::Color _test2, const MyGame::Example::Test &_test3)
+ : x_(flatbuffers::EndianScalar(_x)),
+ y_(flatbuffers::EndianScalar(_y)),
+ z_(flatbuffers::EndianScalar(_z)),
+ padding0__(0),
+ test1_(flatbuffers::EndianScalar(_test1)),
+ test2_(flatbuffers::EndianScalar(static_cast<uint8_t>(_test2))),
+ padding1__(0),
+ test3_(_test3),
+ padding2__(0) {
+ (void)padding0__;
+ (void)padding1__;
+ (void)padding2__;
+ }
+ float x() const {
+ return flatbuffers::EndianScalar(x_);
+ }
+ void mutate_x(float _x) {
+ flatbuffers::WriteScalar(&x_, _x);
+ }
+ float y() const {
+ return flatbuffers::EndianScalar(y_);
+ }
+ void mutate_y(float _y) {
+ flatbuffers::WriteScalar(&y_, _y);
+ }
+ float z() const {
+ return flatbuffers::EndianScalar(z_);
+ }
+ void mutate_z(float _z) {
+ flatbuffers::WriteScalar(&z_, _z);
+ }
+ double test1() const {
+ return flatbuffers::EndianScalar(test1_);
+ }
+ void mutate_test1(double _test1) {
+ flatbuffers::WriteScalar(&test1_, _test1);
+ }
+ MyGame::Example::Color test2() const {
+ return static_cast<MyGame::Example::Color>(flatbuffers::EndianScalar(test2_));
+ }
+ void mutate_test2(MyGame::Example::Color _test2) {
+ flatbuffers::WriteScalar(&test2_, static_cast<uint8_t>(_test2));
+ }
+ const MyGame::Example::Test &test3() const {
+ return test3_;
+ }
+ MyGame::Example::Test &mutable_test3() {
+ return test3_;
+ }
+};
+FLATBUFFERS_STRUCT_END(Vec3, 32);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Ability FLATBUFFERS_FINAL_CLASS {
+ private:
+ uint32_t id_;
+ uint32_t distance_;
+
+ public:
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return AbilityTypeTable();
+ }
+ Ability() {
+ memset(static_cast<void *>(this), 0, sizeof(Ability));
+ }
+ Ability(uint32_t _id, uint32_t _distance)
+ : id_(flatbuffers::EndianScalar(_id)),
+ distance_(flatbuffers::EndianScalar(_distance)) {
+ }
+ uint32_t id() const {
+ return flatbuffers::EndianScalar(id_);
+ }
+ void mutate_id(uint32_t _id) {
+ flatbuffers::WriteScalar(&id_, _id);
+ }
+ bool KeyCompareLessThan(const Ability *o) const {
+ return id() < o->id();
+ }
+ int KeyCompareWithValue(uint32_t val) const {
+ return static_cast<int>(id() > val) - static_cast<int>(id() < val);
+ }
+ uint32_t distance() const {
+ return flatbuffers::EndianScalar(distance_);
+ }
+ void mutate_distance(uint32_t _distance) {
+ flatbuffers::WriteScalar(&distance_, _distance);
+ }
+};
+FLATBUFFERS_STRUCT_END(Ability, 8);
+
+} // namespace Example
+
+struct InParentNamespaceT : public flatbuffers::NativeTable {
+ typedef InParentNamespace TableType;
+ InParentNamespaceT() {
+ }
+};
+
+struct InParentNamespace FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef InParentNamespaceT NativeTableType;
+ typedef InParentNamespaceBuilder Builder;
+ struct Traits;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return InParentNamespaceTypeTable();
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ verifier.EndTable();
+ }
+ InParentNamespaceT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<InParentNamespace> Pack(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct InParentNamespaceBuilder {
+ typedef InParentNamespace Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ explicit InParentNamespaceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ InParentNamespaceBuilder &operator=(const InParentNamespaceBuilder &);
+ flatbuffers::Offset<InParentNamespace> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<InParentNamespace>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(
+ flatbuffers::FlatBufferBuilder &_fbb) {
+ InParentNamespaceBuilder builder_(_fbb);
+ return builder_.Finish();
+}
+
+struct InParentNamespace::Traits {
+ using type = InParentNamespace;
+ static auto constexpr Create = CreateInParentNamespace;
+};
+
+flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+namespace Example2 {
+
+struct MonsterT : public flatbuffers::NativeTable {
+ typedef Monster TableType;
+ MonsterT() {
+ }
+};
+
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef MonsterT NativeTableType;
+ typedef MonsterBuilder Builder;
+ struct Traits;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return MonsterTypeTable();
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ verifier.EndTable();
+ }
+ MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct MonsterBuilder {
+ typedef Monster Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ MonsterBuilder &operator=(const MonsterBuilder &);
+ flatbuffers::Offset<Monster> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Monster>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+ flatbuffers::FlatBufferBuilder &_fbb) {
+ MonsterBuilder builder_(_fbb);
+ return builder_.Finish();
+}
+
+struct Monster::Traits {
+ using type = Monster;
+ static auto constexpr Create = CreateMonster;
+};
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+} // namespace Example2
+
+namespace Example {
+
+struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable {
+ typedef TestSimpleTableWithEnum TableType;
+ MyGame::Example::Color color;
+ TestSimpleTableWithEnumT()
+ : color(MyGame::Example::Color::Green) {
+ }
+};
+
+struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef TestSimpleTableWithEnumT NativeTableType;
+ typedef TestSimpleTableWithEnumBuilder Builder;
+ struct Traits;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return TestSimpleTableWithEnumTypeTable();
+ }
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_COLOR = 4
+ };
+ MyGame::Example::Color color() const {
+ return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 2));
+ }
+ bool mutate_color(MyGame::Example::Color _color) {
+ return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 2);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<uint8_t>(verifier, VT_COLOR) &&
+ verifier.EndTable();
+ }
+ TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<TestSimpleTableWithEnum> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct TestSimpleTableWithEnumBuilder {
+ typedef TestSimpleTableWithEnum Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_color(MyGame::Example::Color color) {
+ fbb_.AddElement<uint8_t>(TestSimpleTableWithEnum::VT_COLOR, static_cast<uint8_t>(color), 2);
+ }
+ explicit TestSimpleTableWithEnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ TestSimpleTableWithEnumBuilder &operator=(const TestSimpleTableWithEnumBuilder &);
+ flatbuffers::Offset<TestSimpleTableWithEnum> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<TestSimpleTableWithEnum>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ MyGame::Example::Color color = MyGame::Example::Color::Green) {
+ TestSimpleTableWithEnumBuilder builder_(_fbb);
+ builder_.add_color(color);
+ return builder_.Finish();
+}
+
+struct TestSimpleTableWithEnum::Traits {
+ using type = TestSimpleTableWithEnum;
+ static auto constexpr Create = CreateTestSimpleTableWithEnum;
+};
+
+flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct StatT : public flatbuffers::NativeTable {
+ typedef Stat TableType;
+ std::string id;
+ int64_t val;
+ uint16_t count;
+ StatT()
+ : val(0),
+ count(0) {
+ }
+};
+
+struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef StatT NativeTableType;
+ typedef StatBuilder Builder;
+ struct Traits;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return StatTypeTable();
+ }
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_ID = 4,
+ VT_VAL = 6,
+ VT_COUNT = 8
+ };
+ const flatbuffers::String *id() const {
+ return GetPointer<const flatbuffers::String *>(VT_ID);
+ }
+ flatbuffers::String *mutable_id() {
+ return GetPointer<flatbuffers::String *>(VT_ID);
+ }
+ int64_t val() const {
+ return GetField<int64_t>(VT_VAL, 0);
+ }
+ bool mutate_val(int64_t _val) {
+ return SetField<int64_t>(VT_VAL, _val, 0);
+ }
+ uint16_t count() const {
+ return GetField<uint16_t>(VT_COUNT, 0);
+ }
+ bool mutate_count(uint16_t _count) {
+ return SetField<uint16_t>(VT_COUNT, _count, 0);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffset(verifier, VT_ID) &&
+ verifier.VerifyString(id()) &&
+ VerifyField<int64_t>(verifier, VT_VAL) &&
+ VerifyField<uint16_t>(verifier, VT_COUNT) &&
+ verifier.EndTable();
+ }
+ StatT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<Stat> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct StatBuilder {
+ typedef Stat Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_id(flatbuffers::Offset<flatbuffers::String> id) {
+ fbb_.AddOffset(Stat::VT_ID, id);
+ }
+ void add_val(int64_t val) {
+ fbb_.AddElement<int64_t>(Stat::VT_VAL, val, 0);
+ }
+ void add_count(uint16_t count) {
+ fbb_.AddElement<uint16_t>(Stat::VT_COUNT, count, 0);
+ }
+ explicit StatBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ StatBuilder &operator=(const StatBuilder &);
+ flatbuffers::Offset<Stat> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Stat>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Stat> CreateStat(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::String> id = 0,
+ int64_t val = 0,
+ uint16_t count = 0) {
+ StatBuilder builder_(_fbb);
+ builder_.add_val(val);
+ builder_.add_id(id);
+ builder_.add_count(count);
+ return builder_.Finish();
+}
+
+struct Stat::Traits {
+ using type = Stat;
+ static auto constexpr Create = CreateStat;
+};
+
+inline flatbuffers::Offset<Stat> CreateStatDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const char *id = nullptr,
+ int64_t val = 0,
+ uint16_t count = 0) {
+ auto id__ = id ? _fbb.CreateString(id) : 0;
+ return MyGame::Example::CreateStat(
+ _fbb,
+ id__,
+ val,
+ count);
+}
+
+flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct ReferrableT : public flatbuffers::NativeTable {
+ typedef Referrable TableType;
+ uint64_t id;
+ ReferrableT()
+ : id(0) {
+ }
+};
+
+struct Referrable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef ReferrableT NativeTableType;
+ typedef ReferrableBuilder Builder;
+ struct Traits;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return ReferrableTypeTable();
+ }
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_ID = 4
+ };
+ uint64_t id() const {
+ return GetField<uint64_t>(VT_ID, 0);
+ }
+ bool mutate_id(uint64_t _id) {
+ return SetField<uint64_t>(VT_ID, _id, 0);
+ }
+ bool KeyCompareLessThan(const Referrable *o) const {
+ return id() < o->id();
+ }
+ int KeyCompareWithValue(uint64_t val) const {
+ return static_cast<int>(id() > val) - static_cast<int>(id() < val);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<uint64_t>(verifier, VT_ID) &&
+ verifier.EndTable();
+ }
+ ReferrableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<Referrable> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ReferrableBuilder {
+ typedef Referrable Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_id(uint64_t id) {
+ fbb_.AddElement<uint64_t>(Referrable::VT_ID, id, 0);
+ }
+ explicit ReferrableBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ ReferrableBuilder &operator=(const ReferrableBuilder &);
+ flatbuffers::Offset<Referrable> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Referrable>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Referrable> CreateReferrable(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ uint64_t id = 0) {
+ ReferrableBuilder builder_(_fbb);
+ builder_.add_id(id);
+ return builder_.Finish();
+}
+
+struct Referrable::Traits {
+ using type = Referrable;
+ static auto constexpr Create = CreateReferrable;
+};
+
+flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct MonsterT : public flatbuffers::NativeTable {
+ typedef Monster TableType;
+ std::unique_ptr<MyGame::Example::Vec3> pos;
+ int16_t mana;
+ int16_t hp;
+ std::string name;
+ std::vector<uint8_t> inventory;
+ MyGame::Example::Color color;
+ MyGame::Example::AnyUnion test;
+ std::vector<MyGame::Example::Test> test4;
+ std::vector<std::string> testarrayofstring;
+ std::vector<std::unique_ptr<MyGame::Example::MonsterT>> testarrayoftables;
+ std::unique_ptr<MyGame::Example::MonsterT> enemy;
+ std::vector<uint8_t> testnestedflatbuffer;
+ std::unique_ptr<MyGame::Example::StatT> testempty;
+ bool testbool;
+ int32_t testhashs32_fnv1;
+ uint32_t testhashu32_fnv1;
+ int64_t testhashs64_fnv1;
+ uint64_t testhashu64_fnv1;
+ int32_t testhashs32_fnv1a;
+ Stat *testhashu32_fnv1a;
+ int64_t testhashs64_fnv1a;
+ uint64_t testhashu64_fnv1a;
+ std::vector<bool> testarrayofbools;
+ float testf;
+ float testf2;
+ float testf3;
+ std::vector<std::string> testarrayofstring2;
+ std::vector<MyGame::Example::Ability> testarrayofsortedstruct;
+ std::vector<uint8_t> flex;
+ std::vector<MyGame::Example::Test> test5;
+ std::vector<int64_t> vector_of_longs;
+ std::vector<double> vector_of_doubles;
+ std::unique_ptr<MyGame::InParentNamespaceT> parent_namespace_test;
+ std::vector<std::unique_ptr<MyGame::Example::ReferrableT>> vector_of_referrables;
+ ReferrableT *single_weak_reference;
+ std::vector<ReferrableT *> vector_of_weak_references;
+ std::vector<std::unique_ptr<MyGame::Example::ReferrableT>> vector_of_strong_referrables;
+ ReferrableT *co_owning_reference;
+ std::vector<std::unique_ptr<ReferrableT>> vector_of_co_owning_references;
+ ReferrableT *non_owning_reference;
+ std::vector<ReferrableT *> vector_of_non_owning_references;
+ MyGame::Example::AnyUniqueAliasesUnion any_unique;
+ MyGame::Example::AnyAmbiguousAliasesUnion any_ambiguous;
+ std::vector<MyGame::Example::Color> vector_of_enums;
+ MyGame::Example::Race signed_enum;
+ MonsterT()
+ : mana(150),
+ hp(100),
+ color(MyGame::Example::Color::Blue),
+ testbool(false),
+ testhashs32_fnv1(0),
+ testhashu32_fnv1(0),
+ testhashs64_fnv1(0),
+ testhashu64_fnv1(0),
+ testhashs32_fnv1a(0),
+ testhashu32_fnv1a(nullptr),
+ testhashs64_fnv1a(0),
+ testhashu64_fnv1a(0),
+ testf(3.14159f),
+ testf2(3.0f),
+ testf3(0.0f),
+ single_weak_reference(nullptr),
+ co_owning_reference(nullptr),
+ non_owning_reference(nullptr),
+ signed_enum(MyGame::Example::Race::None) {
+ }
+};
+
+/// an example documentation comment: "monster object"
+struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef MonsterT NativeTableType;
+ typedef MonsterBuilder Builder;
+ struct Traits;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return MonsterTypeTable();
+ }
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_POS = 4,
+ VT_MANA = 6,
+ VT_HP = 8,
+ VT_NAME = 10,
+ VT_INVENTORY = 14,
+ VT_COLOR = 16,
+ VT_TEST_TYPE = 18,
+ VT_TEST = 20,
+ VT_TEST4 = 22,
+ VT_TESTARRAYOFSTRING = 24,
+ VT_TESTARRAYOFTABLES = 26,
+ VT_ENEMY = 28,
+ VT_TESTNESTEDFLATBUFFER = 30,
+ VT_TESTEMPTY = 32,
+ VT_TESTBOOL = 34,
+ VT_TESTHASHS32_FNV1 = 36,
+ VT_TESTHASHU32_FNV1 = 38,
+ VT_TESTHASHS64_FNV1 = 40,
+ VT_TESTHASHU64_FNV1 = 42,
+ VT_TESTHASHS32_FNV1A = 44,
+ VT_TESTHASHU32_FNV1A = 46,
+ VT_TESTHASHS64_FNV1A = 48,
+ VT_TESTHASHU64_FNV1A = 50,
+ VT_TESTARRAYOFBOOLS = 52,
+ VT_TESTF = 54,
+ VT_TESTF2 = 56,
+ VT_TESTF3 = 58,
+ VT_TESTARRAYOFSTRING2 = 60,
+ VT_TESTARRAYOFSORTEDSTRUCT = 62,
+ VT_FLEX = 64,
+ VT_TEST5 = 66,
+ VT_VECTOR_OF_LONGS = 68,
+ VT_VECTOR_OF_DOUBLES = 70,
+ VT_PARENT_NAMESPACE_TEST = 72,
+ VT_VECTOR_OF_REFERRABLES = 74,
+ VT_SINGLE_WEAK_REFERENCE = 76,
+ VT_VECTOR_OF_WEAK_REFERENCES = 78,
+ VT_VECTOR_OF_STRONG_REFERRABLES = 80,
+ VT_CO_OWNING_REFERENCE = 82,
+ VT_VECTOR_OF_CO_OWNING_REFERENCES = 84,
+ VT_NON_OWNING_REFERENCE = 86,
+ VT_VECTOR_OF_NON_OWNING_REFERENCES = 88,
+ VT_ANY_UNIQUE_TYPE = 90,
+ VT_ANY_UNIQUE = 92,
+ VT_ANY_AMBIGUOUS_TYPE = 94,
+ VT_ANY_AMBIGUOUS = 96,
+ VT_VECTOR_OF_ENUMS = 98,
+ VT_SIGNED_ENUM = 100
+ };
+ const MyGame::Example::Vec3 *pos() const {
+ return GetStruct<const MyGame::Example::Vec3 *>(VT_POS);
+ }
+ MyGame::Example::Vec3 *mutable_pos() {
+ return GetStruct<MyGame::Example::Vec3 *>(VT_POS);
+ }
+ int16_t mana() const {
+ return GetField<int16_t>(VT_MANA, 150);
+ }
+ bool mutate_mana(int16_t _mana) {
+ return SetField<int16_t>(VT_MANA, _mana, 150);
+ }
+ int16_t hp() const {
+ return GetField<int16_t>(VT_HP, 100);
+ }
+ bool mutate_hp(int16_t _hp) {
+ return SetField<int16_t>(VT_HP, _hp, 100);
+ }
+ const flatbuffers::String *name() const {
+ return GetPointer<const flatbuffers::String *>(VT_NAME);
+ }
+ flatbuffers::String *mutable_name() {
+ return GetPointer<flatbuffers::String *>(VT_NAME);
+ }
+ bool KeyCompareLessThan(const Monster *o) const {
+ return *name() < *o->name();
+ }
+ int KeyCompareWithValue(const char *val) const {
+ return strcmp(name()->c_str(), val);
+ }
+ const flatbuffers::Vector<uint8_t> *inventory() const {
+ return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+ }
+ flatbuffers::Vector<uint8_t> *mutable_inventory() {
+ return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
+ }
+ MyGame::Example::Color color() const {
+ return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 8));
+ }
+ bool mutate_color(MyGame::Example::Color _color) {
+ return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 8);
+ }
+ MyGame::Example::Any test_type() const {
+ return static_cast<MyGame::Example::Any>(GetField<uint8_t>(VT_TEST_TYPE, 0));
+ }
+ const void *test() const {
+ return GetPointer<const void *>(VT_TEST);
+ }
+ template<typename T> const T *test_as() const;
+ const MyGame::Example::Monster *test_as_Monster() const {
+ return test_type() == MyGame::Example::Any::Monster ? static_cast<const MyGame::Example::Monster *>(test()) : nullptr;
+ }
+ const MyGame::Example::TestSimpleTableWithEnum *test_as_TestSimpleTableWithEnum() const {
+ return test_type() == MyGame::Example::Any::TestSimpleTableWithEnum ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(test()) : nullptr;
+ }
+ const MyGame::Example2::Monster *test_as_MyGame_Example2_Monster() const {
+ return test_type() == MyGame::Example::Any::MyGame_Example2_Monster ? static_cast<const MyGame::Example2::Monster *>(test()) : nullptr;
+ }
+ void *mutable_test() {
+ return GetPointer<void *>(VT_TEST);
+ }
+ const flatbuffers::Vector<const MyGame::Example::Test *> *test4() const {
+ return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
+ }
+ flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test4() {
+ return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
+ }
+ flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
+ }
+ /// an example documentation comment: this will end up in the generated code
+ /// multiline too
+ const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
+ }
+ flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *mutable_testarrayoftables() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
+ }
+ const MyGame::Example::Monster *enemy() const {
+ return GetPointer<const MyGame::Example::Monster *>(VT_ENEMY);
+ }
+ MyGame::Example::Monster *mutable_enemy() {
+ return GetPointer<MyGame::Example::Monster *>(VT_ENEMY);
+ }
+ const flatbuffers::Vector<uint8_t> *testnestedflatbuffer() const {
+ return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
+ }
+ flatbuffers::Vector<uint8_t> *mutable_testnestedflatbuffer() {
+ return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
+ }
+ const MyGame::Example::Monster *testnestedflatbuffer_nested_root() const {
+ return flatbuffers::GetRoot<MyGame::Example::Monster>(testnestedflatbuffer()->Data());
+ }
+ const MyGame::Example::Stat *testempty() const {
+ return GetPointer<const MyGame::Example::Stat *>(VT_TESTEMPTY);
+ }
+ MyGame::Example::Stat *mutable_testempty() {
+ return GetPointer<MyGame::Example::Stat *>(VT_TESTEMPTY);
+ }
+ bool testbool() const {
+ return GetField<uint8_t>(VT_TESTBOOL, 0) != 0;
+ }
+ bool mutate_testbool(bool _testbool) {
+ return SetField<uint8_t>(VT_TESTBOOL, static_cast<uint8_t>(_testbool), 0);
+ }
+ int32_t testhashs32_fnv1() const {
+ return GetField<int32_t>(VT_TESTHASHS32_FNV1, 0);
+ }
+ bool mutate_testhashs32_fnv1(int32_t _testhashs32_fnv1) {
+ return SetField<int32_t>(VT_TESTHASHS32_FNV1, _testhashs32_fnv1, 0);
+ }
+ uint32_t testhashu32_fnv1() const {
+ return GetField<uint32_t>(VT_TESTHASHU32_FNV1, 0);
+ }
+ bool mutate_testhashu32_fnv1(uint32_t _testhashu32_fnv1) {
+ return SetField<uint32_t>(VT_TESTHASHU32_FNV1, _testhashu32_fnv1, 0);
+ }
+ int64_t testhashs64_fnv1() const {
+ return GetField<int64_t>(VT_TESTHASHS64_FNV1, 0);
+ }
+ bool mutate_testhashs64_fnv1(int64_t _testhashs64_fnv1) {
+ return SetField<int64_t>(VT_TESTHASHS64_FNV1, _testhashs64_fnv1, 0);
+ }
+ uint64_t testhashu64_fnv1() const {
+ return GetField<uint64_t>(VT_TESTHASHU64_FNV1, 0);
+ }
+ bool mutate_testhashu64_fnv1(uint64_t _testhashu64_fnv1) {
+ return SetField<uint64_t>(VT_TESTHASHU64_FNV1, _testhashu64_fnv1, 0);
+ }
+ int32_t testhashs32_fnv1a() const {
+ return GetField<int32_t>(VT_TESTHASHS32_FNV1A, 0);
+ }
+ bool mutate_testhashs32_fnv1a(int32_t _testhashs32_fnv1a) {
+ return SetField<int32_t>(VT_TESTHASHS32_FNV1A, _testhashs32_fnv1a, 0);
+ }
+ uint32_t testhashu32_fnv1a() const {
+ return GetField<uint32_t>(VT_TESTHASHU32_FNV1A, 0);
+ }
+ bool mutate_testhashu32_fnv1a(uint32_t _testhashu32_fnv1a) {
+ return SetField<uint32_t>(VT_TESTHASHU32_FNV1A, _testhashu32_fnv1a, 0);
+ }
+ int64_t testhashs64_fnv1a() const {
+ return GetField<int64_t>(VT_TESTHASHS64_FNV1A, 0);
+ }
+ bool mutate_testhashs64_fnv1a(int64_t _testhashs64_fnv1a) {
+ return SetField<int64_t>(VT_TESTHASHS64_FNV1A, _testhashs64_fnv1a, 0);
+ }
+ uint64_t testhashu64_fnv1a() const {
+ return GetField<uint64_t>(VT_TESTHASHU64_FNV1A, 0);
+ }
+ bool mutate_testhashu64_fnv1a(uint64_t _testhashu64_fnv1a) {
+ return SetField<uint64_t>(VT_TESTHASHU64_FNV1A, _testhashu64_fnv1a, 0);
+ }
+ const flatbuffers::Vector<uint8_t> *testarrayofbools() const {
+ return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTARRAYOFBOOLS);
+ }
+ flatbuffers::Vector<uint8_t> *mutable_testarrayofbools() {
+ return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_TESTARRAYOFBOOLS);
+ }
+ float testf() const {
+ return GetField<float>(VT_TESTF, 3.14159f);
+ }
+ bool mutate_testf(float _testf) {
+ return SetField<float>(VT_TESTF, _testf, 3.14159f);
+ }
+ float testf2() const {
+ return GetField<float>(VT_TESTF2, 3.0f);
+ }
+ bool mutate_testf2(float _testf2) {
+ return SetField<float>(VT_TESTF2, _testf2, 3.0f);
+ }
+ float testf3() const {
+ return GetField<float>(VT_TESTF3, 0.0f);
+ }
+ bool mutate_testf3(float _testf3) {
+ return SetField<float>(VT_TESTF3, _testf3, 0.0f);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
+ }
+ flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring2() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
+ }
+ const flatbuffers::Vector<const MyGame::Example::Ability *> *testarrayofsortedstruct() const {
+ return GetPointer<const flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+ }
+ flatbuffers::Vector<const MyGame::Example::Ability *> *mutable_testarrayofsortedstruct() {
+ return GetPointer<flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+ }
+ const flatbuffers::Vector<uint8_t> *flex() const {
+ return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_FLEX);
+ }
+ flatbuffers::Vector<uint8_t> *mutable_flex() {
+ return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_FLEX);
+ }
+ flexbuffers::Reference flex_flexbuffer_root() const {
+ return flexbuffers::GetRoot(flex()->Data(), flex()->size());
+ }
+ const flatbuffers::Vector<const MyGame::Example::Test *> *test5() const {
+ return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
+ }
+ flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test5() {
+ return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
+ }
+ const flatbuffers::Vector<int64_t> *vector_of_longs() const {
+ return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
+ }
+ flatbuffers::Vector<int64_t> *mutable_vector_of_longs() {
+ return GetPointer<flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
+ }
+ const flatbuffers::Vector<double> *vector_of_doubles() const {
+ return GetPointer<const flatbuffers::Vector<double> *>(VT_VECTOR_OF_DOUBLES);
+ }
+ flatbuffers::Vector<double> *mutable_vector_of_doubles() {
+ return GetPointer<flatbuffers::Vector<double> *>(VT_VECTOR_OF_DOUBLES);
+ }
+ const MyGame::InParentNamespace *parent_namespace_test() const {
+ return GetPointer<const MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
+ }
+ MyGame::InParentNamespace *mutable_parent_namespace_test() {
+ return GetPointer<MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+ }
+ flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_referrables() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+ }
+ uint64_t single_weak_reference() const {
+ return GetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, 0);
+ }
+ bool mutate_single_weak_reference(uint64_t _single_weak_reference) {
+ return SetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, _single_weak_reference, 0);
+ }
+ const flatbuffers::Vector<uint64_t> *vector_of_weak_references() const {
+ return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
+ }
+ flatbuffers::Vector<uint64_t> *mutable_vector_of_weak_references() {
+ return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+ }
+ flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_strong_referrables() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+ }
+ uint64_t co_owning_reference() const {
+ return GetField<uint64_t>(VT_CO_OWNING_REFERENCE, 0);
+ }
+ bool mutate_co_owning_reference(uint64_t _co_owning_reference) {
+ return SetField<uint64_t>(VT_CO_OWNING_REFERENCE, _co_owning_reference, 0);
+ }
+ const flatbuffers::Vector<uint64_t> *vector_of_co_owning_references() const {
+ return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_CO_OWNING_REFERENCES);
+ }
+ flatbuffers::Vector<uint64_t> *mutable_vector_of_co_owning_references() {
+ return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_CO_OWNING_REFERENCES);
+ }
+ uint64_t non_owning_reference() const {
+ return GetField<uint64_t>(VT_NON_OWNING_REFERENCE, 0);
+ }
+ bool mutate_non_owning_reference(uint64_t _non_owning_reference) {
+ return SetField<uint64_t>(VT_NON_OWNING_REFERENCE, _non_owning_reference, 0);
+ }
+ const flatbuffers::Vector<uint64_t> *vector_of_non_owning_references() const {
+ return GetPointer<const flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
+ }
+ flatbuffers::Vector<uint64_t> *mutable_vector_of_non_owning_references() {
+ return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
+ }
+ MyGame::Example::AnyUniqueAliases any_unique_type() const {
+ return static_cast<MyGame::Example::AnyUniqueAliases>(GetField<uint8_t>(VT_ANY_UNIQUE_TYPE, 0));
+ }
+ const void *any_unique() const {
+ return GetPointer<const void *>(VT_ANY_UNIQUE);
+ }
+ template<typename T> const T *any_unique_as() const;
+ const MyGame::Example::Monster *any_unique_as_M() const {
+ return any_unique_type() == MyGame::Example::AnyUniqueAliases::M ? static_cast<const MyGame::Example::Monster *>(any_unique()) : nullptr;
+ }
+ const MyGame::Example::TestSimpleTableWithEnum *any_unique_as_TS() const {
+ return any_unique_type() == MyGame::Example::AnyUniqueAliases::TS ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(any_unique()) : nullptr;
+ }
+ const MyGame::Example2::Monster *any_unique_as_M2() const {
+ return any_unique_type() == MyGame::Example::AnyUniqueAliases::M2 ? static_cast<const MyGame::Example2::Monster *>(any_unique()) : nullptr;
+ }
+ void *mutable_any_unique() {
+ return GetPointer<void *>(VT_ANY_UNIQUE);
+ }
+ MyGame::Example::AnyAmbiguousAliases any_ambiguous_type() const {
+ return static_cast<MyGame::Example::AnyAmbiguousAliases>(GetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, 0));
+ }
+ const void *any_ambiguous() const {
+ return GetPointer<const void *>(VT_ANY_AMBIGUOUS);
+ }
+ const MyGame::Example::Monster *any_ambiguous_as_M1() const {
+ return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases::M1 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+ }
+ const MyGame::Example::Monster *any_ambiguous_as_M2() const {
+ return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases::M2 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+ }
+ const MyGame::Example::Monster *any_ambiguous_as_M3() const {
+ return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases::M3 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
+ }
+ void *mutable_any_ambiguous() {
+ return GetPointer<void *>(VT_ANY_AMBIGUOUS);
+ }
+ const flatbuffers::Vector<MyGame::Example::Color> *vector_of_enums() const {
+ return GetPointer<const flatbuffers::Vector<MyGame::Example::Color> *>(VT_VECTOR_OF_ENUMS);
+ }
+ flatbuffers::Vector<MyGame::Example::Color> *mutable_vector_of_enums() {
+ return GetPointer<flatbuffers::Vector<MyGame::Example::Color> *>(VT_VECTOR_OF_ENUMS);
+ }
+ MyGame::Example::Race signed_enum() const {
+ return static_cast<MyGame::Example::Race>(GetField<int8_t>(VT_SIGNED_ENUM, -1));
+ }
+ bool mutate_signed_enum(MyGame::Example::Race _signed_enum) {
+ return SetField<int8_t>(VT_SIGNED_ENUM, static_cast<int8_t>(_signed_enum), -1);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<MyGame::Example::Vec3>(verifier, VT_POS) &&
+ VerifyField<int16_t>(verifier, VT_MANA) &&
+ VerifyField<int16_t>(verifier, VT_HP) &&
+ VerifyOffsetRequired(verifier, VT_NAME) &&
+ verifier.VerifyString(name()) &&
+ VerifyOffset(verifier, VT_INVENTORY) &&
+ verifier.VerifyVector(inventory()) &&
+ VerifyField<uint8_t>(verifier, VT_COLOR) &&
+ VerifyField<uint8_t>(verifier, VT_TEST_TYPE) &&
+ VerifyOffset(verifier, VT_TEST) &&
+ VerifyAny(verifier, test(), test_type()) &&
+ VerifyOffset(verifier, VT_TEST4) &&
+ verifier.VerifyVector(test4()) &&
+ VerifyOffset(verifier, VT_TESTARRAYOFSTRING) &&
+ verifier.VerifyVector(testarrayofstring()) &&
+ verifier.VerifyVectorOfStrings(testarrayofstring()) &&
+ VerifyOffset(verifier, VT_TESTARRAYOFTABLES) &&
+ verifier.VerifyVector(testarrayoftables()) &&
+ verifier.VerifyVectorOfTables(testarrayoftables()) &&
+ VerifyOffset(verifier, VT_ENEMY) &&
+ verifier.VerifyTable(enemy()) &&
+ VerifyOffset(verifier, VT_TESTNESTEDFLATBUFFER) &&
+ verifier.VerifyVector(testnestedflatbuffer()) &&
+ VerifyOffset(verifier, VT_TESTEMPTY) &&
+ verifier.VerifyTable(testempty()) &&
+ VerifyField<uint8_t>(verifier, VT_TESTBOOL) &&
+ VerifyField<int32_t>(verifier, VT_TESTHASHS32_FNV1) &&
+ VerifyField<uint32_t>(verifier, VT_TESTHASHU32_FNV1) &&
+ VerifyField<int64_t>(verifier, VT_TESTHASHS64_FNV1) &&
+ VerifyField<uint64_t>(verifier, VT_TESTHASHU64_FNV1) &&
+ VerifyField<int32_t>(verifier, VT_TESTHASHS32_FNV1A) &&
+ VerifyField<uint32_t>(verifier, VT_TESTHASHU32_FNV1A) &&
+ VerifyField<int64_t>(verifier, VT_TESTHASHS64_FNV1A) &&
+ VerifyField<uint64_t>(verifier, VT_TESTHASHU64_FNV1A) &&
+ VerifyOffset(verifier, VT_TESTARRAYOFBOOLS) &&
+ verifier.VerifyVector(testarrayofbools()) &&
+ VerifyField<float>(verifier, VT_TESTF) &&
+ VerifyField<float>(verifier, VT_TESTF2) &&
+ VerifyField<float>(verifier, VT_TESTF3) &&
+ VerifyOffset(verifier, VT_TESTARRAYOFSTRING2) &&
+ verifier.VerifyVector(testarrayofstring2()) &&
+ verifier.VerifyVectorOfStrings(testarrayofstring2()) &&
+ VerifyOffset(verifier, VT_TESTARRAYOFSORTEDSTRUCT) &&
+ verifier.VerifyVector(testarrayofsortedstruct()) &&
+ VerifyOffset(verifier, VT_FLEX) &&
+ verifier.VerifyVector(flex()) &&
+ VerifyOffset(verifier, VT_TEST5) &&
+ verifier.VerifyVector(test5()) &&
+ VerifyOffset(verifier, VT_VECTOR_OF_LONGS) &&
+ verifier.VerifyVector(vector_of_longs()) &&
+ VerifyOffset(verifier, VT_VECTOR_OF_DOUBLES) &&
+ verifier.VerifyVector(vector_of_doubles()) &&
+ VerifyOffset(verifier, VT_PARENT_NAMESPACE_TEST) &&
+ verifier.VerifyTable(parent_namespace_test()) &&
+ VerifyOffset(verifier, VT_VECTOR_OF_REFERRABLES) &&
+ verifier.VerifyVector(vector_of_referrables()) &&
+ verifier.VerifyVectorOfTables(vector_of_referrables()) &&
+ VerifyField<uint64_t>(verifier, VT_SINGLE_WEAK_REFERENCE) &&
+ VerifyOffset(verifier, VT_VECTOR_OF_WEAK_REFERENCES) &&
+ verifier.VerifyVector(vector_of_weak_references()) &&
+ VerifyOffset(verifier, VT_VECTOR_OF_STRONG_REFERRABLES) &&
+ verifier.VerifyVector(vector_of_strong_referrables()) &&
+ verifier.VerifyVectorOfTables(vector_of_strong_referrables()) &&
+ VerifyField<uint64_t>(verifier, VT_CO_OWNING_REFERENCE) &&
+ VerifyOffset(verifier, VT_VECTOR_OF_CO_OWNING_REFERENCES) &&
+ verifier.VerifyVector(vector_of_co_owning_references()) &&
+ VerifyField<uint64_t>(verifier, VT_NON_OWNING_REFERENCE) &&
+ VerifyOffset(verifier, VT_VECTOR_OF_NON_OWNING_REFERENCES) &&
+ verifier.VerifyVector(vector_of_non_owning_references()) &&
+ VerifyField<uint8_t>(verifier, VT_ANY_UNIQUE_TYPE) &&
+ VerifyOffset(verifier, VT_ANY_UNIQUE) &&
+ VerifyAnyUniqueAliases(verifier, any_unique(), any_unique_type()) &&
+ VerifyField<uint8_t>(verifier, VT_ANY_AMBIGUOUS_TYPE) &&
+ VerifyOffset(verifier, VT_ANY_AMBIGUOUS) &&
+ VerifyAnyAmbiguousAliases(verifier, any_ambiguous(), any_ambiguous_type()) &&
+ VerifyOffset(verifier, VT_VECTOR_OF_ENUMS) &&
+ verifier.VerifyVector(vector_of_enums()) &&
+ VerifyField<int8_t>(verifier, VT_SIGNED_ENUM) &&
+ verifier.EndTable();
+ }
+ MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+template<> inline const MyGame::Example::Monster *Monster::test_as<MyGame::Example::Monster>() const {
+ return test_as_Monster();
+}
+
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::test_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+ return test_as_TestSimpleTableWithEnum();
+}
+
+template<> inline const MyGame::Example2::Monster *Monster::test_as<MyGame::Example2::Monster>() const {
+ return test_as_MyGame_Example2_Monster();
+}
+
+template<> inline const MyGame::Example::Monster *Monster::any_unique_as<MyGame::Example::Monster>() const {
+ return any_unique_as_M();
+}
+
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::any_unique_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+ return any_unique_as_TS();
+}
+
+template<> inline const MyGame::Example2::Monster *Monster::any_unique_as<MyGame::Example2::Monster>() const {
+ return any_unique_as_M2();
+}
+
+struct MonsterBuilder {
+ typedef Monster Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_pos(const MyGame::Example::Vec3 *pos) {
+ fbb_.AddStruct(Monster::VT_POS, pos);
+ }
+ void add_mana(int16_t mana) {
+ fbb_.AddElement<int16_t>(Monster::VT_MANA, mana, 150);
+ }
+ void add_hp(int16_t hp) {
+ fbb_.AddElement<int16_t>(Monster::VT_HP, hp, 100);
+ }
+ void add_name(flatbuffers::Offset<flatbuffers::String> name) {
+ fbb_.AddOffset(Monster::VT_NAME, name);
+ }
+ void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) {
+ fbb_.AddOffset(Monster::VT_INVENTORY, inventory);
+ }
+ void add_color(MyGame::Example::Color color) {
+ fbb_.AddElement<uint8_t>(Monster::VT_COLOR, static_cast<uint8_t>(color), 8);
+ }
+ void add_test_type(MyGame::Example::Any test_type) {
+ fbb_.AddElement<uint8_t>(Monster::VT_TEST_TYPE, static_cast<uint8_t>(test_type), 0);
+ }
+ void add_test(flatbuffers::Offset<void> test) {
+ fbb_.AddOffset(Monster::VT_TEST, test);
+ }
+ void add_test4(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4) {
+ fbb_.AddOffset(Monster::VT_TEST4, test4);
+ }
+ void add_testarrayofstring(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring) {
+ fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
+ }
+ void add_testarrayoftables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables) {
+ fbb_.AddOffset(Monster::VT_TESTARRAYOFTABLES, testarrayoftables);
+ }
+ void add_enemy(flatbuffers::Offset<MyGame::Example::Monster> enemy) {
+ fbb_.AddOffset(Monster::VT_ENEMY, enemy);
+ }
+ void add_testnestedflatbuffer(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer) {
+ fbb_.AddOffset(Monster::VT_TESTNESTEDFLATBUFFER, testnestedflatbuffer);
+ }
+ void add_testempty(flatbuffers::Offset<MyGame::Example::Stat> testempty) {
+ fbb_.AddOffset(Monster::VT_TESTEMPTY, testempty);
+ }
+ void add_testbool(bool testbool) {
+ fbb_.AddElement<uint8_t>(Monster::VT_TESTBOOL, static_cast<uint8_t>(testbool), 0);
+ }
+ void add_testhashs32_fnv1(int32_t testhashs32_fnv1) {
+ fbb_.AddElement<int32_t>(Monster::VT_TESTHASHS32_FNV1, testhashs32_fnv1, 0);
+ }
+ void add_testhashu32_fnv1(uint32_t testhashu32_fnv1) {
+ fbb_.AddElement<uint32_t>(Monster::VT_TESTHASHU32_FNV1, testhashu32_fnv1, 0);
+ }
+ void add_testhashs64_fnv1(int64_t testhashs64_fnv1) {
+ fbb_.AddElement<int64_t>(Monster::VT_TESTHASHS64_FNV1, testhashs64_fnv1, 0);
+ }
+ void add_testhashu64_fnv1(uint64_t testhashu64_fnv1) {
+ fbb_.AddElement<uint64_t>(Monster::VT_TESTHASHU64_FNV1, testhashu64_fnv1, 0);
+ }
+ void add_testhashs32_fnv1a(int32_t testhashs32_fnv1a) {
+ fbb_.AddElement<int32_t>(Monster::VT_TESTHASHS32_FNV1A, testhashs32_fnv1a, 0);
+ }
+ void add_testhashu32_fnv1a(uint32_t testhashu32_fnv1a) {
+ fbb_.AddElement<uint32_t>(Monster::VT_TESTHASHU32_FNV1A, testhashu32_fnv1a, 0);
+ }
+ void add_testhashs64_fnv1a(int64_t testhashs64_fnv1a) {
+ fbb_.AddElement<int64_t>(Monster::VT_TESTHASHS64_FNV1A, testhashs64_fnv1a, 0);
+ }
+ void add_testhashu64_fnv1a(uint64_t testhashu64_fnv1a) {
+ fbb_.AddElement<uint64_t>(Monster::VT_TESTHASHU64_FNV1A, testhashu64_fnv1a, 0);
+ }
+ void add_testarrayofbools(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools) {
+ fbb_.AddOffset(Monster::VT_TESTARRAYOFBOOLS, testarrayofbools);
+ }
+ void add_testf(float testf) {
+ fbb_.AddElement<float>(Monster::VT_TESTF, testf, 3.14159f);
+ }
+ void add_testf2(float testf2) {
+ fbb_.AddElement<float>(Monster::VT_TESTF2, testf2, 3.0f);
+ }
+ void add_testf3(float testf3) {
+ fbb_.AddElement<float>(Monster::VT_TESTF3, testf3, 0.0f);
+ }
+ void add_testarrayofstring2(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2) {
+ fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING2, testarrayofstring2);
+ }
+ void add_testarrayofsortedstruct(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct) {
+ fbb_.AddOffset(Monster::VT_TESTARRAYOFSORTEDSTRUCT, testarrayofsortedstruct);
+ }
+ void add_flex(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex) {
+ fbb_.AddOffset(Monster::VT_FLEX, flex);
+ }
+ void add_test5(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5) {
+ fbb_.AddOffset(Monster::VT_TEST5, test5);
+ }
+ void add_vector_of_longs(flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs) {
+ fbb_.AddOffset(Monster::VT_VECTOR_OF_LONGS, vector_of_longs);
+ }
+ void add_vector_of_doubles(flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles) {
+ fbb_.AddOffset(Monster::VT_VECTOR_OF_DOUBLES, vector_of_doubles);
+ }
+ void add_parent_namespace_test(flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test) {
+ fbb_.AddOffset(Monster::VT_PARENT_NAMESPACE_TEST, parent_namespace_test);
+ }
+ void add_vector_of_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables) {
+ fbb_.AddOffset(Monster::VT_VECTOR_OF_REFERRABLES, vector_of_referrables);
+ }
+ void add_single_weak_reference(uint64_t single_weak_reference) {
+ fbb_.AddElement<uint64_t>(Monster::VT_SINGLE_WEAK_REFERENCE, single_weak_reference, 0);
+ }
+ void add_vector_of_weak_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references) {
+ fbb_.AddOffset(Monster::VT_VECTOR_OF_WEAK_REFERENCES, vector_of_weak_references);
+ }
+ void add_vector_of_strong_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables) {
+ fbb_.AddOffset(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, vector_of_strong_referrables);
+ }
+ void add_co_owning_reference(uint64_t co_owning_reference) {
+ fbb_.AddElement<uint64_t>(Monster::VT_CO_OWNING_REFERENCE, co_owning_reference, 0);
+ }
+ void add_vector_of_co_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references) {
+ fbb_.AddOffset(Monster::VT_VECTOR_OF_CO_OWNING_REFERENCES, vector_of_co_owning_references);
+ }
+ void add_non_owning_reference(uint64_t non_owning_reference) {
+ fbb_.AddElement<uint64_t>(Monster::VT_NON_OWNING_REFERENCE, non_owning_reference, 0);
+ }
+ void add_vector_of_non_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references) {
+ fbb_.AddOffset(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, vector_of_non_owning_references);
+ }
+ void add_any_unique_type(MyGame::Example::AnyUniqueAliases any_unique_type) {
+ fbb_.AddElement<uint8_t>(Monster::VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(any_unique_type), 0);
+ }
+ void add_any_unique(flatbuffers::Offset<void> any_unique) {
+ fbb_.AddOffset(Monster::VT_ANY_UNIQUE, any_unique);
+ }
+ void add_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases any_ambiguous_type) {
+ fbb_.AddElement<uint8_t>(Monster::VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(any_ambiguous_type), 0);
+ }
+ void add_any_ambiguous(flatbuffers::Offset<void> any_ambiguous) {
+ fbb_.AddOffset(Monster::VT_ANY_AMBIGUOUS, any_ambiguous);
+ }
+ void add_vector_of_enums(flatbuffers::Offset<flatbuffers::Vector<MyGame::Example::Color>> vector_of_enums) {
+ fbb_.AddOffset(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
+ }
+ void add_signed_enum(MyGame::Example::Race signed_enum) {
+ fbb_.AddElement<int8_t>(Monster::VT_SIGNED_ENUM, static_cast<int8_t>(signed_enum), -1);
+ }
+ explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ MonsterBuilder &operator=(const MonsterBuilder &);
+ flatbuffers::Offset<Monster> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Monster>(end);
+ fbb_.Required(o, Monster::VT_NAME);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Monster> CreateMonster(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const MyGame::Example::Vec3 *pos = 0,
+ int16_t mana = 150,
+ int16_t hp = 100,
+ flatbuffers::Offset<flatbuffers::String> name = 0,
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
+ MyGame::Example::Color color = MyGame::Example::Color::Blue,
+ MyGame::Example::Any test_type = MyGame::Example::Any::NONE,
+ flatbuffers::Offset<void> test = 0,
+ flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4 = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables = 0,
+ flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer = 0,
+ flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
+ bool testbool = false,
+ int32_t testhashs32_fnv1 = 0,
+ uint32_t testhashu32_fnv1 = 0,
+ int64_t testhashs64_fnv1 = 0,
+ uint64_t testhashu64_fnv1 = 0,
+ int32_t testhashs32_fnv1a = 0,
+ uint32_t testhashu32_fnv1a = 0,
+ int64_t testhashs64_fnv1a = 0,
+ uint64_t testhashu64_fnv1a = 0,
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testarrayofbools = 0,
+ float testf = 3.14159f,
+ float testf2 = 3.0f,
+ float testf3 = 0.0f,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2 = 0,
+ flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct = 0,
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex = 0,
+ flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5 = 0,
+ flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs = 0,
+ flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles = 0,
+ flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables = 0,
+ uint64_t single_weak_reference = 0,
+ flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables = 0,
+ uint64_t co_owning_reference = 0,
+ flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references = 0,
+ uint64_t non_owning_reference = 0,
+ flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references = 0,
+ MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases::NONE,
+ flatbuffers::Offset<void> any_unique = 0,
+ MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases::NONE,
+ flatbuffers::Offset<void> any_ambiguous = 0,
+ flatbuffers::Offset<flatbuffers::Vector<MyGame::Example::Color>> vector_of_enums = 0,
+ MyGame::Example::Race signed_enum = MyGame::Example::Race::None) {
+ MonsterBuilder builder_(_fbb);
+ builder_.add_non_owning_reference(non_owning_reference);
+ builder_.add_co_owning_reference(co_owning_reference);
+ builder_.add_single_weak_reference(single_weak_reference);
+ builder_.add_testhashu64_fnv1a(testhashu64_fnv1a);
+ builder_.add_testhashs64_fnv1a(testhashs64_fnv1a);
+ builder_.add_testhashu64_fnv1(testhashu64_fnv1);
+ builder_.add_testhashs64_fnv1(testhashs64_fnv1);
+ builder_.add_vector_of_enums(vector_of_enums);
+ builder_.add_any_ambiguous(any_ambiguous);
+ builder_.add_any_unique(any_unique);
+ builder_.add_vector_of_non_owning_references(vector_of_non_owning_references);
+ builder_.add_vector_of_co_owning_references(vector_of_co_owning_references);
+ builder_.add_vector_of_strong_referrables(vector_of_strong_referrables);
+ builder_.add_vector_of_weak_references(vector_of_weak_references);
+ builder_.add_vector_of_referrables(vector_of_referrables);
+ builder_.add_parent_namespace_test(parent_namespace_test);
+ builder_.add_vector_of_doubles(vector_of_doubles);
+ builder_.add_vector_of_longs(vector_of_longs);
+ builder_.add_test5(test5);
+ builder_.add_flex(flex);
+ builder_.add_testarrayofsortedstruct(testarrayofsortedstruct);
+ builder_.add_testarrayofstring2(testarrayofstring2);
+ builder_.add_testf3(testf3);
+ builder_.add_testf2(testf2);
+ builder_.add_testf(testf);
+ builder_.add_testarrayofbools(testarrayofbools);
+ builder_.add_testhashu32_fnv1a(testhashu32_fnv1a);
+ builder_.add_testhashs32_fnv1a(testhashs32_fnv1a);
+ builder_.add_testhashu32_fnv1(testhashu32_fnv1);
+ builder_.add_testhashs32_fnv1(testhashs32_fnv1);
+ builder_.add_testempty(testempty);
+ builder_.add_testnestedflatbuffer(testnestedflatbuffer);
+ builder_.add_enemy(enemy);
+ builder_.add_testarrayoftables(testarrayoftables);
+ builder_.add_testarrayofstring(testarrayofstring);
+ builder_.add_test4(test4);
+ builder_.add_test(test);
+ builder_.add_inventory(inventory);
+ builder_.add_name(name);
+ builder_.add_pos(pos);
+ builder_.add_hp(hp);
+ builder_.add_mana(mana);
+ builder_.add_signed_enum(signed_enum);
+ builder_.add_any_ambiguous_type(any_ambiguous_type);
+ builder_.add_any_unique_type(any_unique_type);
+ builder_.add_testbool(testbool);
+ builder_.add_test_type(test_type);
+ builder_.add_color(color);
+ return builder_.Finish();
+}
+
+struct Monster::Traits {
+ using type = Monster;
+ static auto constexpr Create = CreateMonster;
+};
+
+inline flatbuffers::Offset<Monster> CreateMonsterDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const MyGame::Example::Vec3 *pos = 0,
+ int16_t mana = 150,
+ int16_t hp = 100,
+ const char *name = nullptr,
+ const std::vector<uint8_t> *inventory = nullptr,
+ MyGame::Example::Color color = MyGame::Example::Color::Blue,
+ MyGame::Example::Any test_type = MyGame::Example::Any::NONE,
+ flatbuffers::Offset<void> test = 0,
+ const std::vector<MyGame::Example::Test> *test4 = nullptr,
+ const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring = nullptr,
+ std::vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables = nullptr,
+ flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
+ const std::vector<uint8_t> *testnestedflatbuffer = nullptr,
+ flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
+ bool testbool = false,
+ int32_t testhashs32_fnv1 = 0,
+ uint32_t testhashu32_fnv1 = 0,
+ int64_t testhashs64_fnv1 = 0,
+ uint64_t testhashu64_fnv1 = 0,
+ int32_t testhashs32_fnv1a = 0,
+ uint32_t testhashu32_fnv1a = 0,
+ int64_t testhashs64_fnv1a = 0,
+ uint64_t testhashu64_fnv1a = 0,
+ const std::vector<uint8_t> *testarrayofbools = nullptr,
+ float testf = 3.14159f,
+ float testf2 = 3.0f,
+ float testf3 = 0.0f,
+ const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2 = nullptr,
+ std::vector<MyGame::Example::Ability> *testarrayofsortedstruct = nullptr,
+ const std::vector<uint8_t> *flex = nullptr,
+ const std::vector<MyGame::Example::Test> *test5 = nullptr,
+ const std::vector<int64_t> *vector_of_longs = nullptr,
+ const std::vector<double> *vector_of_doubles = nullptr,
+ flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
+ std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables = nullptr,
+ uint64_t single_weak_reference = 0,
+ const std::vector<uint64_t> *vector_of_weak_references = nullptr,
+ std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables = nullptr,
+ uint64_t co_owning_reference = 0,
+ const std::vector<uint64_t> *vector_of_co_owning_references = nullptr,
+ uint64_t non_owning_reference = 0,
+ const std::vector<uint64_t> *vector_of_non_owning_references = nullptr,
+ MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases::NONE,
+ flatbuffers::Offset<void> any_unique = 0,
+ MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases::NONE,
+ flatbuffers::Offset<void> any_ambiguous = 0,
+ const std::vector<MyGame::Example::Color> *vector_of_enums = nullptr,
+ MyGame::Example::Race signed_enum = MyGame::Example::Race::None) {
+ auto name__ = name ? _fbb.CreateString(name) : 0;
+ auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
+ auto test4__ = test4 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test4) : 0;
+ auto testarrayofstring__ = testarrayofstring ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring) : 0;
+ auto testarrayoftables__ = testarrayoftables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Monster>(testarrayoftables) : 0;
+ auto testnestedflatbuffer__ = testnestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testnestedflatbuffer) : 0;
+ auto testarrayofbools__ = testarrayofbools ? _fbb.CreateVector<uint8_t>(*testarrayofbools) : 0;
+ auto testarrayofstring2__ = testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0;
+ auto testarrayofsortedstruct__ = testarrayofsortedstruct ? _fbb.CreateVectorOfSortedStructs<MyGame::Example::Ability>(testarrayofsortedstruct) : 0;
+ auto flex__ = flex ? _fbb.CreateVector<uint8_t>(*flex) : 0;
+ auto test5__ = test5 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test5) : 0;
+ auto vector_of_longs__ = vector_of_longs ? _fbb.CreateVector<int64_t>(*vector_of_longs) : 0;
+ auto vector_of_doubles__ = vector_of_doubles ? _fbb.CreateVector<double>(*vector_of_doubles) : 0;
+ auto vector_of_referrables__ = vector_of_referrables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Referrable>(vector_of_referrables) : 0;
+ auto vector_of_weak_references__ = vector_of_weak_references ? _fbb.CreateVector<uint64_t>(*vector_of_weak_references) : 0;
+ auto vector_of_strong_referrables__ = vector_of_strong_referrables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Referrable>(vector_of_strong_referrables) : 0;
+ auto vector_of_co_owning_references__ = vector_of_co_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_co_owning_references) : 0;
+ auto vector_of_non_owning_references__ = vector_of_non_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_non_owning_references) : 0;
+ auto vector_of_enums__ = vector_of_enums ? _fbb.CreateVector<MyGame::Example::Color>(*vector_of_enums) : 0;
+ return MyGame::Example::CreateMonster(
+ _fbb,
+ pos,
+ mana,
+ hp,
+ name__,
+ inventory__,
+ color,
+ test_type,
+ test,
+ test4__,
+ testarrayofstring__,
+ testarrayoftables__,
+ enemy,
+ testnestedflatbuffer__,
+ testempty,
+ testbool,
+ testhashs32_fnv1,
+ testhashu32_fnv1,
+ testhashs64_fnv1,
+ testhashu64_fnv1,
+ testhashs32_fnv1a,
+ testhashu32_fnv1a,
+ testhashs64_fnv1a,
+ testhashu64_fnv1a,
+ testarrayofbools__,
+ testf,
+ testf2,
+ testf3,
+ testarrayofstring2__,
+ testarrayofsortedstruct__,
+ flex__,
+ test5__,
+ vector_of_longs__,
+ vector_of_doubles__,
+ parent_namespace_test,
+ vector_of_referrables__,
+ single_weak_reference,
+ vector_of_weak_references__,
+ vector_of_strong_referrables__,
+ co_owning_reference,
+ vector_of_co_owning_references__,
+ non_owning_reference,
+ vector_of_non_owning_references__,
+ any_unique_type,
+ any_unique,
+ any_ambiguous_type,
+ any_ambiguous,
+ vector_of_enums__,
+ signed_enum);
+}
+
+flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+struct TypeAliasesT : public flatbuffers::NativeTable {
+ typedef TypeAliases TableType;
+ int8_t i8;
+ uint8_t u8;
+ int16_t i16;
+ uint16_t u16;
+ int32_t i32;
+ uint32_t u32;
+ int64_t i64;
+ uint64_t u64;
+ float f32;
+ double f64;
+ std::vector<int8_t> v8;
+ std::vector<double> vf64;
+ TypeAliasesT()
+ : i8(0),
+ u8(0),
+ i16(0),
+ u16(0),
+ i32(0),
+ u32(0),
+ i64(0),
+ u64(0),
+ f32(0.0f),
+ f64(0.0) {
+ }
+};
+
+struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef TypeAliasesT NativeTableType;
+ typedef TypeAliasesBuilder Builder;
+ struct Traits;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return TypeAliasesTypeTable();
+ }
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_I8 = 4,
+ VT_U8 = 6,
+ VT_I16 = 8,
+ VT_U16 = 10,
+ VT_I32 = 12,
+ VT_U32 = 14,
+ VT_I64 = 16,
+ VT_U64 = 18,
+ VT_F32 = 20,
+ VT_F64 = 22,
+ VT_V8 = 24,
+ VT_VF64 = 26
+ };
+ int8_t i8() const {
+ return GetField<int8_t>(VT_I8, 0);
+ }
+ bool mutate_i8(int8_t _i8) {
+ return SetField<int8_t>(VT_I8, _i8, 0);
+ }
+ uint8_t u8() const {
+ return GetField<uint8_t>(VT_U8, 0);
+ }
+ bool mutate_u8(uint8_t _u8) {
+ return SetField<uint8_t>(VT_U8, _u8, 0);
+ }
+ int16_t i16() const {
+ return GetField<int16_t>(VT_I16, 0);
+ }
+ bool mutate_i16(int16_t _i16) {
+ return SetField<int16_t>(VT_I16, _i16, 0);
+ }
+ uint16_t u16() const {
+ return GetField<uint16_t>(VT_U16, 0);
+ }
+ bool mutate_u16(uint16_t _u16) {
+ return SetField<uint16_t>(VT_U16, _u16, 0);
+ }
+ int32_t i32() const {
+ return GetField<int32_t>(VT_I32, 0);
+ }
+ bool mutate_i32(int32_t _i32) {
+ return SetField<int32_t>(VT_I32, _i32, 0);
+ }
+ uint32_t u32() const {
+ return GetField<uint32_t>(VT_U32, 0);
+ }
+ bool mutate_u32(uint32_t _u32) {
+ return SetField<uint32_t>(VT_U32, _u32, 0);
+ }
+ int64_t i64() const {
+ return GetField<int64_t>(VT_I64, 0);
+ }
+ bool mutate_i64(int64_t _i64) {
+ return SetField<int64_t>(VT_I64, _i64, 0);
+ }
+ uint64_t u64() const {
+ return GetField<uint64_t>(VT_U64, 0);
+ }
+ bool mutate_u64(uint64_t _u64) {
+ return SetField<uint64_t>(VT_U64, _u64, 0);
+ }
+ float f32() const {
+ return GetField<float>(VT_F32, 0.0f);
+ }
+ bool mutate_f32(float _f32) {
+ return SetField<float>(VT_F32, _f32, 0.0f);
+ }
+ double f64() const {
+ return GetField<double>(VT_F64, 0.0);
+ }
+ bool mutate_f64(double _f64) {
+ return SetField<double>(VT_F64, _f64, 0.0);
+ }
+ const flatbuffers::Vector<int8_t> *v8() const {
+ return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_V8);
+ }
+ flatbuffers::Vector<int8_t> *mutable_v8() {
+ return GetPointer<flatbuffers::Vector<int8_t> *>(VT_V8);
+ }
+ const flatbuffers::Vector<double> *vf64() const {
+ return GetPointer<const flatbuffers::Vector<double> *>(VT_VF64);
+ }
+ flatbuffers::Vector<double> *mutable_vf64() {
+ return GetPointer<flatbuffers::Vector<double> *>(VT_VF64);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<int8_t>(verifier, VT_I8) &&
+ VerifyField<uint8_t>(verifier, VT_U8) &&
+ VerifyField<int16_t>(verifier, VT_I16) &&
+ VerifyField<uint16_t>(verifier, VT_U16) &&
+ VerifyField<int32_t>(verifier, VT_I32) &&
+ VerifyField<uint32_t>(verifier, VT_U32) &&
+ VerifyField<int64_t>(verifier, VT_I64) &&
+ VerifyField<uint64_t>(verifier, VT_U64) &&
+ VerifyField<float>(verifier, VT_F32) &&
+ VerifyField<double>(verifier, VT_F64) &&
+ VerifyOffset(verifier, VT_V8) &&
+ verifier.VerifyVector(v8()) &&
+ VerifyOffset(verifier, VT_VF64) &&
+ verifier.VerifyVector(vf64()) &&
+ verifier.EndTable();
+ }
+ TypeAliasesT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<TypeAliases> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct TypeAliasesBuilder {
+ typedef TypeAliases Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_i8(int8_t i8) {
+ fbb_.AddElement<int8_t>(TypeAliases::VT_I8, i8, 0);
+ }
+ void add_u8(uint8_t u8) {
+ fbb_.AddElement<uint8_t>(TypeAliases::VT_U8, u8, 0);
+ }
+ void add_i16(int16_t i16) {
+ fbb_.AddElement<int16_t>(TypeAliases::VT_I16, i16, 0);
+ }
+ void add_u16(uint16_t u16) {
+ fbb_.AddElement<uint16_t>(TypeAliases::VT_U16, u16, 0);
+ }
+ void add_i32(int32_t i32) {
+ fbb_.AddElement<int32_t>(TypeAliases::VT_I32, i32, 0);
+ }
+ void add_u32(uint32_t u32) {
+ fbb_.AddElement<uint32_t>(TypeAliases::VT_U32, u32, 0);
+ }
+ void add_i64(int64_t i64) {
+ fbb_.AddElement<int64_t>(TypeAliases::VT_I64, i64, 0);
+ }
+ void add_u64(uint64_t u64) {
+ fbb_.AddElement<uint64_t>(TypeAliases::VT_U64, u64, 0);
+ }
+ void add_f32(float f32) {
+ fbb_.AddElement<float>(TypeAliases::VT_F32, f32, 0.0f);
+ }
+ void add_f64(double f64) {
+ fbb_.AddElement<double>(TypeAliases::VT_F64, f64, 0.0);
+ }
+ void add_v8(flatbuffers::Offset<flatbuffers::Vector<int8_t>> v8) {
+ fbb_.AddOffset(TypeAliases::VT_V8, v8);
+ }
+ void add_vf64(flatbuffers::Offset<flatbuffers::Vector<double>> vf64) {
+ fbb_.AddOffset(TypeAliases::VT_VF64, vf64);
+ }
+ explicit TypeAliasesBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ TypeAliasesBuilder &operator=(const TypeAliasesBuilder &);
+ flatbuffers::Offset<TypeAliases> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<TypeAliases>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliases(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ int8_t i8 = 0,
+ uint8_t u8 = 0,
+ int16_t i16 = 0,
+ uint16_t u16 = 0,
+ int32_t i32 = 0,
+ uint32_t u32 = 0,
+ int64_t i64 = 0,
+ uint64_t u64 = 0,
+ float f32 = 0.0f,
+ double f64 = 0.0,
+ flatbuffers::Offset<flatbuffers::Vector<int8_t>> v8 = 0,
+ flatbuffers::Offset<flatbuffers::Vector<double>> vf64 = 0) {
+ TypeAliasesBuilder builder_(_fbb);
+ builder_.add_f64(f64);
+ builder_.add_u64(u64);
+ builder_.add_i64(i64);
+ builder_.add_vf64(vf64);
+ builder_.add_v8(v8);
+ builder_.add_f32(f32);
+ builder_.add_u32(u32);
+ builder_.add_i32(i32);
+ builder_.add_u16(u16);
+ builder_.add_i16(i16);
+ builder_.add_u8(u8);
+ builder_.add_i8(i8);
+ return builder_.Finish();
+}
+
+struct TypeAliases::Traits {
+ using type = TypeAliases;
+ static auto constexpr Create = CreateTypeAliases;
+};
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliasesDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ int8_t i8 = 0,
+ uint8_t u8 = 0,
+ int16_t i16 = 0,
+ uint16_t u16 = 0,
+ int32_t i32 = 0,
+ uint32_t u32 = 0,
+ int64_t i64 = 0,
+ uint64_t u64 = 0,
+ float f32 = 0.0f,
+ double f64 = 0.0,
+ const std::vector<int8_t> *v8 = nullptr,
+ const std::vector<double> *vf64 = nullptr) {
+ auto v8__ = v8 ? _fbb.CreateVector<int8_t>(*v8) : 0;
+ auto vf64__ = vf64 ? _fbb.CreateVector<double>(*vf64) : 0;
+ return MyGame::Example::CreateTypeAliases(
+ _fbb,
+ i8,
+ u8,
+ i16,
+ u16,
+ i32,
+ u32,
+ i64,
+ u64,
+ f32,
+ f64,
+ v8__,
+ vf64__);
+}
+
+flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+} // namespace Example
+
+inline InParentNamespaceT *InParentNamespace::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ std::unique_ptr<MyGame::InParentNamespaceT> _o = std::unique_ptr<MyGame::InParentNamespaceT>(new InParentNamespaceT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void InParentNamespace::UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+}
+
+inline flatbuffers::Offset<InParentNamespace> InParentNamespace::Pack(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateInParentNamespace(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffers::FlatBufferBuilder &_fbb, const InParentNamespaceT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const InParentNamespaceT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ return MyGame::CreateInParentNamespace(
+ _fbb);
+}
+
+namespace Example2 {
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ std::unique_ptr<MyGame::Example2::MonsterT> _o = std::unique_ptr<MyGame::Example2::MonsterT>(new MonsterT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ return MyGame::Example2::CreateMonster(
+ _fbb);
+}
+
+} // namespace Example2
+
+namespace Example {
+
+inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ std::unique_ptr<MyGame::Example::TestSimpleTableWithEnumT> _o = std::unique_ptr<MyGame::Example::TestSimpleTableWithEnumT>(new TestSimpleTableWithEnumT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void TestSimpleTableWithEnum::UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = color(); _o->color = _e; }
+}
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateTestSimpleTableWithEnum(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TestSimpleTableWithEnumT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _color = _o->color;
+ return MyGame::Example::CreateTestSimpleTableWithEnum(
+ _fbb,
+ _color);
+}
+
+inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ std::unique_ptr<MyGame::Example::StatT> _o = std::unique_ptr<MyGame::Example::StatT>(new StatT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void Stat::UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = id(); if (_e) _o->id = _e->str(); }
+ { auto _e = val(); _o->val = _e; }
+ { auto _e = count(); _o->count = _e; }
+}
+
+inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateStat(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StatT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _id = _o->id.empty() ? 0 : _fbb.CreateString(_o->id);
+ auto _val = _o->val;
+ auto _count = _o->count;
+ return MyGame::Example::CreateStat(
+ _fbb,
+ _id,
+ _val,
+ _count);
+}
+
+inline ReferrableT *Referrable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ std::unique_ptr<MyGame::Example::ReferrableT> _o = std::unique_ptr<MyGame::Example::ReferrableT>(new ReferrableT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void Referrable::UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = id(); _o->id = _e; }
+}
+
+inline flatbuffers::Offset<Referrable> Referrable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateReferrable(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ReferrableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _id = _o->id;
+ return MyGame::Example::CreateReferrable(
+ _fbb,
+ _id);
+}
+
+inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ std::unique_ptr<MyGame::Example::MonsterT> _o = std::unique_ptr<MyGame::Example::MonsterT>(new MonsterT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = pos(); if (_e) _o->pos = std::unique_ptr<MyGame::Example::Vec3>(new MyGame::Example::Vec3(*_e)); }
+ { auto _e = mana(); _o->mana = _e; }
+ { auto _e = hp(); _o->hp = _e; }
+ { auto _e = name(); if (_e) _o->name = _e->str(); }
+ { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } }
+ { auto _e = color(); _o->color = _e; }
+ { auto _e = test_type(); _o->test.type = _e; }
+ { auto _e = test(); if (_e) _o->test.value = MyGame::Example::AnyUnion::UnPack(_e, test_type(), _resolver); }
+ { auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } }
+ { auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } }
+ { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = std::unique_ptr<MyGame::Example::MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } }
+ { auto _e = enemy(); if (_e) _o->enemy = std::unique_ptr<MyGame::Example::MonsterT>(_e->UnPack(_resolver)); }
+ { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer[_i] = _e->Get(_i); } } }
+ { auto _e = testempty(); if (_e) _o->testempty = std::unique_ptr<MyGame::Example::StatT>(_e->UnPack(_resolver)); }
+ { auto _e = testbool(); _o->testbool = _e; }
+ { auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; }
+ { auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; }
+ { auto _e = testhashs64_fnv1(); _o->testhashs64_fnv1 = _e; }
+ { auto _e = testhashu64_fnv1(); _o->testhashu64_fnv1 = _e; }
+ { auto _e = testhashs32_fnv1a(); _o->testhashs32_fnv1a = _e; }
+ { auto _e = testhashu32_fnv1a(); //scalar resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; }
+ { auto _e = testhashs64_fnv1a(); _o->testhashs64_fnv1a = _e; }
+ { auto _e = testhashu64_fnv1a(); _o->testhashu64_fnv1a = _e; }
+ { auto _e = testarrayofbools(); if (_e) { _o->testarrayofbools.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofbools[_i] = _e->Get(_i) != 0; } } }
+ { auto _e = testf(); _o->testf = _e; }
+ { auto _e = testf2(); _o->testf2 = _e; }
+ { auto _e = testf3(); _o->testf3 = _e; }
+ { auto _e = testarrayofstring2(); if (_e) { _o->testarrayofstring2.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2[_i] = _e->Get(_i)->str(); } } }
+ { auto _e = testarrayofsortedstruct(); if (_e) { _o->testarrayofsortedstruct.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofsortedstruct[_i] = *_e->Get(_i); } } }
+ { auto _e = flex(); if (_e) { _o->flex.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->flex[_i] = _e->Get(_i); } } }
+ { auto _e = test5(); if (_e) { _o->test5.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test5[_i] = *_e->Get(_i); } } }
+ { auto _e = vector_of_longs(); if (_e) { _o->vector_of_longs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_longs[_i] = _e->Get(_i); } } }
+ { auto _e = vector_of_doubles(); if (_e) { _o->vector_of_doubles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_doubles[_i] = _e->Get(_i); } } }
+ { auto _e = parent_namespace_test(); if (_e) _o->parent_namespace_test = std::unique_ptr<MyGame::InParentNamespaceT>(_e->UnPack(_resolver)); }
+ { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_referrables[_i] = std::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } }
+ { auto _e = single_weak_reference(); //scalar resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->single_weak_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->single_weak_reference = nullptr; }
+ { auto _e = vector_of_weak_references(); if (_e) { _o->vector_of_weak_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_weak_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_weak_references[_i] = nullptr; } } }
+ { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_strong_referrables[_i] = std::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } }
+ { auto _e = co_owning_reference(); //scalar resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->co_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->co_owning_reference = nullptr; }
+ { auto _e = vector_of_co_owning_references(); if (_e) { _o->vector_of_co_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, default_ptr_type
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_co_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i)));/* else do nothing */; } } }
+ { auto _e = non_owning_reference(); //scalar resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->non_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->non_owning_reference = nullptr; }
+ { auto _e = vector_of_non_owning_references(); if (_e) { _o->vector_of_non_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_non_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_non_owning_references[_i] = nullptr; } } }
+ { auto _e = any_unique_type(); _o->any_unique.type = _e; }
+ { auto _e = any_unique(); if (_e) _o->any_unique.value = MyGame::Example::AnyUniqueAliasesUnion::UnPack(_e, any_unique_type(), _resolver); }
+ { auto _e = any_ambiguous_type(); _o->any_ambiguous.type = _e; }
+ { auto _e = any_ambiguous(); if (_e) _o->any_ambiguous.value = MyGame::Example::AnyAmbiguousAliasesUnion::UnPack(_e, any_ambiguous_type(), _resolver); }
+ { auto _e = vector_of_enums(); if (_e) { _o->vector_of_enums.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_enums[_i] = static_cast<MyGame::Example::Color>(_e->Get(_i)); } } }
+ { auto _e = signed_enum(); _o->signed_enum = _e; }
+}
+
+inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateMonster(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _pos = _o->pos ? _o->pos.get() : 0;
+ auto _mana = _o->mana;
+ auto _hp = _o->hp;
+ auto _name = _fbb.CreateString(_o->name);
+ auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
+ auto _color = _o->color;
+ auto _test_type = _o->test.type;
+ auto _test = _o->test.Pack(_fbb);
+ auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0;
+ auto _testarrayofstring = _o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0;
+ auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Monster>> (_o->testarrayoftables.size(), [](size_t i, _VectorArgs *__va) { return CreateMonster(*__va->__fbb, __va->__o->testarrayoftables[i].get(), __va->__rehasher); }, &_va ) : 0;
+ auto _enemy = _o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0;
+ auto _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
+ auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
+ auto _testbool = _o->testbool;
+ auto _testhashs32_fnv1 = _o->testhashs32_fnv1;
+ auto _testhashu32_fnv1 = _o->testhashu32_fnv1;
+ auto _testhashs64_fnv1 = _o->testhashs64_fnv1;
+ auto _testhashu64_fnv1 = _o->testhashu64_fnv1;
+ auto _testhashs32_fnv1a = _o->testhashs32_fnv1a;
+ auto _testhashu32_fnv1a = _rehasher ? static_cast<uint32_t>((*_rehasher)(_o->testhashu32_fnv1a)) : 0;
+ auto _testhashs64_fnv1a = _o->testhashs64_fnv1a;
+ auto _testhashu64_fnv1a = _o->testhashu64_fnv1a;
+ auto _testarrayofbools = _o->testarrayofbools.size() ? _fbb.CreateVector(_o->testarrayofbools) : 0;
+ auto _testf = _o->testf;
+ auto _testf2 = _o->testf2;
+ auto _testf3 = _o->testf3;
+ auto _testarrayofstring2 = _o->testarrayofstring2.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring2) : 0;
+ auto _testarrayofsortedstruct = _o->testarrayofsortedstruct.size() ? _fbb.CreateVectorOfStructs(_o->testarrayofsortedstruct) : 0;
+ auto _flex = _o->flex.size() ? _fbb.CreateVector(_o->flex) : 0;
+ auto _test5 = _o->test5.size() ? _fbb.CreateVectorOfStructs(_o->test5) : 0;
+ auto _vector_of_longs = _o->vector_of_longs.size() ? _fbb.CreateVector(_o->vector_of_longs) : 0;
+ auto _vector_of_doubles = _o->vector_of_doubles.size() ? _fbb.CreateVector(_o->vector_of_doubles) : 0;
+ auto _parent_namespace_test = _o->parent_namespace_test ? CreateInParentNamespace(_fbb, _o->parent_namespace_test.get(), _rehasher) : 0;
+ auto _vector_of_referrables = _o->vector_of_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+ auto _single_weak_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->single_weak_reference)) : 0;
+ auto _vector_of_weak_references = _o->vector_of_weak_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_weak_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_weak_references[i])) : 0; }, &_va ) : 0;
+ auto _vector_of_strong_referrables = _o->vector_of_strong_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_strong_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_strong_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+ auto _co_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->co_owning_reference)) : 0;
+ auto _vector_of_co_owning_references = _o->vector_of_co_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_co_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_co_owning_references[i].get())) : 0; }, &_va ) : 0;
+ auto _non_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->non_owning_reference)) : 0;
+ auto _vector_of_non_owning_references = _o->vector_of_non_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_non_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_non_owning_references[i])) : 0; }, &_va ) : 0;
+ auto _any_unique_type = _o->any_unique.type;
+ auto _any_unique = _o->any_unique.Pack(_fbb);
+ auto _any_ambiguous_type = _o->any_ambiguous.type;
+ auto _any_ambiguous = _o->any_ambiguous.Pack(_fbb);
+ auto _vector_of_enums = _o->vector_of_enums.size() ? _fbb.CreateVector(_o->vector_of_enums) : 0;
+ auto _signed_enum = _o->signed_enum;
+ return MyGame::Example::CreateMonster(
+ _fbb,
+ _pos,
+ _mana,
+ _hp,
+ _name,
+ _inventory,
+ _color,
+ _test_type,
+ _test,
+ _test4,
+ _testarrayofstring,
+ _testarrayoftables,
+ _enemy,
+ _testnestedflatbuffer,
+ _testempty,
+ _testbool,
+ _testhashs32_fnv1,
+ _testhashu32_fnv1,
+ _testhashs64_fnv1,
+ _testhashu64_fnv1,
+ _testhashs32_fnv1a,
+ _testhashu32_fnv1a,
+ _testhashs64_fnv1a,
+ _testhashu64_fnv1a,
+ _testarrayofbools,
+ _testf,
+ _testf2,
+ _testf3,
+ _testarrayofstring2,
+ _testarrayofsortedstruct,
+ _flex,
+ _test5,
+ _vector_of_longs,
+ _vector_of_doubles,
+ _parent_namespace_test,
+ _vector_of_referrables,
+ _single_weak_reference,
+ _vector_of_weak_references,
+ _vector_of_strong_referrables,
+ _co_owning_reference,
+ _vector_of_co_owning_references,
+ _non_owning_reference,
+ _vector_of_non_owning_references,
+ _any_unique_type,
+ _any_unique,
+ _any_ambiguous_type,
+ _any_ambiguous,
+ _vector_of_enums,
+ _signed_enum);
+}
+
+inline TypeAliasesT *TypeAliases::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ std::unique_ptr<MyGame::Example::TypeAliasesT> _o = std::unique_ptr<MyGame::Example::TypeAliasesT>(new TypeAliasesT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void TypeAliases::UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = i8(); _o->i8 = _e; }
+ { auto _e = u8(); _o->u8 = _e; }
+ { auto _e = i16(); _o->i16 = _e; }
+ { auto _e = u16(); _o->u16 = _e; }
+ { auto _e = i32(); _o->i32 = _e; }
+ { auto _e = u32(); _o->u32 = _e; }
+ { auto _e = i64(); _o->i64 = _e; }
+ { auto _e = u64(); _o->u64 = _e; }
+ { auto _e = f32(); _o->f32 = _e; }
+ { auto _e = f64(); _o->f64 = _e; }
+ { auto _e = v8(); if (_e) { _o->v8.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->v8[_i] = _e->Get(_i); } } }
+ { auto _e = vf64(); if (_e) { _o->vf64.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vf64[_i] = _e->Get(_i); } } }
+}
+
+inline flatbuffers::Offset<TypeAliases> TypeAliases::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateTypeAliases(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TypeAliasesT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _i8 = _o->i8;
+ auto _u8 = _o->u8;
+ auto _i16 = _o->i16;
+ auto _u16 = _o->u16;
+ auto _i32 = _o->i32;
+ auto _u32 = _o->u32;
+ auto _i64 = _o->i64;
+ auto _u64 = _o->u64;
+ auto _f32 = _o->f32;
+ auto _f64 = _o->f64;
+ auto _v8 = _o->v8.size() ? _fbb.CreateVector(_o->v8) : 0;
+ auto _vf64 = _o->vf64.size() ? _fbb.CreateVector(_o->vf64) : 0;
+ return MyGame::Example::CreateTypeAliases(
+ _fbb,
+ _i8,
+ _u8,
+ _i16,
+ _u16,
+ _i32,
+ _u32,
+ _i64,
+ _u64,
+ _f32,
+ _f64,
+ _v8,
+ _vf64);
+}
+
+inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type) {
+ switch (type) {
+ case Any::NONE: {
+ return true;
+ }
+ case Any::Monster: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case Any::TestSimpleTableWithEnum: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case Any::MyGame_Example2_Monster: {
+ auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ default: return true;
+ }
+}
+
+inline bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+ if (!values || !types) return !values && !types;
+ if (values->size() != types->size()) return false;
+ for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+ if (!VerifyAny(
+ verifier, values->Get(i), types->GetEnum<Any>(i))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline void *AnyUnion::UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver) {
+ switch (type) {
+ case Any::Monster: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ case Any::TestSimpleTableWithEnum: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ case Any::MyGame_Example2_Monster: {
+ auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ default: return nullptr;
+ }
+}
+
+inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+ switch (type) {
+ case Any::Monster: {
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+ return CreateMonster(_fbb, ptr, _rehasher).Union();
+ }
+ case Any::TestSimpleTableWithEnum: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
+ return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
+ }
+ case Any::MyGame_Example2_Monster: {
+ auto ptr = reinterpret_cast<const MyGame::Example2::MonsterT *>(value);
+ return CreateMonster(_fbb, ptr, _rehasher).Union();
+ }
+ default: return 0;
+ }
+}
+
+inline AnyUnion::AnyUnion(const AnyUnion &u) : type(u.type), value(nullptr) {
+ switch (type) {
+ case Any::Monster: {
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
+ break;
+ }
+ case Any::TestSimpleTableWithEnum: {
+ value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
+ break;
+ }
+ case Any::MyGame_Example2_Monster: {
+ value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+inline void AnyUnion::Reset() {
+ switch (type) {
+ case Any::Monster: {
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+ delete ptr;
+ break;
+ }
+ case Any::TestSimpleTableWithEnum: {
+ auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
+ delete ptr;
+ break;
+ }
+ case Any::MyGame_Example2_Monster: {
+ auto ptr = reinterpret_cast<MyGame::Example2::MonsterT *>(value);
+ delete ptr;
+ break;
+ }
+ default: break;
+ }
+ value = nullptr;
+ type = Any::NONE;
+}
+
+inline bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *obj, AnyUniqueAliases type) {
+ switch (type) {
+ case AnyUniqueAliases::NONE: {
+ return true;
+ }
+ case AnyUniqueAliases::M: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case AnyUniqueAliases::TS: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case AnyUniqueAliases::M2: {
+ auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ default: return true;
+ }
+}
+
+inline bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+ if (!values || !types) return !values && !types;
+ if (values->size() != types->size()) return false;
+ for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+ if (!VerifyAnyUniqueAliases(
+ verifier, values->Get(i), types->GetEnum<AnyUniqueAliases>(i))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline void *AnyUniqueAliasesUnion::UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver) {
+ switch (type) {
+ case AnyUniqueAliases::M: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ case AnyUniqueAliases::TS: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ case AnyUniqueAliases::M2: {
+ auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ default: return nullptr;
+ }
+}
+
+inline flatbuffers::Offset<void> AnyUniqueAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+ switch (type) {
+ case AnyUniqueAliases::M: {
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+ return CreateMonster(_fbb, ptr, _rehasher).Union();
+ }
+ case AnyUniqueAliases::TS: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
+ return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
+ }
+ case AnyUniqueAliases::M2: {
+ auto ptr = reinterpret_cast<const MyGame::Example2::MonsterT *>(value);
+ return CreateMonster(_fbb, ptr, _rehasher).Union();
+ }
+ default: return 0;
+ }
+}
+
+inline AnyUniqueAliasesUnion::AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &u) : type(u.type), value(nullptr) {
+ switch (type) {
+ case AnyUniqueAliases::M: {
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
+ break;
+ }
+ case AnyUniqueAliases::TS: {
+ value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
+ break;
+ }
+ case AnyUniqueAliases::M2: {
+ value = new MyGame::Example2::MonsterT(*reinterpret_cast<MyGame::Example2::MonsterT *>(u.value));
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+inline void AnyUniqueAliasesUnion::Reset() {
+ switch (type) {
+ case AnyUniqueAliases::M: {
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+ delete ptr;
+ break;
+ }
+ case AnyUniqueAliases::TS: {
+ auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
+ delete ptr;
+ break;
+ }
+ case AnyUniqueAliases::M2: {
+ auto ptr = reinterpret_cast<MyGame::Example2::MonsterT *>(value);
+ delete ptr;
+ break;
+ }
+ default: break;
+ }
+ value = nullptr;
+ type = AnyUniqueAliases::NONE;
+}
+
+inline bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const void *obj, AnyAmbiguousAliases type) {
+ switch (type) {
+ case AnyAmbiguousAliases::NONE: {
+ return true;
+ }
+ case AnyAmbiguousAliases::M1: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case AnyAmbiguousAliases::M2: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case AnyAmbiguousAliases::M3: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ default: return true;
+ }
+}
+
+inline bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+ if (!values || !types) return !values && !types;
+ if (values->size() != types->size()) return false;
+ for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+ if (!VerifyAnyAmbiguousAliases(
+ verifier, values->Get(i), types->GetEnum<AnyAmbiguousAliases>(i))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline void *AnyAmbiguousAliasesUnion::UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver) {
+ switch (type) {
+ case AnyAmbiguousAliases::M1: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ case AnyAmbiguousAliases::M2: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ case AnyAmbiguousAliases::M3: {
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
+ return ptr->UnPack(resolver);
+ }
+ default: return nullptr;
+ }
+}
+
+inline flatbuffers::Offset<void> AnyAmbiguousAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
+ switch (type) {
+ case AnyAmbiguousAliases::M1: {
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+ return CreateMonster(_fbb, ptr, _rehasher).Union();
+ }
+ case AnyAmbiguousAliases::M2: {
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+ return CreateMonster(_fbb, ptr, _rehasher).Union();
+ }
+ case AnyAmbiguousAliases::M3: {
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
+ return CreateMonster(_fbb, ptr, _rehasher).Union();
+ }
+ default: return 0;
+ }
+}
+
+inline AnyAmbiguousAliasesUnion::AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &u) : type(u.type), value(nullptr) {
+ switch (type) {
+ case AnyAmbiguousAliases::M1: {
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
+ break;
+ }
+ case AnyAmbiguousAliases::M2: {
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
+ break;
+ }
+ case AnyAmbiguousAliases::M3: {
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+inline void AnyAmbiguousAliasesUnion::Reset() {
+ switch (type) {
+ case AnyAmbiguousAliases::M1: {
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+ delete ptr;
+ break;
+ }
+ case AnyAmbiguousAliases::M2: {
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+ delete ptr;
+ break;
+ }
+ case AnyAmbiguousAliases::M3: {
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
+ delete ptr;
+ break;
+ }
+ default: break;
+ }
+ value = nullptr;
+ type = AnyAmbiguousAliases::NONE;
+}
+
+inline const flatbuffers::TypeTable *ColorTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_UCHAR, 0, 0 },
+ { flatbuffers::ET_UCHAR, 0, 0 },
+ { flatbuffers::ET_UCHAR, 0, 0 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::ColorTypeTable
+ };
+ static const int64_t values[] = { 1, 2, 8 };
+ static const char * const names[] = {
+ "Red",
+ "Green",
+ "Blue"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_ENUM, 3, type_codes, type_refs, values, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *RaceTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_CHAR, 0, 0 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::RaceTypeTable
+ };
+ static const int64_t values[] = { -1, 0, 1, 2 };
+ static const char * const names[] = {
+ "None",
+ "Human",
+ "Dwarf",
+ "Elf"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_ENUM, 4, type_codes, type_refs, values, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_SEQUENCE, 0, -1 },
+ { flatbuffers::ET_SEQUENCE, 0, 0 },
+ { flatbuffers::ET_SEQUENCE, 0, 1 },
+ { flatbuffers::ET_SEQUENCE, 0, 2 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::MonsterTypeTable,
+ MyGame::Example::TestSimpleTableWithEnumTypeTable,
+ MyGame::Example2::MonsterTypeTable
+ };
+ static const char * const names[] = {
+ "NONE",
+ "Monster",
+ "TestSimpleTableWithEnum",
+ "MyGame_Example2_Monster"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyUniqueAliasesTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_SEQUENCE, 0, -1 },
+ { flatbuffers::ET_SEQUENCE, 0, 0 },
+ { flatbuffers::ET_SEQUENCE, 0, 1 },
+ { flatbuffers::ET_SEQUENCE, 0, 2 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::MonsterTypeTable,
+ MyGame::Example::TestSimpleTableWithEnumTypeTable,
+ MyGame::Example2::MonsterTypeTable
+ };
+ static const char * const names[] = {
+ "NONE",
+ "M",
+ "TS",
+ "M2"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *AnyAmbiguousAliasesTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_SEQUENCE, 0, -1 },
+ { flatbuffers::ET_SEQUENCE, 0, 0 },
+ { flatbuffers::ET_SEQUENCE, 0, 0 },
+ { flatbuffers::ET_SEQUENCE, 0, 0 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::MonsterTypeTable
+ };
+ static const char * const names[] = {
+ "NONE",
+ "M1",
+ "M2",
+ "M3"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_UNION, 4, type_codes, type_refs, nullptr, names
+ };
+ return &tt;
+}
+
+} // namespace Example
+
+inline const flatbuffers::TypeTable *InParentNamespaceTypeTable() {
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
+ };
+ return &tt;
+}
+
+namespace Example2 {
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 0, nullptr, nullptr, nullptr, nullptr
+ };
+ return &tt;
+}
+
+} // namespace Example2
+
+namespace Example {
+
+inline const flatbuffers::TypeTable *TestTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_SHORT, 0, -1 },
+ { flatbuffers::ET_CHAR, 0, -1 }
+ };
+ static const int64_t values[] = { 0, 2, 4 };
+ static const char * const names[] = {
+ "a",
+ "b"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_UCHAR, 0, 0 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::ColorTypeTable
+ };
+ static const char * const names[] = {
+ "color"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *Vec3TypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_DOUBLE, 0, -1 },
+ { flatbuffers::ET_UCHAR, 0, 0 },
+ { flatbuffers::ET_SEQUENCE, 0, 1 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::ColorTypeTable,
+ MyGame::Example::TestTypeTable
+ };
+ static const int64_t values[] = { 0, 4, 8, 16, 24, 26, 32 };
+ static const char * const names[] = {
+ "x",
+ "y",
+ "z",
+ "test1",
+ "test2",
+ "test3"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_STRUCT, 6, type_codes, type_refs, values, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *AbilityTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_UINT, 0, -1 },
+ { flatbuffers::ET_UINT, 0, -1 }
+ };
+ static const int64_t values[] = { 0, 4, 8 };
+ static const char * const names[] = {
+ "id",
+ "distance"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_STRUCT, 2, type_codes, nullptr, values, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *StatTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_STRING, 0, -1 },
+ { flatbuffers::ET_LONG, 0, -1 },
+ { flatbuffers::ET_USHORT, 0, -1 }
+ };
+ static const char * const names[] = {
+ "id",
+ "val",
+ "count"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 3, type_codes, nullptr, nullptr, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *ReferrableTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_ULONG, 0, -1 }
+ };
+ static const char * const names[] = {
+ "id"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 1, type_codes, nullptr, nullptr, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *MonsterTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_SEQUENCE, 0, 0 },
+ { flatbuffers::ET_SHORT, 0, -1 },
+ { flatbuffers::ET_SHORT, 0, -1 },
+ { flatbuffers::ET_STRING, 0, -1 },
+ { flatbuffers::ET_BOOL, 0, -1 },
+ { flatbuffers::ET_UCHAR, 1, -1 },
+ { flatbuffers::ET_UCHAR, 0, 1 },
+ { flatbuffers::ET_UTYPE, 0, 2 },
+ { flatbuffers::ET_SEQUENCE, 0, 2 },
+ { flatbuffers::ET_SEQUENCE, 1, 3 },
+ { flatbuffers::ET_STRING, 1, -1 },
+ { flatbuffers::ET_SEQUENCE, 1, 4 },
+ { flatbuffers::ET_SEQUENCE, 0, 4 },
+ { flatbuffers::ET_UCHAR, 1, -1 },
+ { flatbuffers::ET_SEQUENCE, 0, 5 },
+ { flatbuffers::ET_BOOL, 0, -1 },
+ { flatbuffers::ET_INT, 0, -1 },
+ { flatbuffers::ET_UINT, 0, -1 },
+ { flatbuffers::ET_LONG, 0, -1 },
+ { flatbuffers::ET_ULONG, 0, -1 },
+ { flatbuffers::ET_INT, 0, -1 },
+ { flatbuffers::ET_UINT, 0, -1 },
+ { flatbuffers::ET_LONG, 0, -1 },
+ { flatbuffers::ET_ULONG, 0, -1 },
+ { flatbuffers::ET_BOOL, 1, -1 },
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_STRING, 1, -1 },
+ { flatbuffers::ET_SEQUENCE, 1, 6 },
+ { flatbuffers::ET_UCHAR, 1, -1 },
+ { flatbuffers::ET_SEQUENCE, 1, 3 },
+ { flatbuffers::ET_LONG, 1, -1 },
+ { flatbuffers::ET_DOUBLE, 1, -1 },
+ { flatbuffers::ET_SEQUENCE, 0, 7 },
+ { flatbuffers::ET_SEQUENCE, 1, 8 },
+ { flatbuffers::ET_ULONG, 0, -1 },
+ { flatbuffers::ET_ULONG, 1, -1 },
+ { flatbuffers::ET_SEQUENCE, 1, 8 },
+ { flatbuffers::ET_ULONG, 0, -1 },
+ { flatbuffers::ET_ULONG, 1, -1 },
+ { flatbuffers::ET_ULONG, 0, -1 },
+ { flatbuffers::ET_ULONG, 1, -1 },
+ { flatbuffers::ET_UTYPE, 0, 9 },
+ { flatbuffers::ET_SEQUENCE, 0, 9 },
+ { flatbuffers::ET_UTYPE, 0, 10 },
+ { flatbuffers::ET_SEQUENCE, 0, 10 },
+ { flatbuffers::ET_UCHAR, 1, 1 },
+ { flatbuffers::ET_CHAR, 0, 11 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::Vec3TypeTable,
+ MyGame::Example::ColorTypeTable,
+ MyGame::Example::AnyTypeTable,
+ MyGame::Example::TestTypeTable,
+ MyGame::Example::MonsterTypeTable,
+ MyGame::Example::StatTypeTable,
+ MyGame::Example::AbilityTypeTable,
+ MyGame::InParentNamespaceTypeTable,
+ MyGame::Example::ReferrableTypeTable,
+ MyGame::Example::AnyUniqueAliasesTypeTable,
+ MyGame::Example::AnyAmbiguousAliasesTypeTable,
+ MyGame::Example::RaceTypeTable
+ };
+ static const char * const names[] = {
+ "pos",
+ "mana",
+ "hp",
+ "name",
+ "friendly",
+ "inventory",
+ "color",
+ "test_type",
+ "test",
+ "test4",
+ "testarrayofstring",
+ "testarrayoftables",
+ "enemy",
+ "testnestedflatbuffer",
+ "testempty",
+ "testbool",
+ "testhashs32_fnv1",
+ "testhashu32_fnv1",
+ "testhashs64_fnv1",
+ "testhashu64_fnv1",
+ "testhashs32_fnv1a",
+ "testhashu32_fnv1a",
+ "testhashs64_fnv1a",
+ "testhashu64_fnv1a",
+ "testarrayofbools",
+ "testf",
+ "testf2",
+ "testf3",
+ "testarrayofstring2",
+ "testarrayofsortedstruct",
+ "flex",
+ "test5",
+ "vector_of_longs",
+ "vector_of_doubles",
+ "parent_namespace_test",
+ "vector_of_referrables",
+ "single_weak_reference",
+ "vector_of_weak_references",
+ "vector_of_strong_referrables",
+ "co_owning_reference",
+ "vector_of_co_owning_references",
+ "non_owning_reference",
+ "vector_of_non_owning_references",
+ "any_unique_type",
+ "any_unique",
+ "any_ambiguous_type",
+ "any_ambiguous",
+ "vector_of_enums",
+ "signed_enum"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 49, type_codes, type_refs, nullptr, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *TypeAliasesTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_CHAR, 0, -1 },
+ { flatbuffers::ET_UCHAR, 0, -1 },
+ { flatbuffers::ET_SHORT, 0, -1 },
+ { flatbuffers::ET_USHORT, 0, -1 },
+ { flatbuffers::ET_INT, 0, -1 },
+ { flatbuffers::ET_UINT, 0, -1 },
+ { flatbuffers::ET_LONG, 0, -1 },
+ { flatbuffers::ET_ULONG, 0, -1 },
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_DOUBLE, 0, -1 },
+ { flatbuffers::ET_CHAR, 1, -1 },
+ { flatbuffers::ET_DOUBLE, 1, -1 }
+ };
+ static const char * const names[] = {
+ "i8",
+ "u8",
+ "i16",
+ "u16",
+ "i32",
+ "u32",
+ "i64",
+ "u64",
+ "f32",
+ "f64",
+ "v8",
+ "vf64"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 12, type_codes, nullptr, nullptr, names
+ };
+ return &tt;
+}
+
+inline const MyGame::Example::Monster *GetMonster(const void *buf) {
+ return flatbuffers::GetRoot<MyGame::Example::Monster>(buf);
+}
+
+inline const MyGame::Example::Monster *GetSizePrefixedMonster(const void *buf) {
+ return flatbuffers::GetSizePrefixedRoot<MyGame::Example::Monster>(buf);
+}
+
+inline Monster *GetMutableMonster(void *buf) {
+ return flatbuffers::GetMutableRoot<Monster>(buf);
+}
+
+inline const char *MonsterIdentifier() {
+ return "MONS";
+}
+
+inline bool MonsterBufferHasIdentifier(const void *buf) {
+ return flatbuffers::BufferHasIdentifier(
+ buf, MonsterIdentifier());
+}
+
+inline bool VerifyMonsterBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifyBuffer<MyGame::Example::Monster>(MonsterIdentifier());
+}
+
+inline bool VerifySizePrefixedMonsterBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifySizePrefixedBuffer<MyGame::Example::Monster>(MonsterIdentifier());
+}
+
+inline const char *MonsterExtension() {
+ return "mon";
+}
+
+inline void FinishMonsterBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<MyGame::Example::Monster> root) {
+ fbb.Finish(root, MonsterIdentifier());
+}
+
+inline void FinishSizePrefixedMonsterBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<MyGame::Example::Monster> root) {
+ fbb.FinishSizePrefixed(root, MonsterIdentifier());
+}
+
+inline std::unique_ptr<MyGame::Example::MonsterT> UnPackMonster(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return std::unique_ptr<MyGame::Example::MonsterT>(GetMonster(buf)->UnPack(res));
+}
+
+inline std::unique_ptr<MyGame::Example::MonsterT> UnPackSizePrefixedMonster(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return std::unique_ptr<MyGame::Example::MonsterT>(GetSizePrefixedMonster(buf)->UnPack(res));
+}
+
+} // namespace Example
+} // namespace MyGame
+
+#endif // FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_H_
diff --git a/tests/cpp17/test_cpp17.cpp b/tests/cpp17/test_cpp17.cpp
new file mode 100644
index 00000000..91390bda
--- /dev/null
+++ b/tests/cpp17/test_cpp17.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014 Google Inc. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// This is a sandbox for modeling C++17 code generator.
+// C++17 code generator: "flatc --cpp_std c++17".
+// Warning:
+// This is an experimental feature and could change at any time.
+
+#include "flatbuffers/flatbuffers.h"
+#include "flatbuffers/flexbuffers.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/minireflect.h"
+#include "flatbuffers/registry.h"
+#include "flatbuffers/util.h"
+#include "test_assert.h"
+
+// Embed generated code into an isolated namespace.
+namespace cpp17 {
+#include "generated_cpp17/monster_test_generated.h"
+} // namespace cpp17
+
+namespace cpp11 {
+#include "../monster_test_generated.h"
+} // namespace cpp11
+
+void CreateTableByTypeTest() {
+ flatbuffers::FlatBufferBuilder builder;
+
+ // We will create an object of this type using only the type.
+ using type_to_create_t = cpp17::MyGame::Example::Stat;
+
+ [&builder] {
+ auto id_str = builder.CreateString("my_id");
+ auto table = type_to_create_t::Traits::Create(builder, id_str, 42, 7);
+ // Be sure that the correct return type was inferred.
+ static_assert(
+ std::is_same_v<decltype(table), flatbuffers::Offset<type_to_create_t>>);
+ builder.Finish(table);
+ }();
+
+ // Access it.
+ auto stat =
+ flatbuffers::GetRoot<type_to_create_t>(builder.GetBufferPointer());
+ TEST_EQ_STR(stat->id()->c_str(), "my_id");
+ TEST_EQ(stat->val(), 42);
+ TEST_EQ(stat->count(), 7);
+}
+
+int FlatBufferCpp17Tests() {
+ CreateTableByTypeTest();
+ return 0;
+}
+
+int main(int /*argc*/, const char * /*argv*/[]) {
+ InitTestEngine();
+
+ FlatBufferCpp17Tests();
+
+ if (!testing_fails) {
+ TEST_OUTPUT_LINE("C++17: ALL TESTS PASSED");
+ } else {
+ TEST_OUTPUT_LINE("C++17: %d FAILED TESTS", testing_fails);
+ }
+ return CloseTestEngine();
+}
diff --git a/tests/docker/Dockerfile.testing.cpp.debian_buster b/tests/docker/Dockerfile.testing.cpp.debian_buster
new file mode 100644
index 00000000..7b0cce2d
--- /dev/null
+++ b/tests/docker/Dockerfile.testing.cpp.debian_buster
@@ -0,0 +1,10 @@
+FROM debian:10.1-slim as base
+RUN apt -qq update >/dev/null
+RUN apt -qq install -y cmake make build-essential >/dev/null
+RUN apt -qq install -y autoconf git libtool >/dev/null
+RUN apt -qq install -y clang >/dev/null
+FROM base
+# Travis machines have 2 cores. Can be redefined with 'run --env PAR_JOBS=N'.
+ENV JOBS=2
+WORKDIR /flatbuffers
+ADD . .
diff --git a/tests/docker/build_flatc.run.sh b/tests/docker/build_flatc.run.sh
new file mode 100755
index 00000000..c8885b19
--- /dev/null
+++ b/tests/docker/build_flatc.run.sh
@@ -0,0 +1,15 @@
+set -e
+
+JOBS=${JOBS:-1}
+config=$1
+echo ""
+echo "Build 'flatc' compiler for '$config'"
+
+cmake . -DCMAKE_BUILD_TYPE=$config \
+ -DFLATBUFFERS_BUILD_FLATC=1 -DFLATBUFFERS_STATIC_FLATC=1 \
+ -DFLATBUFFERS_BUILD_TESTS=0 -DFLATBUFFERS_INSTALL=0
+cmake --build . --target flatc --clean-first -- -j$JOBS
+
+echo "Check generated code"
+.travis/check-generate-code.sh
+echo "Done"
diff --git a/tests/docker/cpp_test.run.sh b/tests/docker/cpp_test.run.sh
new file mode 100755
index 00000000..fa3b0fb1
--- /dev/null
+++ b/tests/docker/cpp_test.run.sh
@@ -0,0 +1,20 @@
+set -e
+
+JOBS=${JOBS:-1}
+export UBSAN_OPTIONS=halt_on_error=1
+export ASAN_OPTIONS=halt_on_error=1
+export MAKEFLAGS="-j$JOBS"
+
+config=$1
+echo ""
+echo "Build Flatbuffers project for '$config' with jobs=$JOBS"
+
+cmake . -DCMAKE_BUILD_TYPE=$config \
+ -DFLATBUFFERS_BUILD_TESTS=ON -DFLATBUFFERS_CODE_SANITIZE=ON
+cmake --build . --target all --clean-first -- -j$JOBS
+ctest --extra-verbose --output-on-failure -j$JOBS
+
+echo "Check generated code"
+.travis/check-generate-code.sh
+
+echo "C++ tests done"
diff --git a/tests/docker/languages/Dockerfile.testing.python.numpy.cpython_2_7_15 b/tests/docker/languages/Dockerfile.testing.python.numpy.cpython_2_7_15
new file mode 100644
index 00000000..718c5ac5
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.python.numpy.cpython_2_7_15
@@ -0,0 +1,9 @@
+FROM python:2.7.15-slim-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN python --version
+RUN pip install numpy
+RUN pip install coverage
+RUN ./PythonTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.python.numpy.cpython_3_7_1 b/tests/docker/languages/Dockerfile.testing.python.numpy.cpython_3_7_1
new file mode 100644
index 00000000..1de2c268
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.python.numpy.cpython_3_7_1
@@ -0,0 +1,9 @@
+FROM python:3.7.1-slim-stretch as base
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN python --version
+RUN pip install numpy
+RUN pip install coverage
+RUN ./PythonTest.sh
diff --git a/tests/docker/languages/Dockerfile.testing.rust.1_30_1 b/tests/docker/languages/Dockerfile.testing.rust.1_37_0
index 4d1755c6..522937b8 100644
--- a/tests/docker/languages/Dockerfile.testing.rust.1_30_1
+++ b/tests/docker/languages/Dockerfile.testing.rust.1_37_0
@@ -1,4 +1,4 @@
-FROM rust:1.30.1-slim-stretch as base
+FROM rust:1.37.0-slim-stretch as base
WORKDIR /code
ADD . .
RUN cp flatc_debian_stretch flatc
diff --git a/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1 b/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_37_0
index f2e93f4e..eae0fe14 100644
--- a/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_30_1
+++ b/tests/docker/languages/Dockerfile.testing.rust.big_endian.1_37_0
@@ -1,4 +1,4 @@
-FROM rust:1.30.1-slim-stretch as base
+FROM rust:1.37.0-slim-stretch as base
RUN apt -qq update -y && apt -qq install -y \
gcc-mips-linux-gnu \
libexpat1 \
diff --git a/tests/docker/languages/Dockerfile.testing.swift_5_1 b/tests/docker/languages/Dockerfile.testing.swift_5_1
new file mode 100644
index 00000000..e98e4be1
--- /dev/null
+++ b/tests/docker/languages/Dockerfile.testing.swift_5_1
@@ -0,0 +1,8 @@
+FROM swift:5.1
+WORKDIR /code
+ADD . .
+RUN cp flatc_debian_stretch flatc
+WORKDIR /code/tests
+RUN swift --version
+WORKDIR /code/tests/FlatBuffers.Test.Swift
+RUN sh SwiftTest.sh
diff --git a/tests/evolution_test/evolution_v1.fbs b/tests/evolution_test/evolution_v1.fbs
new file mode 100644
index 00000000..2576c879
--- /dev/null
+++ b/tests/evolution_test/evolution_v1.fbs
@@ -0,0 +1,39 @@
+namespace Evolution.V1;
+
+table TableA {
+ a:float;
+ b:int;
+}
+
+table TableB {
+ a:int;
+}
+
+enum Enum : byte {
+ King,
+ Queen
+}
+
+union Union {
+ TableA,
+ TableB
+}
+
+struct Struct {
+ a:int;
+ b:double;
+}
+
+table Root {
+ a:int;
+ b:bool;
+ c:Union;
+ d:Enum;
+ e:TableA;
+ f:Struct;
+ g:[int];
+ h:[TableB];
+ i:int = 1234;
+}
+
+root_type Root; \ No newline at end of file
diff --git a/tests/evolution_test/evolution_v1.json b/tests/evolution_test/evolution_v1.json
new file mode 100644
index 00000000..8b4b3522
--- /dev/null
+++ b/tests/evolution_test/evolution_v1.json
@@ -0,0 +1,26 @@
+{
+ "a": 42,
+ "b": true,
+ "c_type": "TableB",
+ "c": {
+ "a": 15
+ },
+ "d": "King",
+ "e": {
+ "a": 3.1452,
+ "b": 325
+ },
+ "f":{
+ "a": 16,
+ "b": 243.980943
+ },
+ "g": [ 7, 8, 9],
+ "h": [
+ {
+ "a": 212
+ },
+ {
+ "a": 459
+ }
+ ]
+} \ No newline at end of file
diff --git a/tests/evolution_test/evolution_v1_generated.h b/tests/evolution_test/evolution_v1_generated.h
new file mode 100644
index 00000000..1d447ffc
--- /dev/null
+++ b/tests/evolution_test/evolution_v1_generated.h
@@ -0,0 +1,453 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_
+#define FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace Evolution {
+namespace V1 {
+
+struct TableA;
+
+struct TableB;
+
+struct Struct;
+
+struct Root;
+
+enum class Enum : int8_t {
+ King = 0,
+ Queen = 1,
+ MIN = King,
+ MAX = Queen
+};
+
+inline const Enum (&EnumValuesEnum())[2] {
+ static const Enum values[] = {
+ Enum::King,
+ Enum::Queen
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesEnum() {
+ static const char * const names[3] = {
+ "King",
+ "Queen",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameEnum(Enum e) {
+ if (e < Enum::King || e > Enum::Queen) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesEnum()[index];
+}
+
+enum class Union : uint8_t {
+ NONE = 0,
+ TableA = 1,
+ TableB = 2,
+ MIN = NONE,
+ MAX = TableB
+};
+
+inline const Union (&EnumValuesUnion())[3] {
+ static const Union values[] = {
+ Union::NONE,
+ Union::TableA,
+ Union::TableB
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesUnion() {
+ static const char * const names[4] = {
+ "NONE",
+ "TableA",
+ "TableB",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameUnion(Union e) {
+ if (e < Union::NONE || e > Union::TableB) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesUnion()[index];
+}
+
+template<typename T> struct UnionTraits {
+ static const Union enum_value = Union::NONE;
+};
+
+template<> struct UnionTraits<Evolution::V1::TableA> {
+ static const Union enum_value = Union::TableA;
+};
+
+template<> struct UnionTraits<Evolution::V1::TableB> {
+ static const Union enum_value = Union::TableB;
+};
+
+bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type);
+bool VerifyUnionVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS {
+ private:
+ int32_t a_;
+ int32_t padding0__;
+ double b_;
+
+ public:
+ Struct() {
+ memset(static_cast<void *>(this), 0, sizeof(Struct));
+ }
+ Struct(int32_t _a, double _b)
+ : a_(flatbuffers::EndianScalar(_a)),
+ padding0__(0),
+ b_(flatbuffers::EndianScalar(_b)) {
+ (void)padding0__;
+ }
+ int32_t a() const {
+ return flatbuffers::EndianScalar(a_);
+ }
+ double b() const {
+ return flatbuffers::EndianScalar(b_);
+ }
+};
+FLATBUFFERS_STRUCT_END(Struct, 16);
+
+struct TableA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_A = 4,
+ VT_B = 6
+ };
+ float a() const {
+ return GetField<float>(VT_A, 0.0f);
+ }
+ int32_t b() const {
+ return GetField<int32_t>(VT_B, 0);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<float>(verifier, VT_A) &&
+ VerifyField<int32_t>(verifier, VT_B) &&
+ verifier.EndTable();
+ }
+};
+
+struct TableABuilder {
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_a(float a) {
+ fbb_.AddElement<float>(TableA::VT_A, a, 0.0f);
+ }
+ void add_b(int32_t b) {
+ fbb_.AddElement<int32_t>(TableA::VT_B, b, 0);
+ }
+ explicit TableABuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ TableABuilder &operator=(const TableABuilder &);
+ flatbuffers::Offset<TableA> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<TableA>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<TableA> CreateTableA(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ float a = 0.0f,
+ int32_t b = 0) {
+ TableABuilder builder_(_fbb);
+ builder_.add_b(b);
+ builder_.add_a(a);
+ return builder_.Finish();
+}
+
+struct TableB FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_A = 4
+ };
+ int32_t a() const {
+ return GetField<int32_t>(VT_A, 0);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<int32_t>(verifier, VT_A) &&
+ verifier.EndTable();
+ }
+};
+
+struct TableBBuilder {
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_a(int32_t a) {
+ fbb_.AddElement<int32_t>(TableB::VT_A, a, 0);
+ }
+ explicit TableBBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ TableBBuilder &operator=(const TableBBuilder &);
+ flatbuffers::Offset<TableB> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<TableB>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<TableB> CreateTableB(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ int32_t a = 0) {
+ TableBBuilder builder_(_fbb);
+ builder_.add_a(a);
+ return builder_.Finish();
+}
+
+struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_A = 4,
+ VT_B = 6,
+ VT_C_TYPE = 8,
+ VT_C = 10,
+ VT_D = 12,
+ VT_E = 14,
+ VT_F = 16,
+ VT_G = 18,
+ VT_H = 20,
+ VT_I = 22
+ };
+ int32_t a() const {
+ return GetField<int32_t>(VT_A, 0);
+ }
+ bool b() const {
+ return GetField<uint8_t>(VT_B, 0) != 0;
+ }
+ Evolution::V1::Union c_type() const {
+ return static_cast<Evolution::V1::Union>(GetField<uint8_t>(VT_C_TYPE, 0));
+ }
+ const void *c() const {
+ return GetPointer<const void *>(VT_C);
+ }
+ template<typename T> const T *c_as() const;
+ const Evolution::V1::TableA *c_as_TableA() const {
+ return c_type() == Evolution::V1::Union::TableA ? static_cast<const Evolution::V1::TableA *>(c()) : nullptr;
+ }
+ const Evolution::V1::TableB *c_as_TableB() const {
+ return c_type() == Evolution::V1::Union::TableB ? static_cast<const Evolution::V1::TableB *>(c()) : nullptr;
+ }
+ Evolution::V1::Enum d() const {
+ return static_cast<Evolution::V1::Enum>(GetField<int8_t>(VT_D, 0));
+ }
+ const Evolution::V1::TableA *e() const {
+ return GetPointer<const Evolution::V1::TableA *>(VT_E);
+ }
+ const Evolution::V1::Struct *f() const {
+ return GetStruct<const Evolution::V1::Struct *>(VT_F);
+ }
+ const flatbuffers::Vector<int32_t> *g() const {
+ return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_G);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>> *h() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>> *>(VT_H);
+ }
+ int32_t i() const {
+ return GetField<int32_t>(VT_I, 1234);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<int32_t>(verifier, VT_A) &&
+ VerifyField<uint8_t>(verifier, VT_B) &&
+ VerifyField<uint8_t>(verifier, VT_C_TYPE) &&
+ VerifyOffset(verifier, VT_C) &&
+ VerifyUnion(verifier, c(), c_type()) &&
+ VerifyField<int8_t>(verifier, VT_D) &&
+ VerifyOffset(verifier, VT_E) &&
+ verifier.VerifyTable(e()) &&
+ VerifyField<Evolution::V1::Struct>(verifier, VT_F) &&
+ VerifyOffset(verifier, VT_G) &&
+ verifier.VerifyVector(g()) &&
+ VerifyOffset(verifier, VT_H) &&
+ verifier.VerifyVector(h()) &&
+ verifier.VerifyVectorOfTables(h()) &&
+ VerifyField<int32_t>(verifier, VT_I) &&
+ verifier.EndTable();
+ }
+};
+
+template<> inline const Evolution::V1::TableA *Root::c_as<Evolution::V1::TableA>() const {
+ return c_as_TableA();
+}
+
+template<> inline const Evolution::V1::TableB *Root::c_as<Evolution::V1::TableB>() const {
+ return c_as_TableB();
+}
+
+struct RootBuilder {
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_a(int32_t a) {
+ fbb_.AddElement<int32_t>(Root::VT_A, a, 0);
+ }
+ void add_b(bool b) {
+ fbb_.AddElement<uint8_t>(Root::VT_B, static_cast<uint8_t>(b), 0);
+ }
+ void add_c_type(Evolution::V1::Union c_type) {
+ fbb_.AddElement<uint8_t>(Root::VT_C_TYPE, static_cast<uint8_t>(c_type), 0);
+ }
+ void add_c(flatbuffers::Offset<void> c) {
+ fbb_.AddOffset(Root::VT_C, c);
+ }
+ void add_d(Evolution::V1::Enum d) {
+ fbb_.AddElement<int8_t>(Root::VT_D, static_cast<int8_t>(d), 0);
+ }
+ void add_e(flatbuffers::Offset<Evolution::V1::TableA> e) {
+ fbb_.AddOffset(Root::VT_E, e);
+ }
+ void add_f(const Evolution::V1::Struct *f) {
+ fbb_.AddStruct(Root::VT_F, f);
+ }
+ void add_g(flatbuffers::Offset<flatbuffers::Vector<int32_t>> g) {
+ fbb_.AddOffset(Root::VT_G, g);
+ }
+ void add_h(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>>> h) {
+ fbb_.AddOffset(Root::VT_H, h);
+ }
+ void add_i(int32_t i) {
+ fbb_.AddElement<int32_t>(Root::VT_I, i, 1234);
+ }
+ explicit RootBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ RootBuilder &operator=(const RootBuilder &);
+ flatbuffers::Offset<Root> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Root>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Root> CreateRoot(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ int32_t a = 0,
+ bool b = false,
+ Evolution::V1::Union c_type = Evolution::V1::Union::NONE,
+ flatbuffers::Offset<void> c = 0,
+ Evolution::V1::Enum d = Evolution::V1::Enum::King,
+ flatbuffers::Offset<Evolution::V1::TableA> e = 0,
+ const Evolution::V1::Struct *f = 0,
+ flatbuffers::Offset<flatbuffers::Vector<int32_t>> g = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>>> h = 0,
+ int32_t i = 1234) {
+ RootBuilder builder_(_fbb);
+ builder_.add_i(i);
+ builder_.add_h(h);
+ builder_.add_g(g);
+ builder_.add_f(f);
+ builder_.add_e(e);
+ builder_.add_c(c);
+ builder_.add_a(a);
+ builder_.add_d(d);
+ builder_.add_c_type(c_type);
+ builder_.add_b(b);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Root> CreateRootDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ int32_t a = 0,
+ bool b = false,
+ Evolution::V1::Union c_type = Evolution::V1::Union::NONE,
+ flatbuffers::Offset<void> c = 0,
+ Evolution::V1::Enum d = Evolution::V1::Enum::King,
+ flatbuffers::Offset<Evolution::V1::TableA> e = 0,
+ const Evolution::V1::Struct *f = 0,
+ const std::vector<int32_t> *g = nullptr,
+ const std::vector<flatbuffers::Offset<Evolution::V1::TableB>> *h = nullptr,
+ int32_t i = 1234) {
+ auto g__ = g ? _fbb.CreateVector<int32_t>(*g) : 0;
+ auto h__ = h ? _fbb.CreateVector<flatbuffers::Offset<Evolution::V1::TableB>>(*h) : 0;
+ return Evolution::V1::CreateRoot(
+ _fbb,
+ a,
+ b,
+ c_type,
+ c,
+ d,
+ e,
+ f,
+ g__,
+ h__,
+ i);
+}
+
+inline bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type) {
+ switch (type) {
+ case Union::NONE: {
+ return true;
+ }
+ case Union::TableA: {
+ auto ptr = reinterpret_cast<const Evolution::V1::TableA *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case Union::TableB: {
+ auto ptr = reinterpret_cast<const Evolution::V1::TableB *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ default: return true;
+ }
+}
+
+inline bool VerifyUnionVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+ if (!values || !types) return !values && !types;
+ if (values->size() != types->size()) return false;
+ for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+ if (!VerifyUnion(
+ verifier, values->Get(i), types->GetEnum<Union>(i))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline const Evolution::V1::Root *GetRoot(const void *buf) {
+ return flatbuffers::GetRoot<Evolution::V1::Root>(buf);
+}
+
+inline const Evolution::V1::Root *GetSizePrefixedRoot(const void *buf) {
+ return flatbuffers::GetSizePrefixedRoot<Evolution::V1::Root>(buf);
+}
+
+inline bool VerifyRootBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifyBuffer<Evolution::V1::Root>(nullptr);
+}
+
+inline bool VerifySizePrefixedRootBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifySizePrefixedBuffer<Evolution::V1::Root>(nullptr);
+}
+
+inline void FinishRootBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<Evolution::V1::Root> root) {
+ fbb.Finish(root);
+}
+
+inline void FinishSizePrefixedRootBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<Evolution::V1::Root> root) {
+ fbb.FinishSizePrefixed(root);
+}
+
+} // namespace V1
+} // namespace Evolution
+
+#endif // FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_
diff --git a/tests/evolution_test/evolution_v2.fbs b/tests/evolution_test/evolution_v2.fbs
new file mode 100644
index 00000000..5f4601e6
--- /dev/null
+++ b/tests/evolution_test/evolution_v2.fbs
@@ -0,0 +1,50 @@
+namespace Evolution.V2;
+
+table TableA {
+ b:int (id: 1); // swapped with 'a'
+ a:float (id: 0); // swapped with 'b'
+ c:string (id: 2); // new in v2
+}
+
+table TableB {
+ a:int;
+}
+
+table TableC { // new in v2
+ a:double;
+ b:string;
+}
+
+enum Enum : byte {
+ King,
+ Queen,
+ Rook, // new in v2
+ Bishop // new in v2
+}
+
+union Union {
+ TableA,
+ TableB,
+ TableC
+}
+
+struct Struct {
+ a:int;
+ b:double;
+}
+
+table Root {
+ a:int (deprecated); // deprecated in v2
+ b:bool;
+ c:Union;
+ d:Enum;
+ e:TableA;
+ ff:Struct; // renamed from 'f' in v1
+ g:[int];
+ h:[TableB];
+ i:uint = 1234;
+ j:TableC; // new in v2
+ k:uint8 = 56; // new in v2
+}
+
+root_type Root; \ No newline at end of file
diff --git a/tests/evolution_test/evolution_v2.json b/tests/evolution_test/evolution_v2.json
new file mode 100644
index 00000000..625f5060
--- /dev/null
+++ b/tests/evolution_test/evolution_v2.json
@@ -0,0 +1,34 @@
+{
+ "b": false,
+ "c_type": "TableC",
+ "c": {
+ "a": 984.2494
+ },
+ "d": "Bishop",
+ "e": {
+ "a": 3.1452,
+ "b": 435,
+ "c": "yummy yummy fig bar bar"
+ },
+ "ff":{
+ "a": 35,
+ "b": 243.980943
+ },
+ "g": [ 7, 8, 10],
+ "h": [
+ {
+ "a": 212
+ },
+ {
+ "a": 459
+ },
+ {
+ "a": 333
+ }
+ ],
+ "i": 4321,
+ "j": {
+ "a": 9874.342,
+ "b": "more please"
+ }
+}
diff --git a/tests/evolution_test/evolution_v2_generated.h b/tests/evolution_test/evolution_v2_generated.h
new file mode 100644
index 00000000..4e1b8404
--- /dev/null
+++ b/tests/evolution_test/evolution_v2_generated.h
@@ -0,0 +1,578 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_H_
+#define FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+namespace Evolution {
+namespace V2 {
+
+struct TableA;
+
+struct TableB;
+
+struct TableC;
+
+struct Struct;
+
+struct Root;
+
+enum class Enum : int8_t {
+ King = 0,
+ Queen = 1,
+ Rook = 2,
+ Bishop = 3,
+ MIN = King,
+ MAX = Bishop
+};
+
+inline const Enum (&EnumValuesEnum())[4] {
+ static const Enum values[] = {
+ Enum::King,
+ Enum::Queen,
+ Enum::Rook,
+ Enum::Bishop
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesEnum() {
+ static const char * const names[5] = {
+ "King",
+ "Queen",
+ "Rook",
+ "Bishop",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameEnum(Enum e) {
+ if (e < Enum::King || e > Enum::Bishop) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesEnum()[index];
+}
+
+enum class Union : uint8_t {
+ NONE = 0,
+ TableA = 1,
+ TableB = 2,
+ TableC = 3,
+ MIN = NONE,
+ MAX = TableC
+};
+
+inline const Union (&EnumValuesUnion())[4] {
+ static const Union values[] = {
+ Union::NONE,
+ Union::TableA,
+ Union::TableB,
+ Union::TableC
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesUnion() {
+ static const char * const names[5] = {
+ "NONE",
+ "TableA",
+ "TableB",
+ "TableC",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameUnion(Union e) {
+ if (e < Union::NONE || e > Union::TableC) return "";
+ const size_t index = static_cast<size_t>(e);
+ return EnumNamesUnion()[index];
+}
+
+template<typename T> struct UnionTraits {
+ static const Union enum_value = Union::NONE;
+};
+
+template<> struct UnionTraits<Evolution::V2::TableA> {
+ static const Union enum_value = Union::TableA;
+};
+
+template<> struct UnionTraits<Evolution::V2::TableB> {
+ static const Union enum_value = Union::TableB;
+};
+
+template<> struct UnionTraits<Evolution::V2::TableC> {
+ static const Union enum_value = Union::TableC;
+};
+
+bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type);
+bool VerifyUnionVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS {
+ private:
+ int32_t a_;
+ int32_t padding0__;
+ double b_;
+
+ public:
+ Struct() {
+ memset(static_cast<void *>(this), 0, sizeof(Struct));
+ }
+ Struct(int32_t _a, double _b)
+ : a_(flatbuffers::EndianScalar(_a)),
+ padding0__(0),
+ b_(flatbuffers::EndianScalar(_b)) {
+ (void)padding0__;
+ }
+ int32_t a() const {
+ return flatbuffers::EndianScalar(a_);
+ }
+ double b() const {
+ return flatbuffers::EndianScalar(b_);
+ }
+};
+FLATBUFFERS_STRUCT_END(Struct, 16);
+
+struct TableA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_A = 4,
+ VT_B = 6,
+ VT_C = 8
+ };
+ float a() const {
+ return GetField<float>(VT_A, 0.0f);
+ }
+ int32_t b() const {
+ return GetField<int32_t>(VT_B, 0);
+ }
+ const flatbuffers::String *c() const {
+ return GetPointer<const flatbuffers::String *>(VT_C);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<float>(verifier, VT_A) &&
+ VerifyField<int32_t>(verifier, VT_B) &&
+ VerifyOffset(verifier, VT_C) &&
+ verifier.VerifyString(c()) &&
+ verifier.EndTable();
+ }
+};
+
+struct TableABuilder {
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_a(float a) {
+ fbb_.AddElement<float>(TableA::VT_A, a, 0.0f);
+ }
+ void add_b(int32_t b) {
+ fbb_.AddElement<int32_t>(TableA::VT_B, b, 0);
+ }
+ void add_c(flatbuffers::Offset<flatbuffers::String> c) {
+ fbb_.AddOffset(TableA::VT_C, c);
+ }
+ explicit TableABuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ TableABuilder &operator=(const TableABuilder &);
+ flatbuffers::Offset<TableA> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<TableA>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<TableA> CreateTableA(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ float a = 0.0f,
+ int32_t b = 0,
+ flatbuffers::Offset<flatbuffers::String> c = 0) {
+ TableABuilder builder_(_fbb);
+ builder_.add_c(c);
+ builder_.add_b(b);
+ builder_.add_a(a);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<TableA> CreateTableADirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ float a = 0.0f,
+ int32_t b = 0,
+ const char *c = nullptr) {
+ auto c__ = c ? _fbb.CreateString(c) : 0;
+ return Evolution::V2::CreateTableA(
+ _fbb,
+ a,
+ b,
+ c__);
+}
+
+struct TableB FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_A = 4
+ };
+ int32_t a() const {
+ return GetField<int32_t>(VT_A, 0);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<int32_t>(verifier, VT_A) &&
+ verifier.EndTable();
+ }
+};
+
+struct TableBBuilder {
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_a(int32_t a) {
+ fbb_.AddElement<int32_t>(TableB::VT_A, a, 0);
+ }
+ explicit TableBBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ TableBBuilder &operator=(const TableBBuilder &);
+ flatbuffers::Offset<TableB> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<TableB>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<TableB> CreateTableB(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ int32_t a = 0) {
+ TableBBuilder builder_(_fbb);
+ builder_.add_a(a);
+ return builder_.Finish();
+}
+
+struct TableC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_A = 4,
+ VT_B = 6
+ };
+ double a() const {
+ return GetField<double>(VT_A, 0.0);
+ }
+ const flatbuffers::String *b() const {
+ return GetPointer<const flatbuffers::String *>(VT_B);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<double>(verifier, VT_A) &&
+ VerifyOffset(verifier, VT_B) &&
+ verifier.VerifyString(b()) &&
+ verifier.EndTable();
+ }
+};
+
+struct TableCBuilder {
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_a(double a) {
+ fbb_.AddElement<double>(TableC::VT_A, a, 0.0);
+ }
+ void add_b(flatbuffers::Offset<flatbuffers::String> b) {
+ fbb_.AddOffset(TableC::VT_B, b);
+ }
+ explicit TableCBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ TableCBuilder &operator=(const TableCBuilder &);
+ flatbuffers::Offset<TableC> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<TableC>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<TableC> CreateTableC(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ double a = 0.0,
+ flatbuffers::Offset<flatbuffers::String> b = 0) {
+ TableCBuilder builder_(_fbb);
+ builder_.add_a(a);
+ builder_.add_b(b);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<TableC> CreateTableCDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ double a = 0.0,
+ const char *b = nullptr) {
+ auto b__ = b ? _fbb.CreateString(b) : 0;
+ return Evolution::V2::CreateTableC(
+ _fbb,
+ a,
+ b__);
+}
+
+struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_B = 6,
+ VT_C_TYPE = 8,
+ VT_C = 10,
+ VT_D = 12,
+ VT_E = 14,
+ VT_FF = 16,
+ VT_G = 18,
+ VT_H = 20,
+ VT_I = 22,
+ VT_J = 24,
+ VT_K = 26
+ };
+ bool b() const {
+ return GetField<uint8_t>(VT_B, 0) != 0;
+ }
+ Evolution::V2::Union c_type() const {
+ return static_cast<Evolution::V2::Union>(GetField<uint8_t>(VT_C_TYPE, 0));
+ }
+ const void *c() const {
+ return GetPointer<const void *>(VT_C);
+ }
+ template<typename T> const T *c_as() const;
+ const Evolution::V2::TableA *c_as_TableA() const {
+ return c_type() == Evolution::V2::Union::TableA ? static_cast<const Evolution::V2::TableA *>(c()) : nullptr;
+ }
+ const Evolution::V2::TableB *c_as_TableB() const {
+ return c_type() == Evolution::V2::Union::TableB ? static_cast<const Evolution::V2::TableB *>(c()) : nullptr;
+ }
+ const Evolution::V2::TableC *c_as_TableC() const {
+ return c_type() == Evolution::V2::Union::TableC ? static_cast<const Evolution::V2::TableC *>(c()) : nullptr;
+ }
+ Evolution::V2::Enum d() const {
+ return static_cast<Evolution::V2::Enum>(GetField<int8_t>(VT_D, 0));
+ }
+ const Evolution::V2::TableA *e() const {
+ return GetPointer<const Evolution::V2::TableA *>(VT_E);
+ }
+ const Evolution::V2::Struct *ff() const {
+ return GetStruct<const Evolution::V2::Struct *>(VT_FF);
+ }
+ const flatbuffers::Vector<int32_t> *g() const {
+ return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_G);
+ }
+ const flatbuffers::Vector<flatbuffers::Offset<Evolution::V2::TableB>> *h() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Evolution::V2::TableB>> *>(VT_H);
+ }
+ uint32_t i() const {
+ return GetField<uint32_t>(VT_I, 1234);
+ }
+ const Evolution::V2::TableC *j() const {
+ return GetPointer<const Evolution::V2::TableC *>(VT_J);
+ }
+ uint8_t k() const {
+ return GetField<uint8_t>(VT_K, 56);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyField<uint8_t>(verifier, VT_B) &&
+ VerifyField<uint8_t>(verifier, VT_C_TYPE) &&
+ VerifyOffset(verifier, VT_C) &&
+ VerifyUnion(verifier, c(), c_type()) &&
+ VerifyField<int8_t>(verifier, VT_D) &&
+ VerifyOffset(verifier, VT_E) &&
+ verifier.VerifyTable(e()) &&
+ VerifyField<Evolution::V2::Struct>(verifier, VT_FF) &&
+ VerifyOffset(verifier, VT_G) &&
+ verifier.VerifyVector(g()) &&
+ VerifyOffset(verifier, VT_H) &&
+ verifier.VerifyVector(h()) &&
+ verifier.VerifyVectorOfTables(h()) &&
+ VerifyField<uint32_t>(verifier, VT_I) &&
+ VerifyOffset(verifier, VT_J) &&
+ verifier.VerifyTable(j()) &&
+ VerifyField<uint8_t>(verifier, VT_K) &&
+ verifier.EndTable();
+ }
+};
+
+template<> inline const Evolution::V2::TableA *Root::c_as<Evolution::V2::TableA>() const {
+ return c_as_TableA();
+}
+
+template<> inline const Evolution::V2::TableB *Root::c_as<Evolution::V2::TableB>() const {
+ return c_as_TableB();
+}
+
+template<> inline const Evolution::V2::TableC *Root::c_as<Evolution::V2::TableC>() const {
+ return c_as_TableC();
+}
+
+struct RootBuilder {
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_b(bool b) {
+ fbb_.AddElement<uint8_t>(Root::VT_B, static_cast<uint8_t>(b), 0);
+ }
+ void add_c_type(Evolution::V2::Union c_type) {
+ fbb_.AddElement<uint8_t>(Root::VT_C_TYPE, static_cast<uint8_t>(c_type), 0);
+ }
+ void add_c(flatbuffers::Offset<void> c) {
+ fbb_.AddOffset(Root::VT_C, c);
+ }
+ void add_d(Evolution::V2::Enum d) {
+ fbb_.AddElement<int8_t>(Root::VT_D, static_cast<int8_t>(d), 0);
+ }
+ void add_e(flatbuffers::Offset<Evolution::V2::TableA> e) {
+ fbb_.AddOffset(Root::VT_E, e);
+ }
+ void add_ff(const Evolution::V2::Struct *ff) {
+ fbb_.AddStruct(Root::VT_FF, ff);
+ }
+ void add_g(flatbuffers::Offset<flatbuffers::Vector<int32_t>> g) {
+ fbb_.AddOffset(Root::VT_G, g);
+ }
+ void add_h(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V2::TableB>>> h) {
+ fbb_.AddOffset(Root::VT_H, h);
+ }
+ void add_i(uint32_t i) {
+ fbb_.AddElement<uint32_t>(Root::VT_I, i, 1234);
+ }
+ void add_j(flatbuffers::Offset<Evolution::V2::TableC> j) {
+ fbb_.AddOffset(Root::VT_J, j);
+ }
+ void add_k(uint8_t k) {
+ fbb_.AddElement<uint8_t>(Root::VT_K, k, 56);
+ }
+ explicit RootBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ RootBuilder &operator=(const RootBuilder &);
+ flatbuffers::Offset<Root> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<Root>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<Root> CreateRoot(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ bool b = false,
+ Evolution::V2::Union c_type = Evolution::V2::Union::NONE,
+ flatbuffers::Offset<void> c = 0,
+ Evolution::V2::Enum d = Evolution::V2::Enum::King,
+ flatbuffers::Offset<Evolution::V2::TableA> e = 0,
+ const Evolution::V2::Struct *ff = 0,
+ flatbuffers::Offset<flatbuffers::Vector<int32_t>> g = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V2::TableB>>> h = 0,
+ uint32_t i = 1234,
+ flatbuffers::Offset<Evolution::V2::TableC> j = 0,
+ uint8_t k = 56) {
+ RootBuilder builder_(_fbb);
+ builder_.add_j(j);
+ builder_.add_i(i);
+ builder_.add_h(h);
+ builder_.add_g(g);
+ builder_.add_ff(ff);
+ builder_.add_e(e);
+ builder_.add_c(c);
+ builder_.add_k(k);
+ builder_.add_d(d);
+ builder_.add_c_type(c_type);
+ builder_.add_b(b);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<Root> CreateRootDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ bool b = false,
+ Evolution::V2::Union c_type = Evolution::V2::Union::NONE,
+ flatbuffers::Offset<void> c = 0,
+ Evolution::V2::Enum d = Evolution::V2::Enum::King,
+ flatbuffers::Offset<Evolution::V2::TableA> e = 0,
+ const Evolution::V2::Struct *ff = 0,
+ const std::vector<int32_t> *g = nullptr,
+ const std::vector<flatbuffers::Offset<Evolution::V2::TableB>> *h = nullptr,
+ uint32_t i = 1234,
+ flatbuffers::Offset<Evolution::V2::TableC> j = 0,
+ uint8_t k = 56) {
+ auto g__ = g ? _fbb.CreateVector<int32_t>(*g) : 0;
+ auto h__ = h ? _fbb.CreateVector<flatbuffers::Offset<Evolution::V2::TableB>>(*h) : 0;
+ return Evolution::V2::CreateRoot(
+ _fbb,
+ b,
+ c_type,
+ c,
+ d,
+ e,
+ ff,
+ g__,
+ h__,
+ i,
+ j,
+ k);
+}
+
+inline bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type) {
+ switch (type) {
+ case Union::NONE: {
+ return true;
+ }
+ case Union::TableA: {
+ auto ptr = reinterpret_cast<const Evolution::V2::TableA *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case Union::TableB: {
+ auto ptr = reinterpret_cast<const Evolution::V2::TableB *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ case Union::TableC: {
+ auto ptr = reinterpret_cast<const Evolution::V2::TableC *>(obj);
+ return verifier.VerifyTable(ptr);
+ }
+ default: return true;
+ }
+}
+
+inline bool VerifyUnionVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
+ if (!values || !types) return !values && !types;
+ if (values->size() != types->size()) return false;
+ for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
+ if (!VerifyUnion(
+ verifier, values->Get(i), types->GetEnum<Union>(i))) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline const Evolution::V2::Root *GetRoot(const void *buf) {
+ return flatbuffers::GetRoot<Evolution::V2::Root>(buf);
+}
+
+inline const Evolution::V2::Root *GetSizePrefixedRoot(const void *buf) {
+ return flatbuffers::GetSizePrefixedRoot<Evolution::V2::Root>(buf);
+}
+
+inline bool VerifyRootBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifyBuffer<Evolution::V2::Root>(nullptr);
+}
+
+inline bool VerifySizePrefixedRootBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifySizePrefixedBuffer<Evolution::V2::Root>(nullptr);
+}
+
+inline void FinishRootBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<Evolution::V2::Root> root) {
+ fbb.Finish(root);
+}
+
+inline void FinishSizePrefixedRootBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<Evolution::V2::Root> root) {
+ fbb.FinishSizePrefixed(root);
+}
+
+} // namespace V2
+} // namespace Evolution
+
+#endif // FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_H_
diff --git a/tests/fuzzer/CMakeLists.txt b/tests/fuzzer/CMakeLists.txt
index 7df5df2a..de1626f3 100644
--- a/tests/fuzzer/CMakeLists.txt
+++ b/tests/fuzzer/CMakeLists.txt
@@ -40,7 +40,6 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld")
set(FLATBUFFERS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../")
set(FlatBuffers_Library_SRCS
- ${FLATBUFFERS_DIR}/include/flatbuffers/code_generators.h
${FLATBUFFERS_DIR}/include/flatbuffers/base.h
${FLATBUFFERS_DIR}/include/flatbuffers/flatbuffers.h
${FLATBUFFERS_DIR}/include/flatbuffers/hash.h
@@ -52,7 +51,6 @@ set(FlatBuffers_Library_SRCS
${FLATBUFFERS_DIR}/include/flatbuffers/flexbuffers.h
${FLATBUFFERS_DIR}/include/flatbuffers/registry.h
${FLATBUFFERS_DIR}/include/flatbuffers/minireflect.h
- ${FLATBUFFERS_DIR}/src/code_generators.cpp
${FLATBUFFERS_DIR}/src/idl_parser.cpp
${FLATBUFFERS_DIR}/src/idl_gen_text.cpp
${FLATBUFFERS_DIR}/src/reflection.cpp
diff --git a/tests/fuzzer/test_init.h b/tests/fuzzer/test_init.h
index 3d8d07c8..6c9113d9 100644
--- a/tests/fuzzer/test_init.h
+++ b/tests/fuzzer/test_init.h
@@ -5,10 +5,6 @@
#include "fuzzer_assert.h"
#include "test_assert.h"
-static_assert(__has_feature(memory_sanitizer) ||
- __has_feature(address_sanitizer),
- "sanitizer disabled");
-
// Utility for test run.
struct OneTimeTestInit {
// Declare trap for the Flatbuffers test engine.
@@ -53,4 +49,4 @@ struct OneTimeTestInit {
static OneTimeTestInit one_time_init_;
};
-#endif // !FUZZER_TEST_INIT_H_ \ No newline at end of file
+#endif // !FUZZER_TEST_INIT_H_
diff --git a/tests/generate_code.bat b/tests/generate_code.bat
index fd335512..5d4db19f 100644
--- a/tests/generate_code.bat
+++ b/tests/generate_code.bat
@@ -12,24 +12,67 @@
:: See the License for the specific language governing permissions and
:: limitations under the License.
+@SETLOCAL
+
set buildtype=Release
if "%1"=="-b" set buildtype=%2
-..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --lobster --lua --js --rust --ts --php --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
-..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --lobster --lua --js --rust --ts --php --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL
-..\%buildtype%\flatc.exe --cpp --java --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs || goto FAIL
+set commandline=%*
+
+
+if NOT "%commandline%"=="%commandline:--cpp-std c++0x=%" (
+ set TEST_CPP_FLAGS=--cpp-std c++0x
+) else (
+ @rem --cpp-std is defined by flatc default settings.
+ set TEST_CPP_FLAGS=
+)
+
+set TEST_CPP_FLAGS=--gen-compare --cpp-ptr-type flatbuffers::unique_ptr %TEST_CPP_FLAGS%
+set TEST_CS_FLAGS=--cs-gen-json-serializer
+set TEST_RUST_FLAGS=--gen-name-strings
+set TEST_BASE_FLAGS=--reflect-names --gen-mutable --gen-object-api
+set TEST_NOINCL_FLAGS=%TEST_BASE_FLAGS% --no-includes --no-fb-import
+
+..\%buildtype%\flatc.exe --binary --cpp --java --kotlin --csharp --dart --go --lobster --lua --js --ts --php --grpc ^
+%TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
+..\%buildtype%\flatc.exe --rust %TEST_NOINCL_FLAGS% %TEST_RUST_FLAGS% -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
+
+..\%buildtype%\flatc.exe --python %TEST_BASE_FLAGS% --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
+
+..\%buildtype%\flatc.exe --binary --cpp --java --csharp --dart --go --lobster --lua --js --ts --php --python --rust ^
+%TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL
+
+..\%buildtype%\flatc.exe --cpp --java --csharp --js --ts --php %TEST_BASE_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% -o union_vector ./union_vector/union_vector.fbs || goto FAIL
+..\%buildtype%\flatc.exe --rust -I include_test -o include_test include_test/include_test1.fbs || goto FAIL
+..\%buildtype%\flatc.exe --rust -I include_test -o include_test/sub include_test/sub/include_test2.fbs || goto FAIL
..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --bfbs-comments --bfbs-builtins --bfbs-gen-embed %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% -I include_test monster_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs || goto FAIL
..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --java --csharp --jsonschema %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% --scoped-enums arrays_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --python %TEST_BASE_FLAGS% arrays_test.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp %TEST_BASE_FLAGS% --cpp-ptr-type flatbuffers::unique_ptr native_type_test.fbs || goto FAIL
-IF NOT "%MONSTER_EXTRA%"=="skip" (
+if NOT "%MONSTER_EXTRA%"=="skip" (
@echo Generate MosterExtra
- ..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs || goto FAIL
+ ..\%buildtype%\flatc.exe --cpp --java --csharp %TEST_NOINCL_FLAGS% %TEST_CPP_FLAGS% %TEST_CS_FLAGS% monster_extra.fbs monsterdata_extra.json || goto FAIL
+ ..\%buildtype%\flatc.exe --python %TEST_BASE_FLAGS% monster_extra.fbs monsterdata_extra.json || goto FAIL
) else (
@echo monster_extra.fbs skipped (the strtod function from MSVC2013 or older doesn't support NaN/Inf arguments)
)
+set TEST_CPP17_FLAGS=--cpp --cpp-std c++17 -o ./cpp17/generated_cpp17 %TEST_NOINCL_FLAGS%
+if NOT "%MONSTER_EXTRA%"=="skip" (
+ @rem Flag c++17 requires Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher.
+ ..\%buildtype%\flatc.exe %TEST_CPP17_FLAGS% -I include_test monster_test.fbs || goto FAIL
+ @rem..\%buildtype%\flatc.exe %TEST_CPP17_FLAGS% arrays_test.fbs || goto FAIL
+ @rem..\%buildtype%\flatc.exe %TEST_CPP17_FLAGS% native_type_test.fbs || goto FAIL
+ @rem..\%buildtype%\flatc.exe %TEST_CPP17_FLAGS% monster_extra.fbs || goto FAIL
+ @rem..\%buildtype%\flatc.exe %TEST_CPP17_FLAGS% ./union_vector/union_vector.fbs || goto FAIL
+)
+
cd ../samples
-..\%buildtype%\flatc.exe --cpp --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs || goto FAIL
+..\%buildtype%\flatc.exe --cpp --lobster %TEST_BASE_FLAGS% %TEST_CPP_FLAGS% monster.fbs || goto FAIL
..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins monster.fbs || goto FAIL
cd ../reflection
call generate_code.bat %1 %2 || goto FAIL
diff --git a/tests/generate_code.sh b/tests/generate_code.sh
index 40373a34..e97334f0 100755
--- a/tests/generate_code.sh
+++ b/tests/generate_code.sh
@@ -15,14 +15,60 @@
# limitations under the License.
set -e
-../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
-../flatc --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
-../flatc --cpp --java --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
+commandline="'$*'"
+
+if [[ $commandline == *"--cpp-std c++0x"* ]]; then
+ TEST_CPP_FLAGS="--cpp-std c++0x"
+else
+ # --cpp-std is defined by flatc default settings.
+ TEST_CPP_FLAGS=
+fi
+
+TEST_CPP_FLAGS="--gen-compare --cpp-ptr-type flatbuffers::unique_ptr $TEST_CPP_FLAGS"
+TEST_CS_FLAGS="--cs-gen-json-serializer"
+TEST_BASE_FLAGS="--reflect-names --gen-mutable --gen-object-api"
+TEST_RUST_FLAGS="$TEST_BASE_FLAGS --gen-name-strings"
+TEST_NOINCL_FLAGS="$TEST_BASE_FLAGS --no-includes --no-fb-import"
+
+../flatc --binary --cpp --java --kotlin --csharp --dart --go --lobster --lua --js --ts --php --grpc \
+$TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -I include_test monster_test.fbs monsterdata_test.json
+../flatc --rust $TEST_RUST_FLAGS -I include_test monster_test.fbs monsterdata_test.json
+
+../flatc --python $TEST_BASE_FLAGS -I include_test monster_test.fbs monsterdata_test.json
+
+../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --js --ts --php --python --rust \
+$TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
+
+../flatc --cpp --java --kotlin --csharp --js --ts --php $TEST_BASE_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS -o union_vector ./union_vector/union_vector.fbs
+../flatc --rust -I include_test -o include_test include_test/include_test1.fbs
+../flatc --rust -I include_test -o include_test/sub include_test/sub/include_test2.fbs
../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs
+../flatc --cpp --bfbs-comments --bfbs-builtins --bfbs-gen-embed $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS -I include_test monster_test.fbs
+../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs
../flatc --jsonschema --schema -I include_test monster_test.fbs
-../flatc --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs || goto FAIL
+../flatc --cpp --java --kotlin --csharp --python $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS monster_extra.fbs monsterdata_extra.json
+../flatc --cpp --java --csharp --jsonschema $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS $TEST_CS_FLAGS --scoped-enums arrays_test.fbs
+../flatc --python $TEST_BASE_FLAGS arrays_test.fbs
+../flatc --dart monster_extra.fbs
+
+# Tests if the --filename-suffix and --filename-ext works and produces the same
+# outputs.
+../flatc --cpp --filename-suffix _suffix --filename-ext hpp $TEST_NOINCL_FLAGS $TEST_CPP_FLAGS -I include_test monster_test.fbs
+if [ -f "monster_test_suffix.hpp" ]; then
+ if ! cmp -s "monster_test_suffix.hpp" "monster_test_generated.h"; then
+ echo "[Error] Filename suffix option did not produce identical results"
+ fi
+ rm "monster_test_suffix.hpp"
+else
+ echo "[Error] Filename suffix option did not produce a file"
+fi
+
+# Flag c++17 requires Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher.
+TEST_CPP17_FLAGS="--cpp --cpp-std c++17 -o ./cpp17/generated_cpp17 $TEST_NOINCL_FLAGS"
+../flatc $TEST_CPP17_FLAGS -I include_test monster_test.fbs
+
cd ../samples
-../flatc --cpp --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs
+../flatc --cpp --lobster $TEST_BASE_FLAGS $TEST_CPP_FLAGS monster.fbs
../flatc -b --schema --bfbs-comments --bfbs-builtins monster.fbs
cd ../reflection
-./generate_code.sh
+./generate_code.sh --cpp-std c++0x
diff --git a/tests/go_test.go b/tests/go_test.go
index 0c16da91..9b2ec964 100644
--- a/tests/go_test.go
+++ b/tests/go_test.go
@@ -28,6 +28,7 @@ import (
"reflect"
"sort"
"testing"
+ "testing/quick"
flatbuffers "github.com/google/flatbuffers/go"
)
@@ -77,7 +78,8 @@ func TestAll(t *testing.T) {
CheckByteStringIsNestedError(t.Fatalf)
CheckStructIsNotInlineError(t.Fatalf)
CheckFinishedBytesError(t.Fatalf)
-
+ CheckSharedStrings(t.Fatalf)
+
// Verify that GetRootAs works for non-root tables
CheckGetRootAsForNonRootTable(t.Fatalf)
CheckTableAccessors(t.Fatalf)
@@ -90,6 +92,7 @@ func TestAll(t *testing.T) {
// generated Go code:
CheckReadBuffer(generated, off, t.Fatalf)
CheckMutateBuffer(generated, off, t.Fatalf)
+ CheckObjectAPI(generated, off, t.Fatalf)
// Verify that the buffer generated by C++ code is readable by the
// generated Go code:
@@ -99,6 +102,7 @@ func TestAll(t *testing.T) {
}
CheckReadBuffer(monsterDataCpp, 0, t.Fatalf)
CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf)
+ CheckObjectAPI(monsterDataCpp, 0, t.Fatalf)
// Verify that vtables are deduplicated when written:
CheckVtableDeduplication(t.Fatalf)
@@ -106,6 +110,12 @@ func TestAll(t *testing.T) {
// Verify the enum names
CheckEnumNames(t.Fatalf)
+ // Verify enum String methods
+ CheckEnumString(t.Fatalf)
+
+ // Verify the enum values maps
+ CheckEnumValues(t.Fatalf)
+
// Verify that the Go code used in FlatBuffers documentation passes
// some sanity checks:
CheckDocExample(generated, off, t.Fatalf)
@@ -199,8 +209,8 @@ func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string,
fail(FailString("Pos.Test1", float64(3.0), got))
}
- if got := vec.Test2(); int8(2) != got {
- fail(FailString("Pos.Test2", int8(2), got))
+ if got := vec.Test2(); example.ColorGreen != got {
+ fail(FailString("Pos.Test2", example.ColorGreen, got))
}
// initialize a Test from Test3(...)
@@ -331,7 +341,7 @@ func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string
testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(2.0) }},
testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(3.0) }},
testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(3.0) }},
- testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == int8(2) }},
+ testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorGreen }},
testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(5) }},
testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(6) }},
testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(2) }},
@@ -345,7 +355,7 @@ func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string
testcase{"Pos.Y", func() bool { return monster.Pos(nil).MutateY(20.0) }},
testcase{"Pos.Z", func() bool { return monster.Pos(nil).MutateZ(30.0) }},
testcase{"Pos.Test1", func() bool { return monster.Pos(nil).MutateTest1(30.0) }},
- testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(20) }},
+ testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.ColorBlue) }},
testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).MutateA(50) }},
testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).MutateB(60) }},
testcase{"Inventory[2]", func() bool { return monster.MutateInventory(2, 200) }},
@@ -359,12 +369,17 @@ func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string
testcase{"Pos.Y'", func() bool { return monster.Pos(nil).Y() == float32(20.0) }},
testcase{"Pos.Z'", func() bool { return monster.Pos(nil).Z() == float32(30.0) }},
testcase{"Pos.Test1'", func() bool { return monster.Pos(nil).Test1() == float64(30.0) }},
- testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == int8(20) }},
+ testcase{"Pos.Test2'", func() bool { return monster.Pos(nil).Test2() == example.ColorBlue }},
testcase{"Pos.Test3.A", func() bool { return monster.Pos(nil).Test3(nil).A() == int16(50) }},
testcase{"Pos.Test3.B", func() bool { return monster.Pos(nil).Test3(nil).B() == int8(60) }},
testcase{"Inventory[2]", func() bool { return monster.Inventory(2) == byte(200) }},
}
+ testInvalidEnumValues := []testcase{
+ testcase{"Pos.Test2", func() bool { return monster.Pos(nil).MutateTest2(example.Color(20)) }},
+ testcase{"Pos.Test2", func() bool { return monster.Pos(nil).Test2() == example.Color(20) }},
+ }
+
// make sure original values are okay
for _, t := range testForOriginalValues {
if !t.testfn() {
@@ -400,6 +415,14 @@ func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string
}
}
+ // a couple extra tests for "invalid" enum values, which don't correspond to
+ // anything in the schema, but are allowed
+ for _, t := range testInvalidEnumValues {
+ if !t.testfn() {
+ fail("field '" + t.field + "' doesn't work with an invalid enum value")
+ }
+ }
+
// reverting all fields to original values should
// re-create the original buffer. Mutate all fields
// back to their original values and compare buffers.
@@ -412,7 +435,7 @@ func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string
monster.Pos(nil).MutateY(2.0)
monster.Pos(nil).MutateZ(3.0)
monster.Pos(nil).MutateTest1(3.0)
- monster.Pos(nil).MutateTest2(2)
+ monster.Pos(nil).MutateTest2(example.ColorGreen)
monster.Pos(nil).Test3(nil).MutateA(5)
monster.Pos(nil).Test3(nil).MutateB(6)
monster.MutateInventory(2, 2)
@@ -429,6 +452,26 @@ func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string
}
}
+func CheckObjectAPI(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
+ monster := example.GetRootAsMonster(buf, offset).UnPack()
+
+ if got := monster.Hp; 80 != got {
+ fail(FailString("hp", 80, got))
+ }
+
+ // default
+ if got := monster.Mana; 150 != got {
+ fail(FailString("mana", 150, got))
+ }
+
+ builder := flatbuffers.NewBuilder(0)
+ builder.Finish(monster.Pack(builder))
+ monster2 := example.GetRootAsMonster(builder.FinishedBytes(), 0).UnPack()
+ if !reflect.DeepEqual(monster, monster2) {
+ fail(FailString("Pack/Unpack()", monster, monster2))
+ }
+}
+
// Low level stress/fuzz test: serialize/deserialize a variety of
// different kinds of data in different combinations
func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {
@@ -1170,7 +1213,7 @@ func CheckGeneratedBuild(fail func(string, ...interface{})) ([]byte, flatbuffers
example.MonsterStart(b)
- pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
+ pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
example.MonsterAddPos(b, pos)
example.MonsterAddHp(b, 80)
@@ -1334,6 +1377,29 @@ func CheckStringIsNestedError(fail func(string, ...interface{})) {
b.CreateString("foo")
}
+func CheckSharedStrings(fail func(string, ...interface{})) {
+ f := func(strings []string) bool {
+ b := flatbuffers.NewBuilder(0)
+ for _, s1 := range strings {
+ for _, s2 := range strings {
+ off1 := b.CreateSharedString(s1)
+ off2 := b.CreateSharedString(s2)
+
+ if (s1 == s2) && (off1 != off2) {
+ return false
+ }
+ if (s1 != s2) && (off1 == off2) {
+ return false
+ }
+ }
+ }
+ return true
+ }
+ if err := quick.Check(f, nil); err != nil {
+ fail("expected same offset")
+ }
+}
+
// CheckByteStringIsNestedError verifies that a bytestring can not be created
// inside another object.
func CheckByteStringIsNestedError(fail func(string, ...interface{})) {
@@ -1379,7 +1445,6 @@ func CheckFinishedBytesError(fail func(string, ...interface{})) {
// CheckEnumNames checks that the generated enum names are correct.
func CheckEnumNames(fail func(string, ...interface{})) {
{
-
want := map[example.Any]string{
example.AnyNONE: "NONE",
example.AnyMonster: "Monster",
@@ -1404,6 +1469,43 @@ func CheckEnumNames(fail func(string, ...interface{})) {
}
}
+// CheckEnumString checks the String method on generated enum types.
+func CheckEnumString(fail func(string, ...interface{})) {
+ if got := example.AnyMonster.String(); got != "Monster" {
+ fail("Monster.String: %q != %q", got, "Monster")
+ }
+ if got := fmt.Sprintf("color: %s", example.ColorGreen); got != "color: Green" {
+ fail("color.String: %q != %q", got, "color: Green")
+ }
+}
+
+// CheckEnumValues checks that the generated enum values maps are correct.
+func CheckEnumValues(fail func(string, ...interface{})) {
+ {
+ want := map[string]example.Any{
+ "NONE": example.AnyNONE,
+ "Monster": example.AnyMonster,
+ "TestSimpleTableWithEnum": example.AnyTestSimpleTableWithEnum,
+ "MyGame_Example2_Monster": example.AnyMyGame_Example2_Monster,
+ }
+ got := example.EnumValuesAny
+ if !reflect.DeepEqual(got, want) {
+ fail("enum name is not equal")
+ }
+ }
+ {
+ want := map[string]example.Color{
+ "Red": example.ColorRed,
+ "Green": example.ColorGreen,
+ "Blue": example.ColorBlue,
+ }
+ got := example.EnumValuesColor
+ if !reflect.DeepEqual(got, want) {
+ fail("enum name is not equal")
+ }
+ }
+}
+
// CheckDocExample checks that the code given in FlatBuffers documentation
// is syntactically correct.
func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...interface{})) {
@@ -1424,11 +1526,12 @@ func CheckDocExample(buf []byte, off flatbuffers.UOffsetT, fail func(string, ...
str := builder.CreateString("MyMonster")
example.MonsterStart(builder)
- example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, 4, 5, 6))
+ example.MonsterAddPos(builder, example.CreateVec3(builder, 1.0, 2.0, 3.0, 3.0, example.Color(4), 5, 6))
example.MonsterAddHp(builder, 80)
example.MonsterAddName(builder, str)
example.MonsterAddInventory(builder, inv)
example.MonsterAddTestType(builder, 1)
+ example.MonsterAddColor(builder, example.ColorRed)
// example.MonsterAddTest(builder, mon2)
// example.MonsterAddTest4(builder, test4s)
_ = example.MonsterEnd(builder)
@@ -1816,7 +1919,7 @@ func BenchmarkBuildGold(b *testing.B) {
example.MonsterStart(bldr)
- pos := example.CreateVec3(bldr, 1.0, 2.0, 3.0, 3.0, 2, 5, 6)
+ pos := example.CreateVec3(bldr, 1.0, 2.0, 3.0, 3.0, example.ColorGreen, 5, 6)
example.MonsterAddPos(bldr, pos)
example.MonsterAddHp(bldr, 80)
diff --git a/tests/include_test/include_test1_generated.rs b/tests/include_test/include_test1_generated.rs
new file mode 100644
index 00000000..e6e7d490
--- /dev/null
+++ b/tests/include_test/include_test1_generated.rs
@@ -0,0 +1,87 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use crate::include_test2_generated::*;
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+pub enum TableAOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TableA<'a> {
+ pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TableA<'a> {
+ type Inner = TableA<'a>;
+ #[inline]
+ fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+ Self {
+ _tab: flatbuffers::Table { buf: buf, loc: loc },
+ }
+ }
+}
+
+impl<'a> TableA<'a> {
+ #[inline]
+ pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+ TableA {
+ _tab: table,
+ }
+ }
+ #[allow(unused_mut)]
+ pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+ _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+ args: &'args TableAArgs<'args>) -> flatbuffers::WIPOffset<TableA<'bldr>> {
+ let mut builder = TableABuilder::new(_fbb);
+ if let Some(x) = args.b { builder.add_b(x); }
+ builder.finish()
+ }
+
+ pub const VT_B: flatbuffers::VOffsetT = 4;
+
+ #[inline]
+ pub fn b(&self) -> Option<my_game::other_name_space::TableB<'a>> {
+ self._tab.get::<flatbuffers::ForwardsUOffset<my_game::other_name_space::TableB<'a>>>(TableA::VT_B, None)
+ }
+}
+
+pub struct TableAArgs<'a> {
+ pub b: Option<flatbuffers::WIPOffset<my_game::other_name_space::TableB<'a >>>,
+}
+impl<'a> Default for TableAArgs<'a> {
+ #[inline]
+ fn default() -> Self {
+ TableAArgs {
+ b: None,
+ }
+ }
+}
+pub struct TableABuilder<'a: 'b, 'b> {
+ fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+ start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TableABuilder<'a, 'b> {
+ #[inline]
+ pub fn add_b(&mut self, b: flatbuffers::WIPOffset<my_game::other_name_space::TableB<'b >>) {
+ self.fbb_.push_slot_always::<flatbuffers::WIPOffset<my_game::other_name_space::TableB>>(TableA::VT_B, b);
+ }
+ #[inline]
+ pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TableABuilder<'a, 'b> {
+ let start = _fbb.start_table();
+ TableABuilder {
+ fbb_: _fbb,
+ start_: start,
+ }
+ }
+ #[inline]
+ pub fn finish(self) -> flatbuffers::WIPOffset<TableA<'a>> {
+ let o = self.fbb_.end_table(self.start_);
+ flatbuffers::WIPOffset::new(o.value())
+ }
+}
+
diff --git a/tests/include_test/sub/include_test2_generated.rs b/tests/include_test/sub/include_test2_generated.rs
new file mode 100644
index 00000000..eee54a93
--- /dev/null
+++ b/tests/include_test/sub/include_test2_generated.rs
@@ -0,0 +1,222 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+
+use crate::include_test1_generated::*;
+use std::mem;
+use std::cmp::Ordering;
+
+extern crate flatbuffers;
+use self::flatbuffers::EndianScalar;
+
+#[allow(unused_imports, dead_code)]
+pub mod my_game {
+
+ use crate::include_test1_generated::*;
+ use std::mem;
+ use std::cmp::Ordering;
+
+ extern crate flatbuffers;
+ use self::flatbuffers::EndianScalar;
+#[allow(unused_imports, dead_code)]
+pub mod other_name_space {
+
+ use crate::include_test1_generated::*;
+ use std::mem;
+ use std::cmp::Ordering;
+
+ extern crate flatbuffers;
+ use self::flatbuffers::EndianScalar;
+
+#[allow(non_camel_case_types)]
+#[repr(i64)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum FromInclude {
+ IncludeVal = 0,
+
+}
+
+pub const ENUM_MIN_FROM_INCLUDE: i64 = 0;
+pub const ENUM_MAX_FROM_INCLUDE: i64 = 0;
+
+impl<'a> flatbuffers::Follow<'a> for FromInclude {
+ type Inner = Self;
+ #[inline]
+ fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+ flatbuffers::read_scalar_at::<Self>(buf, loc)
+ }
+}
+
+impl flatbuffers::EndianScalar for FromInclude {
+ #[inline]
+ fn to_little_endian(self) -> Self {
+ let n = i64::to_le(self as i64);
+ let p = &n as *const i64 as *const FromInclude;
+ unsafe { *p }
+ }
+ #[inline]
+ fn from_little_endian(self) -> Self {
+ let n = i64::from_le(self as i64);
+ let p = &n as *const i64 as *const FromInclude;
+ unsafe { *p }
+ }
+}
+
+impl flatbuffers::Push for FromInclude {
+ type Output = FromInclude;
+ #[inline]
+ fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+ flatbuffers::emplace_scalar::<FromInclude>(dst, *self);
+ }
+}
+
+#[allow(non_camel_case_types)]
+pub const ENUM_VALUES_FROM_INCLUDE:[FromInclude; 1] = [
+ FromInclude::IncludeVal
+];
+
+#[allow(non_camel_case_types)]
+pub const ENUM_NAMES_FROM_INCLUDE:[&'static str; 1] = [
+ "IncludeVal"
+];
+
+pub fn enum_name_from_include(e: FromInclude) -> &'static str {
+ let index = e as i64;
+ ENUM_NAMES_FROM_INCLUDE[index as usize]
+}
+
+// struct Unused, aligned to 4
+#[repr(C, align(4))]
+#[derive(Clone, Copy, Debug, PartialEq)]
+pub struct Unused {
+ a_: i32,
+} // pub struct Unused
+impl flatbuffers::SafeSliceAccess for Unused {}
+impl<'a> flatbuffers::Follow<'a> for Unused {
+ type Inner = &'a Unused;
+ #[inline]
+ fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+ <&'a Unused>::follow(buf, loc)
+ }
+}
+impl<'a> flatbuffers::Follow<'a> for &'a Unused {
+ type Inner = &'a Unused;
+ #[inline]
+ fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+ flatbuffers::follow_cast_ref::<Unused>(buf, loc)
+ }
+}
+impl<'b> flatbuffers::Push for Unused {
+ type Output = Unused;
+ #[inline]
+ fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+ let src = unsafe {
+ ::std::slice::from_raw_parts(self as *const Unused as *const u8, Self::size())
+ };
+ dst.copy_from_slice(src);
+ }
+}
+impl<'b> flatbuffers::Push for &'b Unused {
+ type Output = Unused;
+
+ #[inline]
+ fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+ let src = unsafe {
+ ::std::slice::from_raw_parts(*self as *const Unused as *const u8, Self::size())
+ };
+ dst.copy_from_slice(src);
+ }
+}
+
+
+impl Unused {
+ pub fn new<'a>(_a: i32) -> Self {
+ Unused {
+ a_: _a.to_little_endian(),
+
+ }
+ }
+ pub fn a<'a>(&'a self) -> i32 {
+ self.a_.from_little_endian()
+ }
+}
+
+pub enum TableBOffset {}
+#[derive(Copy, Clone, Debug, PartialEq)]
+
+pub struct TableB<'a> {
+ pub _tab: flatbuffers::Table<'a>,
+}
+
+impl<'a> flatbuffers::Follow<'a> for TableB<'a> {
+ type Inner = TableB<'a>;
+ #[inline]
+ fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+ Self {
+ _tab: flatbuffers::Table { buf: buf, loc: loc },
+ }
+ }
+}
+
+impl<'a> TableB<'a> {
+ #[inline]
+ pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
+ TableB {
+ _tab: table,
+ }
+ }
+ #[allow(unused_mut)]
+ pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
+ _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
+ args: &'args TableBArgs<'args>) -> flatbuffers::WIPOffset<TableB<'bldr>> {
+ let mut builder = TableBBuilder::new(_fbb);
+ if let Some(x) = args.a { builder.add_a(x); }
+ builder.finish()
+ }
+
+ pub const VT_A: flatbuffers::VOffsetT = 4;
+
+ #[inline]
+ pub fn a(&self) -> Option<super::super::TableA<'a>> {
+ self._tab.get::<flatbuffers::ForwardsUOffset<super::super::TableA<'a>>>(TableB::VT_A, None)
+ }
+}
+
+pub struct TableBArgs<'a> {
+ pub a: Option<flatbuffers::WIPOffset<super::super::TableA<'a >>>,
+}
+impl<'a> Default for TableBArgs<'a> {
+ #[inline]
+ fn default() -> Self {
+ TableBArgs {
+ a: None,
+ }
+ }
+}
+pub struct TableBBuilder<'a: 'b, 'b> {
+ fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
+ start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
+}
+impl<'a: 'b, 'b> TableBBuilder<'a, 'b> {
+ #[inline]
+ pub fn add_a(&mut self, a: flatbuffers::WIPOffset<super::super::TableA<'b >>) {
+ self.fbb_.push_slot_always::<flatbuffers::WIPOffset<super::super::TableA>>(TableB::VT_A, a);
+ }
+ #[inline]
+ pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> TableBBuilder<'a, 'b> {
+ let start = _fbb.start_table();
+ TableBBuilder {
+ fbb_: _fbb,
+ start_: start,
+ }
+ }
+ #[inline]
+ pub fn finish(self) -> flatbuffers::WIPOffset<TableB<'a>> {
+ let o = self.fbb_.end_table(self.start_);
+ flatbuffers::WIPOffset::new(o.value())
+ }
+}
+
+} // pub mod OtherNameSpace
+} // pub mod MyGame
+
diff --git a/tests/lobstertest.lobster b/tests/lobstertest.lobster
index e4f08087..7ea9b388 100644
--- a/tests/lobstertest.lobster
+++ b/tests/lobstertest.lobster
@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-include from "../lobster/"
-include "monster_test_generated.lobster"
+import from "../lobster/"
+import monster_test_generated
def check_read_buffer(buf):
// CheckReadBuffer checks that the given buffer is evaluated correctly as the example Monster.
@@ -70,9 +70,10 @@ def make_monster_from_generated_code():
let inv = b.MyGame_Example_MonsterCreateInventoryVector([ 0, 1, 2, 3, 4 ])
- b.MyGame_Example_MonsterStart()
- b.MyGame_Example_MonsterAddName(fred)
- let mon2 = b.MyGame_Example_MonsterEnd()
+ let mon2 = MyGame_Example_MonsterBuilder { b }
+ .start()
+ .add_name(fred)
+ .end()
b.MyGame_Example_MonsterStartTest4Vector(2)
b.MyGame_Example_CreateTest(10, 20)
@@ -88,18 +89,20 @@ def make_monster_from_generated_code():
let vector_of_doubles = b.MyGame_Example_MonsterCreateVectorOfDoublesVector(
[ -1.7976931348623157e+308, 0, 1.7976931348623157e+308 ])
- b.MyGame_Example_MonsterStart()
- b.MyGame_Example_MonsterAddPos(b.MyGame_Example_CreateVec3(1.0, 2.0, 3.0, 3.0, 2, 5, 6))
- b.MyGame_Example_MonsterAddHp(80)
- b.MyGame_Example_MonsterAddName(name)
- b.MyGame_Example_MonsterAddInventory(inv)
- b.MyGame_Example_MonsterAddTestType(MyGame_Example_Any_Monster)
- b.MyGame_Example_MonsterAddTest(mon2)
- b.MyGame_Example_MonsterAddTest4(test4)
- b.MyGame_Example_MonsterAddTestarrayofstring(test_array_of_string)
- b.MyGame_Example_MonsterAddVectorOfLongs(vector_of_longs)
- b.MyGame_Example_MonsterAddVectorOfDoubles(vector_of_doubles)
- let mon = b.MyGame_Example_MonsterEnd()
+ let mon = MyGame_Example_MonsterBuilder { b }
+ .start()
+ .add_pos(b.MyGame_Example_CreateVec3(1.0, 2.0, 3.0, 3.0,
+ MyGame_Example_Color_Green, 5, 6))
+ .add_hp(80)
+ .add_name(name)
+ .add_inventory(inv)
+ .add_test_type(MyGame_Example_Any_Monster)
+ .add_test(mon2)
+ .add_test4(test4)
+ .add_testarrayofstring(test_array_of_string)
+ .add_vector_of_longs(vector_of_longs)
+ .add_vector_of_doubles(vector_of_doubles)
+ .end()
b.Finish(mon)
@@ -119,14 +122,14 @@ check_read_buffer(fb1)
write_file("monsterdata_lobster_wire.mon", fb1)
// Test converting the buffer to JSON and parsing the JSON back again.
-schema := read_file("monster_test.fbs")
+let schema = read_file("monster_test.fbs")
assert schema
-includedirs := [ "include_test" ]
+let includedirs = [ "include_test" ]
// Convert binary to JSON:
-json, err1 := flatbuffers_binary_to_json(schema, fb1, includedirs)
+let json, err1 = flatbuffers_binary_to_json(schema, fb1, includedirs)
assert not err1
// Parse JSON back to binary:
-fb3, err2 := flatbuffers_json_to_binary(schema, json, includedirs)
+let fb3, err2 = flatbuffers_json_to_binary(schema, json, includedirs)
assert not err2
// Check the resulting binary again (full roundtrip test):
check_read_buffer(fb3)
diff --git a/tests/luatest.lua b/tests/luatest.lua
index 23bc0f29..e60f837d 100644
--- a/tests/luatest.lua
+++ b/tests/luatest.lua
@@ -9,9 +9,7 @@ local function checkReadBuffer(buf, offset, sizePrefix)
if sizePrefix then
local size = flatbuffers.N.Int32:Unpack(buf, offset)
- -- no longer matches python tests, but the latest 'monsterdata_test.mon'
- -- is 448 bytes, minus 4 to arrive at the 444
- assert(size == 444)
+ assert(size == #buf - offset - 4)
offset = offset + flatbuffers.N.Int32.bytewidth
end
@@ -83,8 +81,9 @@ local function checkReadBuffer(buf, offset, sizePrefix)
assert(mon:Testempty() == nil)
end
-local function generateMonster(sizePrefix)
- local b = flatbuffers.Builder(0)
+local function generateMonster(sizePrefix, b)
+ if b then b:Clear() end
+ b = b or flatbuffers.Builder(0)
local str = b:CreateString("MyMonster")
local test1 = b:CreateString("test1")
local test2 = b:CreateString("test2")
@@ -136,6 +135,10 @@ local function generateMonster(sizePrefix)
monster.AddTestType(b, 1)
monster.AddTest(b, mon2)
monster.AddTest4(b, test4)
+ monster.AddTestbool(b, true)
+ monster.AddTestbool(b, false)
+ monster.AddTestbool(b, null)
+ monster.AddTestbool(b,"true")
monster.AddTestarrayofstring(b, testArrayOfString)
monster.AddVectorOfLongs(b, vectorOfLongs)
monster.AddVectorOfDoubles(b, vectorOfDoubles)
@@ -154,6 +157,51 @@ local function sizePrefix(sizePrefix)
checkReadBuffer(buf, offset, sizePrefix)
end
+local function fbbClear()
+ -- Generate a builder that will be 'cleared' and reused to create two different objects.
+ local fbb = flatbuffers.Builder(0)
+
+ -- First use the builder to read the normal monster data and verify it works
+ local buf, offset = generateMonster(false, fbb)
+ checkReadBuffer(buf, offset, false)
+
+ -- Then clear the builder to be used again
+ fbb:Clear()
+
+ -- Storage for the built monsters
+ local monsters = {}
+ local lastBuf
+
+ -- Make another builder that will be use identically to the 'cleared' one so outputs can be compared. Build both the
+ -- Cleared builder and new builder in the exact same way, so we can compare their results
+ for i, builder in ipairs({fbb, flatbuffers.Builder(0)}) do
+ local strOffset = builder:CreateString("Hi there")
+ monster.Start(builder)
+ monster.AddPos(builder, vec3.CreateVec3(builder, 3.0, 2.0, 1.0, 17.0, 3, 100, 123))
+ monster.AddName(builder, strOffset)
+ monster.AddMana(builder, 123)
+ builder:Finish(monster.End(builder))
+ local buf = builder:Output(false)
+ if not lastBuf then
+ lastBuf = buf
+ else
+ -- the output, sized-buffer should be identical
+ assert(lastBuf == buf, "Monster output buffers are not identical")
+ end
+ monsters[i] = monster.GetRootAsMonster(flatbuffers.binaryArray.New(buf), 0)
+ end
+
+ -- Check that all the fields for the generated monsters are as we expect
+ for i, monster in ipairs(monsters) do
+ assert(monster:Name() == "Hi there", "Monster Name is not 'Hi There' for monster "..i)
+ -- HP is default to 100 in the schema, but we change it in generateMonster to 80, so this is a good test to
+ -- see if the cleared builder really clears the data.
+ assert(monster:Hp() == 100, "HP doesn't equal the default value for monster "..i)
+ assert(monster:Mana() == 123, "Monster Mana is not '123' for monster "..i)
+ assert(monster:Pos():X() == 3.0, "Monster vec3.X is not '3' for monster "..i)
+ end
+end
+
local function testCanonicalData()
local f = assert(io.open('monsterdata_test.mon', 'rb'))
local wireData = f:read("*a")
@@ -161,26 +209,16 @@ local function testCanonicalData()
checkReadBuffer(wireData)
end
-local function benchmarkMakeMonster(count)
- local length = #(generateMonster())
-
- --require("flatbuffers.profiler")
- --profiler = newProfiler("call")
- --profiler:start()
-
+local function benchmarkMakeMonster(count, reuseBuilder)
+ local fbb = reuseBuilder and flatbuffers.Builder(0)
+ local length = #(generateMonster(false, fbb))
+
local s = os.clock()
for i=1,count do
- generateMonster()
+ generateMonster(false, fbb)
end
local e = os.clock()
-
- --profiler:stop()
- --local outfile = io.open( "profile.txt", "w+" )
- --profiler:report( outfile, true)
- --outfile:close()
-
-
local dur = (e - s)
local rate = count / (dur * 1000)
local data = (length * count) / (1024 * 1024)
@@ -217,6 +255,10 @@ local tests =
d = "Test size prefix",
args = {{true}, {false}}
},
+ {
+ f = fbbClear,
+ d = "FlatBufferBuilder Clear",
+ },
{
f = testCanonicalData,
d = "Tests Canonical flatbuffer file included in repo"
@@ -228,6 +270,7 @@ local tests =
{100},
{1000},
{10000},
+ {10000, true}
}
},
{
@@ -239,7 +282,7 @@ local tests =
{10000},
-- uncomment following to run 1 million to compare.
-- Took ~141 seconds on my machine
- --{1000000},
+ --{1000000},
}
},
}
diff --git a/tests/monster_extra.fbs b/tests/monster_extra.fbs
index 89f1cc8d..7cadf457 100644
--- a/tests/monster_extra.fbs
+++ b/tests/monster_extra.fbs
@@ -1,12 +1,22 @@
namespace MyGame;
-// Not all programmining languages support this extra table.
+// Not all programming languages support this extra table.
table MonsterExtra {
// Float-point values with NaN and Inf defaults.
- testf_nan:float = nan;
- testf_pinf:float = +inf;
- testf_ninf:float = -inf;
- testd_nan:double = nan;
- testd_pinf:double = +inf;
- testd_ninf:double = -inf;
+ d0:double = nan;
+ d1:double = -nan; // parser must ignore sign of NaN
+ d2:double = +inf;
+ d3:double = -inf;
+ f0:float = -nan; // parser must ignore sign of NaN
+ f1:float = +nan;
+ f2:float = +inf;
+ f3:float = -inf;
+ dvec : [double];
+ fvec : [float];
+ deprec:int (deprecated);
}
+
+root_type MonsterExtra;
+
+file_identifier "MONE";
+file_extension "mon";
diff --git a/tests/monster_extra_generated.h b/tests/monster_extra_generated.h
index 8599b811..3b4ee27a 100644
--- a/tests/monster_extra_generated.h
+++ b/tests/monster_extra_generated.h
@@ -9,6 +9,7 @@
namespace MyGame {
struct MonsterExtra;
+struct MonsterExtraBuilder;
struct MonsterExtraT;
bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs);
@@ -18,30 +19,40 @@ inline const flatbuffers::TypeTable *MonsterExtraTypeTable();
struct MonsterExtraT : public flatbuffers::NativeTable {
typedef MonsterExtra TableType;
- float testf_nan;
- float testf_pinf;
- float testf_ninf;
- double testd_nan;
- double testd_pinf;
- double testd_ninf;
+ double d0;
+ double d1;
+ double d2;
+ double d3;
+ float f0;
+ float f1;
+ float f2;
+ float f3;
+ std::vector<double> dvec;
+ std::vector<float> fvec;
MonsterExtraT()
- : testf_nan(std::numeric_limits<float>::quiet_NaN()),
- testf_pinf(std::numeric_limits<float>::infinity()),
- testf_ninf(-std::numeric_limits<float>::infinity()),
- testd_nan(std::numeric_limits<double>::quiet_NaN()),
- testd_pinf(std::numeric_limits<double>::infinity()),
- testd_ninf(-std::numeric_limits<double>::infinity()) {
+ : d0(std::numeric_limits<double>::quiet_NaN()),
+ d1(std::numeric_limits<double>::quiet_NaN()),
+ d2(std::numeric_limits<double>::infinity()),
+ d3(-std::numeric_limits<double>::infinity()),
+ f0(std::numeric_limits<float>::quiet_NaN()),
+ f1(std::numeric_limits<float>::quiet_NaN()),
+ f2(std::numeric_limits<float>::infinity()),
+ f3(-std::numeric_limits<float>::infinity()) {
}
};
inline bool operator==(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
return
- (lhs.testf_nan == rhs.testf_nan) &&
- (lhs.testf_pinf == rhs.testf_pinf) &&
- (lhs.testf_ninf == rhs.testf_ninf) &&
- (lhs.testd_nan == rhs.testd_nan) &&
- (lhs.testd_pinf == rhs.testd_pinf) &&
- (lhs.testd_ninf == rhs.testd_ninf);
+ (lhs.d0 == rhs.d0) &&
+ (lhs.d1 == rhs.d1) &&
+ (lhs.d2 == rhs.d2) &&
+ (lhs.d3 == rhs.d3) &&
+ (lhs.f0 == rhs.f0) &&
+ (lhs.f1 == rhs.f1) &&
+ (lhs.f2 == rhs.f2) &&
+ (lhs.f3 == rhs.f3) &&
+ (lhs.dvec == rhs.dvec) &&
+ (lhs.fvec == rhs.fvec);
}
inline bool operator!=(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
@@ -51,61 +62,96 @@ inline bool operator!=(const MonsterExtraT &lhs, const MonsterExtraT &rhs) {
struct MonsterExtra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef MonsterExtraT NativeTableType;
+ typedef MonsterExtraBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MonsterExtraTypeTable();
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
- VT_TESTF_NAN = 4,
- VT_TESTF_PINF = 6,
- VT_TESTF_NINF = 8,
- VT_TESTD_NAN = 10,
- VT_TESTD_PINF = 12,
- VT_TESTD_NINF = 14
+ VT_D0 = 4,
+ VT_D1 = 6,
+ VT_D2 = 8,
+ VT_D3 = 10,
+ VT_F0 = 12,
+ VT_F1 = 14,
+ VT_F2 = 16,
+ VT_F3 = 18,
+ VT_DVEC = 20,
+ VT_FVEC = 22
};
- float testf_nan() const {
- return GetField<float>(VT_TESTF_NAN, std::numeric_limits<float>::quiet_NaN());
+ double d0() const {
+ return GetField<double>(VT_D0, std::numeric_limits<double>::quiet_NaN());
}
- bool mutate_testf_nan(float _testf_nan) {
- return SetField<float>(VT_TESTF_NAN, _testf_nan, std::numeric_limits<float>::quiet_NaN());
+ bool mutate_d0(double _d0) {
+ return SetField<double>(VT_D0, _d0, std::numeric_limits<double>::quiet_NaN());
}
- float testf_pinf() const {
- return GetField<float>(VT_TESTF_PINF, std::numeric_limits<float>::infinity());
+ double d1() const {
+ return GetField<double>(VT_D1, std::numeric_limits<double>::quiet_NaN());
}
- bool mutate_testf_pinf(float _testf_pinf) {
- return SetField<float>(VT_TESTF_PINF, _testf_pinf, std::numeric_limits<float>::infinity());
+ bool mutate_d1(double _d1) {
+ return SetField<double>(VT_D1, _d1, std::numeric_limits<double>::quiet_NaN());
}
- float testf_ninf() const {
- return GetField<float>(VT_TESTF_NINF, -std::numeric_limits<float>::infinity());
+ double d2() const {
+ return GetField<double>(VT_D2, std::numeric_limits<double>::infinity());
}
- bool mutate_testf_ninf(float _testf_ninf) {
- return SetField<float>(VT_TESTF_NINF, _testf_ninf, -std::numeric_limits<float>::infinity());
+ bool mutate_d2(double _d2) {
+ return SetField<double>(VT_D2, _d2, std::numeric_limits<double>::infinity());
}
- double testd_nan() const {
- return GetField<double>(VT_TESTD_NAN, std::numeric_limits<double>::quiet_NaN());
+ double d3() const {
+ return GetField<double>(VT_D3, -std::numeric_limits<double>::infinity());
}
- bool mutate_testd_nan(double _testd_nan) {
- return SetField<double>(VT_TESTD_NAN, _testd_nan, std::numeric_limits<double>::quiet_NaN());
+ bool mutate_d3(double _d3) {
+ return SetField<double>(VT_D3, _d3, -std::numeric_limits<double>::infinity());
}
- double testd_pinf() const {
- return GetField<double>(VT_TESTD_PINF, std::numeric_limits<double>::infinity());
+ float f0() const {
+ return GetField<float>(VT_F0, std::numeric_limits<float>::quiet_NaN());
}
- bool mutate_testd_pinf(double _testd_pinf) {
- return SetField<double>(VT_TESTD_PINF, _testd_pinf, std::numeric_limits<double>::infinity());
+ bool mutate_f0(float _f0) {
+ return SetField<float>(VT_F0, _f0, std::numeric_limits<float>::quiet_NaN());
}
- double testd_ninf() const {
- return GetField<double>(VT_TESTD_NINF, -std::numeric_limits<double>::infinity());
+ float f1() const {
+ return GetField<float>(VT_F1, std::numeric_limits<float>::quiet_NaN());
}
- bool mutate_testd_ninf(double _testd_ninf) {
- return SetField<double>(VT_TESTD_NINF, _testd_ninf, -std::numeric_limits<double>::infinity());
+ bool mutate_f1(float _f1) {
+ return SetField<float>(VT_F1, _f1, std::numeric_limits<float>::quiet_NaN());
+ }
+ float f2() const {
+ return GetField<float>(VT_F2, std::numeric_limits<float>::infinity());
+ }
+ bool mutate_f2(float _f2) {
+ return SetField<float>(VT_F2, _f2, std::numeric_limits<float>::infinity());
+ }
+ float f3() const {
+ return GetField<float>(VT_F3, -std::numeric_limits<float>::infinity());
+ }
+ bool mutate_f3(float _f3) {
+ return SetField<float>(VT_F3, _f3, -std::numeric_limits<float>::infinity());
+ }
+ const flatbuffers::Vector<double> *dvec() const {
+ return GetPointer<const flatbuffers::Vector<double> *>(VT_DVEC);
+ }
+ flatbuffers::Vector<double> *mutable_dvec() {
+ return GetPointer<flatbuffers::Vector<double> *>(VT_DVEC);
+ }
+ const flatbuffers::Vector<float> *fvec() const {
+ return GetPointer<const flatbuffers::Vector<float> *>(VT_FVEC);
+ }
+ flatbuffers::Vector<float> *mutable_fvec() {
+ return GetPointer<flatbuffers::Vector<float> *>(VT_FVEC);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
- VerifyField<float>(verifier, VT_TESTF_NAN) &&
- VerifyField<float>(verifier, VT_TESTF_PINF) &&
- VerifyField<float>(verifier, VT_TESTF_NINF) &&
- VerifyField<double>(verifier, VT_TESTD_NAN) &&
- VerifyField<double>(verifier, VT_TESTD_PINF) &&
- VerifyField<double>(verifier, VT_TESTD_NINF) &&
+ VerifyField<double>(verifier, VT_D0) &&
+ VerifyField<double>(verifier, VT_D1) &&
+ VerifyField<double>(verifier, VT_D2) &&
+ VerifyField<double>(verifier, VT_D3) &&
+ VerifyField<float>(verifier, VT_F0) &&
+ VerifyField<float>(verifier, VT_F1) &&
+ VerifyField<float>(verifier, VT_F2) &&
+ VerifyField<float>(verifier, VT_F3) &&
+ VerifyOffset(verifier, VT_DVEC) &&
+ verifier.VerifyVector(dvec()) &&
+ VerifyOffset(verifier, VT_FVEC) &&
+ verifier.VerifyVector(fvec()) &&
verifier.EndTable();
}
MonsterExtraT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
@@ -114,25 +160,38 @@ struct MonsterExtra FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct MonsterExtraBuilder {
+ typedef MonsterExtra Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
- void add_testf_nan(float testf_nan) {
- fbb_.AddElement<float>(MonsterExtra::VT_TESTF_NAN, testf_nan, std::numeric_limits<float>::quiet_NaN());
+ void add_d0(double d0) {
+ fbb_.AddElement<double>(MonsterExtra::VT_D0, d0, std::numeric_limits<double>::quiet_NaN());
+ }
+ void add_d1(double d1) {
+ fbb_.AddElement<double>(MonsterExtra::VT_D1, d1, std::numeric_limits<double>::quiet_NaN());
+ }
+ void add_d2(double d2) {
+ fbb_.AddElement<double>(MonsterExtra::VT_D2, d2, std::numeric_limits<double>::infinity());
+ }
+ void add_d3(double d3) {
+ fbb_.AddElement<double>(MonsterExtra::VT_D3, d3, -std::numeric_limits<double>::infinity());
+ }
+ void add_f0(float f0) {
+ fbb_.AddElement<float>(MonsterExtra::VT_F0, f0, std::numeric_limits<float>::quiet_NaN());
}
- void add_testf_pinf(float testf_pinf) {
- fbb_.AddElement<float>(MonsterExtra::VT_TESTF_PINF, testf_pinf, std::numeric_limits<float>::infinity());
+ void add_f1(float f1) {
+ fbb_.AddElement<float>(MonsterExtra::VT_F1, f1, std::numeric_limits<float>::quiet_NaN());
}
- void add_testf_ninf(float testf_ninf) {
- fbb_.AddElement<float>(MonsterExtra::VT_TESTF_NINF, testf_ninf, -std::numeric_limits<float>::infinity());
+ void add_f2(float f2) {
+ fbb_.AddElement<float>(MonsterExtra::VT_F2, f2, std::numeric_limits<float>::infinity());
}
- void add_testd_nan(double testd_nan) {
- fbb_.AddElement<double>(MonsterExtra::VT_TESTD_NAN, testd_nan, std::numeric_limits<double>::quiet_NaN());
+ void add_f3(float f3) {
+ fbb_.AddElement<float>(MonsterExtra::VT_F3, f3, -std::numeric_limits<float>::infinity());
}
- void add_testd_pinf(double testd_pinf) {
- fbb_.AddElement<double>(MonsterExtra::VT_TESTD_PINF, testd_pinf, std::numeric_limits<double>::infinity());
+ void add_dvec(flatbuffers::Offset<flatbuffers::Vector<double>> dvec) {
+ fbb_.AddOffset(MonsterExtra::VT_DVEC, dvec);
}
- void add_testd_ninf(double testd_ninf) {
- fbb_.AddElement<double>(MonsterExtra::VT_TESTD_NINF, testd_ninf, -std::numeric_limits<double>::infinity());
+ void add_fvec(flatbuffers::Offset<flatbuffers::Vector<float>> fvec) {
+ fbb_.AddOffset(MonsterExtra::VT_FVEC, fvec);
}
explicit MonsterExtraBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
@@ -148,39 +207,79 @@ struct MonsterExtraBuilder {
inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(
flatbuffers::FlatBufferBuilder &_fbb,
- float testf_nan = std::numeric_limits<float>::quiet_NaN(),
- float testf_pinf = std::numeric_limits<float>::infinity(),
- float testf_ninf = -std::numeric_limits<float>::infinity(),
- double testd_nan = std::numeric_limits<double>::quiet_NaN(),
- double testd_pinf = std::numeric_limits<double>::infinity(),
- double testd_ninf = -std::numeric_limits<double>::infinity()) {
+ double d0 = std::numeric_limits<double>::quiet_NaN(),
+ double d1 = std::numeric_limits<double>::quiet_NaN(),
+ double d2 = std::numeric_limits<double>::infinity(),
+ double d3 = -std::numeric_limits<double>::infinity(),
+ float f0 = std::numeric_limits<float>::quiet_NaN(),
+ float f1 = std::numeric_limits<float>::quiet_NaN(),
+ float f2 = std::numeric_limits<float>::infinity(),
+ float f3 = -std::numeric_limits<float>::infinity(),
+ flatbuffers::Offset<flatbuffers::Vector<double>> dvec = 0,
+ flatbuffers::Offset<flatbuffers::Vector<float>> fvec = 0) {
MonsterExtraBuilder builder_(_fbb);
- builder_.add_testd_ninf(testd_ninf);
- builder_.add_testd_pinf(testd_pinf);
- builder_.add_testd_nan(testd_nan);
- builder_.add_testf_ninf(testf_ninf);
- builder_.add_testf_pinf(testf_pinf);
- builder_.add_testf_nan(testf_nan);
+ builder_.add_d3(d3);
+ builder_.add_d2(d2);
+ builder_.add_d1(d1);
+ builder_.add_d0(d0);
+ builder_.add_fvec(fvec);
+ builder_.add_dvec(dvec);
+ builder_.add_f3(f3);
+ builder_.add_f2(f2);
+ builder_.add_f1(f1);
+ builder_.add_f0(f0);
return builder_.Finish();
}
+inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtraDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ double d0 = std::numeric_limits<double>::quiet_NaN(),
+ double d1 = std::numeric_limits<double>::quiet_NaN(),
+ double d2 = std::numeric_limits<double>::infinity(),
+ double d3 = -std::numeric_limits<double>::infinity(),
+ float f0 = std::numeric_limits<float>::quiet_NaN(),
+ float f1 = std::numeric_limits<float>::quiet_NaN(),
+ float f2 = std::numeric_limits<float>::infinity(),
+ float f3 = -std::numeric_limits<float>::infinity(),
+ const std::vector<double> *dvec = nullptr,
+ const std::vector<float> *fvec = nullptr) {
+ auto dvec__ = dvec ? _fbb.CreateVector<double>(*dvec) : 0;
+ auto fvec__ = fvec ? _fbb.CreateVector<float>(*fvec) : 0;
+ return MyGame::CreateMonsterExtra(
+ _fbb,
+ d0,
+ d1,
+ d2,
+ d3,
+ f0,
+ f1,
+ f2,
+ f3,
+ dvec__,
+ fvec__);
+}
+
flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline MonsterExtraT *MonsterExtra::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new MonsterExtraT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::MonsterExtraT> _o = flatbuffers::unique_ptr<MyGame::MonsterExtraT>(new MonsterExtraT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void MonsterExtra::UnPackTo(MonsterExtraT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = testf_nan(); _o->testf_nan = _e; };
- { auto _e = testf_pinf(); _o->testf_pinf = _e; };
- { auto _e = testf_ninf(); _o->testf_ninf = _e; };
- { auto _e = testd_nan(); _o->testd_nan = _e; };
- { auto _e = testd_pinf(); _o->testd_pinf = _e; };
- { auto _e = testd_ninf(); _o->testd_ninf = _e; };
+ { auto _e = d0(); _o->d0 = _e; }
+ { auto _e = d1(); _o->d1 = _e; }
+ { auto _e = d2(); _o->d2 = _e; }
+ { auto _e = d3(); _o->d3 = _e; }
+ { auto _e = f0(); _o->f0 = _e; }
+ { auto _e = f1(); _o->f1 = _e; }
+ { auto _e = f2(); _o->f2 = _e; }
+ { auto _e = f3(); _o->f3 = _e; }
+ { auto _e = dvec(); if (_e) { _o->dvec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->dvec[_i] = _e->Get(_i); } } }
+ { auto _e = fvec(); if (_e) { _o->fvec.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->fvec[_i] = _e->Get(_i); } } }
}
inline flatbuffers::Offset<MonsterExtra> MonsterExtra::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterExtraT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -191,45 +290,122 @@ inline flatbuffers::Offset<MonsterExtra> CreateMonsterExtra(flatbuffers::FlatBuf
(void)_rehasher;
(void)_o;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterExtraT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
- auto _testf_nan = _o->testf_nan;
- auto _testf_pinf = _o->testf_pinf;
- auto _testf_ninf = _o->testf_ninf;
- auto _testd_nan = _o->testd_nan;
- auto _testd_pinf = _o->testd_pinf;
- auto _testd_ninf = _o->testd_ninf;
+ auto _d0 = _o->d0;
+ auto _d1 = _o->d1;
+ auto _d2 = _o->d2;
+ auto _d3 = _o->d3;
+ auto _f0 = _o->f0;
+ auto _f1 = _o->f1;
+ auto _f2 = _o->f2;
+ auto _f3 = _o->f3;
+ auto _dvec = _o->dvec.size() ? _fbb.CreateVector(_o->dvec) : 0;
+ auto _fvec = _o->fvec.size() ? _fbb.CreateVector(_o->fvec) : 0;
return MyGame::CreateMonsterExtra(
_fbb,
- _testf_nan,
- _testf_pinf,
- _testf_ninf,
- _testd_nan,
- _testd_pinf,
- _testd_ninf);
+ _d0,
+ _d1,
+ _d2,
+ _d3,
+ _f0,
+ _f1,
+ _f2,
+ _f3,
+ _dvec,
+ _fvec);
}
inline const flatbuffers::TypeTable *MonsterExtraTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_DOUBLE, 0, -1 },
+ { flatbuffers::ET_DOUBLE, 0, -1 },
+ { flatbuffers::ET_DOUBLE, 0, -1 },
+ { flatbuffers::ET_DOUBLE, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
- { flatbuffers::ET_DOUBLE, 0, -1 },
- { flatbuffers::ET_DOUBLE, 0, -1 },
- { flatbuffers::ET_DOUBLE, 0, -1 }
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_DOUBLE, 1, -1 },
+ { flatbuffers::ET_FLOAT, 1, -1 },
+ { flatbuffers::ET_INT, 0, -1 }
};
static const char * const names[] = {
- "testf_nan",
- "testf_pinf",
- "testf_ninf",
- "testd_nan",
- "testd_pinf",
- "testd_ninf"
+ "d0",
+ "d1",
+ "d2",
+ "d3",
+ "f0",
+ "f1",
+ "f2",
+ "f3",
+ "dvec",
+ "fvec",
+ "deprec"
};
static const flatbuffers::TypeTable tt = {
- flatbuffers::ST_TABLE, 6, type_codes, nullptr, nullptr, names
+ flatbuffers::ST_TABLE, 11, type_codes, nullptr, nullptr, names
};
return &tt;
}
+inline const MyGame::MonsterExtra *GetMonsterExtra(const void *buf) {
+ return flatbuffers::GetRoot<MyGame::MonsterExtra>(buf);
+}
+
+inline const MyGame::MonsterExtra *GetSizePrefixedMonsterExtra(const void *buf) {
+ return flatbuffers::GetSizePrefixedRoot<MyGame::MonsterExtra>(buf);
+}
+
+inline MonsterExtra *GetMutableMonsterExtra(void *buf) {
+ return flatbuffers::GetMutableRoot<MonsterExtra>(buf);
+}
+
+inline const char *MonsterExtraIdentifier() {
+ return "MONE";
+}
+
+inline bool MonsterExtraBufferHasIdentifier(const void *buf) {
+ return flatbuffers::BufferHasIdentifier(
+ buf, MonsterExtraIdentifier());
+}
+
+inline bool VerifyMonsterExtraBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifyBuffer<MyGame::MonsterExtra>(MonsterExtraIdentifier());
+}
+
+inline bool VerifySizePrefixedMonsterExtraBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifySizePrefixedBuffer<MyGame::MonsterExtra>(MonsterExtraIdentifier());
+}
+
+inline const char *MonsterExtraExtension() {
+ return "mon";
+}
+
+inline void FinishMonsterExtraBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<MyGame::MonsterExtra> root) {
+ fbb.Finish(root, MonsterExtraIdentifier());
+}
+
+inline void FinishSizePrefixedMonsterExtraBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<MyGame::MonsterExtra> root) {
+ fbb.FinishSizePrefixed(root, MonsterExtraIdentifier());
+}
+
+inline flatbuffers::unique_ptr<MyGame::MonsterExtraT> UnPackMonsterExtra(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<MyGame::MonsterExtraT>(GetMonsterExtra(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::MonsterExtraT> UnPackSizePrefixedMonsterExtra(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<MyGame::MonsterExtraT>(GetSizePrefixedMonsterExtra(buf)->UnPack(res));
+}
+
} // namespace MyGame
#endif // FLATBUFFERS_GENERATED_MONSTEREXTRA_MYGAME_H_
diff --git a/tests/monster_extra_my_game_generated.dart b/tests/monster_extra_my_game_generated.dart
new file mode 100644
index 00000000..676641de
--- /dev/null
+++ b/tests/monster_extra_my_game_generated.dart
@@ -0,0 +1,176 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+// ignore_for_file: unused_import, unused_field, unused_local_variable
+
+library my_game;
+
+import 'dart:typed_data' show Uint8List;
+import 'package:flat_buffers/flat_buffers.dart' as fb;
+
+
+class MonsterExtra {
+ MonsterExtra._(this._bc, this._bcOffset);
+ factory MonsterExtra(List<int> bytes) {
+ fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
+ return reader.read(rootRef, 0);
+ }
+
+ static const fb.Reader<MonsterExtra> reader = const _MonsterExtraReader();
+
+ final fb.BufferContext _bc;
+ final int _bcOffset;
+
+ double get d0 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 4, double.nan);
+ double get d1 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 6, double.nan);
+ double get d2 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 8, double.infinity);
+ double get d3 => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 10, double.negativeInfinity);
+ double get f0 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 12, double.nan);
+ double get f1 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 14, double.nan);
+ double get f2 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 16, double.infinity);
+ double get f3 => const fb.Float32Reader().vTableGet(_bc, _bcOffset, 18, double.negativeInfinity);
+ List<double> get dvec => const fb.ListReader<double>(const fb.Float64Reader()).vTableGet(_bc, _bcOffset, 20, null);
+ List<double> get fvec => const fb.ListReader<double>(const fb.Float32Reader()).vTableGet(_bc, _bcOffset, 22, null);
+
+ @override
+ String toString() {
+ return 'MonsterExtra{d0: $d0, d1: $d1, d2: $d2, d3: $d3, f0: $f0, f1: $f1, f2: $f2, f3: $f3, dvec: $dvec, fvec: $fvec}';
+ }
+}
+
+class _MonsterExtraReader extends fb.TableReader<MonsterExtra> {
+ const _MonsterExtraReader();
+
+ @override
+ MonsterExtra createObject(fb.BufferContext bc, int offset) =>
+ new MonsterExtra._(bc, offset);
+}
+
+class MonsterExtraBuilder {
+ MonsterExtraBuilder(this.fbBuilder) {
+ assert(fbBuilder != null);
+ }
+
+ final fb.Builder fbBuilder;
+
+ void begin() {
+ fbBuilder.startTable();
+ }
+
+ int addD0(double d0) {
+ fbBuilder.addFloat64(0, d0);
+ return fbBuilder.offset;
+ }
+ int addD1(double d1) {
+ fbBuilder.addFloat64(1, d1);
+ return fbBuilder.offset;
+ }
+ int addD2(double d2) {
+ fbBuilder.addFloat64(2, d2);
+ return fbBuilder.offset;
+ }
+ int addD3(double d3) {
+ fbBuilder.addFloat64(3, d3);
+ return fbBuilder.offset;
+ }
+ int addF0(double f0) {
+ fbBuilder.addFloat32(4, f0);
+ return fbBuilder.offset;
+ }
+ int addF1(double f1) {
+ fbBuilder.addFloat32(5, f1);
+ return fbBuilder.offset;
+ }
+ int addF2(double f2) {
+ fbBuilder.addFloat32(6, f2);
+ return fbBuilder.offset;
+ }
+ int addF3(double f3) {
+ fbBuilder.addFloat32(7, f3);
+ return fbBuilder.offset;
+ }
+ int addDvecOffset(int offset) {
+ fbBuilder.addOffset(8, offset);
+ return fbBuilder.offset;
+ }
+ int addFvecOffset(int offset) {
+ fbBuilder.addOffset(9, offset);
+ return fbBuilder.offset;
+ }
+
+ int finish() {
+ return fbBuilder.endTable();
+ }
+}
+
+class MonsterExtraObjectBuilder extends fb.ObjectBuilder {
+ final double _d0;
+ final double _d1;
+ final double _d2;
+ final double _d3;
+ final double _f0;
+ final double _f1;
+ final double _f2;
+ final double _f3;
+ final List<double> _dvec;
+ final List<double> _fvec;
+
+ MonsterExtraObjectBuilder({
+ double d0,
+ double d1,
+ double d2,
+ double d3,
+ double f0,
+ double f1,
+ double f2,
+ double f3,
+ List<double> dvec,
+ List<double> fvec,
+ })
+ : _d0 = d0,
+ _d1 = d1,
+ _d2 = d2,
+ _d3 = d3,
+ _f0 = f0,
+ _f1 = f1,
+ _f2 = f2,
+ _f3 = f3,
+ _dvec = dvec,
+ _fvec = fvec;
+
+ /// Finish building, and store into the [fbBuilder].
+ @override
+ int finish(
+ fb.Builder fbBuilder) {
+ assert(fbBuilder != null);
+ final int dvecOffset = _dvec?.isNotEmpty == true
+ ? fbBuilder.writeListFloat64(_dvec)
+ : null;
+ final int fvecOffset = _fvec?.isNotEmpty == true
+ ? fbBuilder.writeListFloat32(_fvec)
+ : null;
+
+ fbBuilder.startTable();
+ fbBuilder.addFloat64(0, _d0);
+ fbBuilder.addFloat64(1, _d1);
+ fbBuilder.addFloat64(2, _d2);
+ fbBuilder.addFloat64(3, _d3);
+ fbBuilder.addFloat32(4, _f0);
+ fbBuilder.addFloat32(5, _f1);
+ fbBuilder.addFloat32(6, _f2);
+ fbBuilder.addFloat32(7, _f3);
+ if (dvecOffset != null) {
+ fbBuilder.addOffset(8, dvecOffset);
+ }
+ if (fvecOffset != null) {
+ fbBuilder.addOffset(9, fvecOffset);
+ }
+ return fbBuilder.endTable();
+ }
+
+ /// Convenience method to serialize to byte list.
+ @override
+ Uint8List toBytes([String fileIdentifier]) {
+ fb.Builder fbBuilder = new fb.Builder();
+ int offset = finish(fbBuilder);
+ return fbBuilder.finish(offset, fileIdentifier);
+ }
+}
diff --git a/tests/monster_test.bfbs b/tests/monster_test.bfbs
index fefdd2c7..84f24470 100644
--- a/tests/monster_test.bfbs
+++ b/tests/monster_test.bfbs
Binary files differ
diff --git a/tests/monster_test.fbs b/tests/monster_test.fbs
index d5718534..094de8ca 100644
--- a/tests/monster_test.fbs
+++ b/tests/monster_test.fbs
@@ -14,11 +14,26 @@ namespace MyGame.Example;
attribute "priority";
-enum Color:byte (bit_flags) { Red = 0, Green, Blue = 3, }
+/// Composite components of Monster color.
+enum Color:ubyte (bit_flags) {
+ Red = 0, // color Red = (1u << 0)
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
+ Green,
+ /// \brief color Blue (1u << 3)
+ Blue = 3,
+}
+
+enum Race:byte {
+ None = -1,
+ Human = 0,
+ Dwarf,
+ Elf,
+}
union Any { Monster, TestSimpleTableWithEnum, MyGame.Example2.Monster }
-union AnyUniqueAliases { M: Monster, T: TestSimpleTableWithEnum, M2: MyGame.Example2.Monster }
+union AnyUniqueAliases { M: Monster, TS: TestSimpleTableWithEnum, M2: MyGame.Example2.Monster }
union AnyAmbiguousAliases { M1: Monster, M2: Monster, M3: Monster }
struct Test { a:short; b:byte; }
@@ -51,7 +66,7 @@ table Referrable {
id:ulong(key, hash:"fnv1a_64");
}
-/// an example documentation comment: monster object
+/// an example documentation comment: "monster object"
table Monster {
pos:Vec3 (id: 0);
hp:short = 100 (id: 2);
@@ -100,6 +115,7 @@ table Monster {
any_unique:AnyUniqueAliases(id:44);
any_ambiguous:AnyAmbiguousAliases (id:46);
vector_of_enums:[Color] (id:47);
+ signed_enum:Race = None (id:48);
}
table TypeAliases {
diff --git a/tests/monster_test.schema.json b/tests/monster_test.schema.json
index 0a53acc1..0c7d30de 100644
--- a/tests/monster_test.schema.json
+++ b/tests/monster_test.schema.json
@@ -9,13 +9,17 @@
"type" : "string",
"enum": ["Red", "Green", "Blue"]
},
+ "MyGame_Example_Race" : {
+ "type" : "string",
+ "enum": ["None", "Human", "Dwarf", "Elf"]
+ },
"MyGame_Example_Any" : {
"type" : "string",
"enum": ["NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster"]
},
"MyGame_Example_AnyUniqueAliases" : {
"type" : "string",
- "enum": ["NONE", "M", "T", "M2"]
+ "enum": ["NONE", "M", "TS", "M2"]
},
"MyGame_Example_AnyAmbiguousAliases" : {
"type" : "string",
@@ -24,21 +28,27 @@
"MyGame_OtherNameSpace_Unused" : {
"type" : "object",
"properties" : {
- "a" : { "type" : "number" }
+ "a" : {
+ "type" : "number"
+ }
},
"additionalProperties" : false
},
"MyGame_OtherNameSpace_TableB" : {
"type" : "object",
"properties" : {
- "a" : { "$ref" : "#/definitions/TableA" }
+ "a" : {
+ "$ref" : "#/definitions/TableA"
+ }
},
"additionalProperties" : false
},
"TableA" : {
"type" : "object",
"properties" : {
- "b" : { "$ref" : "#/definitions/MyGame_OtherNameSpace_TableB" }
+ "b" : {
+ "$ref" : "#/definitions/MyGame_OtherNameSpace_TableB"
+ }
},
"additionalProperties" : false
},
@@ -57,106 +67,235 @@
"MyGame_Example_Test" : {
"type" : "object",
"properties" : {
- "a" : { "type" : "number" },
- "b" : { "type" : "number" }
+ "a" : {
+ "type" : "number"
+ },
+ "b" : {
+ "type" : "number"
+ }
},
"additionalProperties" : false
},
"MyGame_Example_TestSimpleTableWithEnum" : {
"type" : "object",
"properties" : {
- "color" : { "$ref" : "#/definitions/MyGame_Example_Color" }
+ "color" : {
+ "$ref" : "#/definitions/MyGame_Example_Color"
+ }
},
"additionalProperties" : false
},
"MyGame_Example_Vec3" : {
"type" : "object",
"properties" : {
- "x" : { "type" : "number" },
- "y" : { "type" : "number" },
- "z" : { "type" : "number" },
- "test1" : { "type" : "number" },
- "test2" : { "$ref" : "#/definitions/MyGame_Example_Color" },
- "test3" : { "$ref" : "#/definitions/MyGame_Example_Test" }
+ "x" : {
+ "type" : "number"
+ },
+ "y" : {
+ "type" : "number"
+ },
+ "z" : {
+ "type" : "number"
+ },
+ "test1" : {
+ "type" : "number"
+ },
+ "test2" : {
+ "$ref" : "#/definitions/MyGame_Example_Color"
+ },
+ "test3" : {
+ "$ref" : "#/definitions/MyGame_Example_Test"
+ }
},
"additionalProperties" : false
},
"MyGame_Example_Ability" : {
"type" : "object",
"properties" : {
- "id" : { "type" : "number" },
- "distance" : { "type" : "number" }
+ "id" : {
+ "type" : "number"
+ },
+ "distance" : {
+ "type" : "number"
+ }
},
"additionalProperties" : false
},
"MyGame_Example_Stat" : {
"type" : "object",
"properties" : {
- "id" : { "type" : "string" },
- "val" : { "type" : "number" },
- "count" : { "type" : "number" }
+ "id" : {
+ "type" : "string"
+ },
+ "val" : {
+ "type" : "number"
+ },
+ "count" : {
+ "type" : "number"
+ }
},
"additionalProperties" : false
},
"MyGame_Example_Referrable" : {
"type" : "object",
"properties" : {
- "id" : { "type" : "number" }
+ "id" : {
+ "type" : "number"
+ }
},
"additionalProperties" : false
},
"MyGame_Example_Monster" : {
"type" : "object",
- "description" : " an example documentation comment: monster object",
+ "description" : " an example documentation comment: \"monster object\"",
"properties" : {
- "pos" : { "$ref" : "#/definitions/MyGame_Example_Vec3" },
- "mana" : { "type" : "number" },
- "hp" : { "type" : "number" },
- "name" : { "type" : "string" },
- "friendly" : { "type" : "boolean" },
- "inventory" : { "type" : "array", "items" : { "type" : "number" } },
- "color" : { "$ref" : "#/definitions/MyGame_Example_Color" },
- "test_type" : { "$ref" : "#/definitions/MyGame_Example_Any" },
- "test" : { "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_TestSimpleTableWithEnum" },{ "$ref" : "#/definitions/MyGame_Example2_Monster" }] },
- "test4" : { "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Test" } },
- "testarrayofstring" : { "type" : "array", "items" : { "type" : "string" } },
- "testarrayoftables" : { "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Monster" } },
- "enemy" : { "$ref" : "#/definitions/MyGame_Example_Monster" },
- "testnestedflatbuffer" : { "type" : "array", "items" : { "type" : "number" } },
- "testempty" : { "$ref" : "#/definitions/MyGame_Example_Stat" },
- "testbool" : { "type" : "boolean" },
- "testhashs32_fnv1" : { "type" : "number" },
- "testhashu32_fnv1" : { "type" : "number" },
- "testhashs64_fnv1" : { "type" : "number" },
- "testhashu64_fnv1" : { "type" : "number" },
- "testhashs32_fnv1a" : { "type" : "number" },
- "testhashu32_fnv1a" : { "type" : "number" },
- "testhashs64_fnv1a" : { "type" : "number" },
- "testhashu64_fnv1a" : { "type" : "number" },
- "testarrayofbools" : { "type" : "array", "items" : { "type" : "boolean" } },
- "testf" : { "type" : "number" },
- "testf2" : { "type" : "number" },
- "testf3" : { "type" : "number" },
- "testarrayofstring2" : { "type" : "array", "items" : { "type" : "string" } },
- "testarrayofsortedstruct" : { "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Ability" } },
- "flex" : { "type" : "array", "items" : { "type" : "number" } },
- "test5" : { "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Test" } },
- "vector_of_longs" : { "type" : "array", "items" : { "type" : "number" } },
- "vector_of_doubles" : { "type" : "array", "items" : { "type" : "number" } },
- "parent_namespace_test" : { "$ref" : "#/definitions/MyGame_InParentNamespace" },
- "vector_of_referrables" : { "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Referrable" } },
- "single_weak_reference" : { "type" : "number" },
- "vector_of_weak_references" : { "type" : "array", "items" : { "type" : "number" } },
- "vector_of_strong_referrables" : { "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Referrable" } },
- "co_owning_reference" : { "type" : "number" },
- "vector_of_co_owning_references" : { "type" : "array", "items" : { "type" : "number" } },
- "non_owning_reference" : { "type" : "number" },
- "vector_of_non_owning_references" : { "type" : "array", "items" : { "type" : "number" } },
- "any_unique_type" : { "$ref" : "#/definitions/MyGame_Example_AnyUniqueAliases" },
- "any_unique" : { "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_TestSimpleTableWithEnum" },{ "$ref" : "#/definitions/MyGame_Example2_Monster" }] },
- "any_ambiguous_type" : { "$ref" : "#/definitions/MyGame_Example_AnyAmbiguousAliases" },
- "any_ambiguous" : { "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_Monster" }] },
- "vector_of_enums" : { "$ref" : "#/definitions/MyGame_Example_Color" }
+ "pos" : {
+ "$ref" : "#/definitions/MyGame_Example_Vec3"
+ },
+ "mana" : {
+ "type" : "number"
+ },
+ "hp" : {
+ "type" : "number"
+ },
+ "name" : {
+ "type" : "string"
+ },
+ "friendly" : {
+ "type" : "boolean"
+ },
+ "inventory" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "color" : {
+ "$ref" : "#/definitions/MyGame_Example_Color"
+ },
+ "test_type" : {
+ "$ref" : "#/definitions/MyGame_Example_Any"
+ },
+ "test" : {
+ "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_TestSimpleTableWithEnum" },{ "$ref" : "#/definitions/MyGame_Example2_Monster" }]
+ },
+ "test4" : {
+ "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Test" }
+ },
+ "testarrayofstring" : {
+ "type" : "array", "items" : { "type" : "string" }
+ },
+ "testarrayoftables" : {
+ "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Monster" }
+ },
+ "enemy" : {
+ "$ref" : "#/definitions/MyGame_Example_Monster"
+ },
+ "testnestedflatbuffer" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "testempty" : {
+ "$ref" : "#/definitions/MyGame_Example_Stat"
+ },
+ "testbool" : {
+ "type" : "boolean"
+ },
+ "testhashs32_fnv1" : {
+ "type" : "number"
+ },
+ "testhashu32_fnv1" : {
+ "type" : "number"
+ },
+ "testhashs64_fnv1" : {
+ "type" : "number"
+ },
+ "testhashu64_fnv1" : {
+ "type" : "number"
+ },
+ "testhashs32_fnv1a" : {
+ "type" : "number"
+ },
+ "testhashu32_fnv1a" : {
+ "type" : "number"
+ },
+ "testhashs64_fnv1a" : {
+ "type" : "number"
+ },
+ "testhashu64_fnv1a" : {
+ "type" : "number"
+ },
+ "testarrayofbools" : {
+ "type" : "array", "items" : { "type" : "boolean" }
+ },
+ "testf" : {
+ "type" : "number"
+ },
+ "testf2" : {
+ "type" : "number"
+ },
+ "testf3" : {
+ "type" : "number"
+ },
+ "testarrayofstring2" : {
+ "type" : "array", "items" : { "type" : "string" }
+ },
+ "testarrayofsortedstruct" : {
+ "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Ability" }
+ },
+ "flex" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "test5" : {
+ "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Test" }
+ },
+ "vector_of_longs" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "vector_of_doubles" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "parent_namespace_test" : {
+ "$ref" : "#/definitions/MyGame_InParentNamespace"
+ },
+ "vector_of_referrables" : {
+ "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Referrable" }
+ },
+ "single_weak_reference" : {
+ "type" : "number"
+ },
+ "vector_of_weak_references" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "vector_of_strong_referrables" : {
+ "type" : "array", "items" : { "$ref" : "#/definitions/MyGame_Example_Referrable" }
+ },
+ "co_owning_reference" : {
+ "type" : "number"
+ },
+ "vector_of_co_owning_references" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "non_owning_reference" : {
+ "type" : "number"
+ },
+ "vector_of_non_owning_references" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "any_unique_type" : {
+ "$ref" : "#/definitions/MyGame_Example_AnyUniqueAliases"
+ },
+ "any_unique" : {
+ "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_TestSimpleTableWithEnum" },{ "$ref" : "#/definitions/MyGame_Example2_Monster" }]
+ },
+ "any_ambiguous_type" : {
+ "$ref" : "#/definitions/MyGame_Example_AnyAmbiguousAliases"
+ },
+ "any_ambiguous" : {
+ "anyOf": [{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_Monster" },{ "$ref" : "#/definitions/MyGame_Example_Monster" }]
+ },
+ "vector_of_enums" : {
+ "$ref" : "#/definitions/MyGame_Example_Color"
+ },
+ "signed_enum" : {
+ "$ref" : "#/definitions/MyGame_Example_Race"
+ }
},
"required" : ["name"],
"additionalProperties" : false
@@ -164,18 +303,42 @@
"MyGame_Example_TypeAliases" : {
"type" : "object",
"properties" : {
- "i8" : { "type" : "number" },
- "u8" : { "type" : "number" },
- "i16" : { "type" : "number" },
- "u16" : { "type" : "number" },
- "i32" : { "type" : "number" },
- "u32" : { "type" : "number" },
- "i64" : { "type" : "number" },
- "u64" : { "type" : "number" },
- "f32" : { "type" : "number" },
- "f64" : { "type" : "number" },
- "v8" : { "type" : "array", "items" : { "type" : "number" } },
- "vf64" : { "type" : "array", "items" : { "type" : "number" } }
+ "i8" : {
+ "type" : "number"
+ },
+ "u8" : {
+ "type" : "number"
+ },
+ "i16" : {
+ "type" : "number"
+ },
+ "u16" : {
+ "type" : "number"
+ },
+ "i32" : {
+ "type" : "number"
+ },
+ "u32" : {
+ "type" : "number"
+ },
+ "i64" : {
+ "type" : "number"
+ },
+ "u64" : {
+ "type" : "number"
+ },
+ "f32" : {
+ "type" : "number"
+ },
+ "f64" : {
+ "type" : "number"
+ },
+ "v8" : {
+ "type" : "array", "items" : { "type" : "number" }
+ },
+ "vf64" : {
+ "type" : "array", "items" : { "type" : "number" }
+ }
},
"additionalProperties" : false
}
diff --git a/tests/monster_test_bfbs_generated.h b/tests/monster_test_bfbs_generated.h
new file mode 100644
index 00000000..07acbe42
--- /dev/null
+++ b/tests/monster_test_bfbs_generated.h
@@ -0,0 +1,640 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_BFBS_H_
+#define FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_BFBS_H_
+
+namespace MyGame {
+namespace Example {
+
+struct MonsterBinarySchema {
+ static const uint8_t *data() {
+ // Buffer containing the binary schema.
+ static const uint8_t bfbsData[12176] = {
+ 0x18,0x00,0x00,0x00,0x42,0x46,0x42,0x53,0x10,0x00,0x1C,0x00,0x04,0x00,0x08,0x00,0x0C,0x00,0x10,0x00,
+ 0x14,0x00,0x18,0x00,0x10,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+ 0x14,0x00,0x00,0x00,0xF8,0x0B,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x78,0x00,0x00,0x00,
+ 0x03,0x00,0x00,0x00,0x6D,0x6F,0x6E,0x00,0x04,0x00,0x00,0x00,0x4D,0x4F,0x4E,0x53,0x00,0x00,0x00,0x00,
+ 0x06,0x00,0x00,0x00,0xCC,0x04,0x00,0x00,0x50,0x02,0x00,0x00,0x78,0x03,0x00,0x00,0x18,0x07,0x00,0x00,
+ 0x0C,0x06,0x00,0x00,0xE0,0x08,0x00,0x00,0x0D,0x00,0x00,0x00,0xDC,0x28,0x00,0x00,0xB0,0x0B,0x00,0x00,
+ 0x44,0x27,0x00,0x00,0x14,0x28,0x00,0x00,0x54,0x2C,0x00,0x00,0x50,0x2B,0x00,0x00,0x4C,0x09,0x00,0x00,
+ 0xB4,0x29,0x00,0x00,0xF0,0x2C,0x00,0x00,0x24,0x2D,0x00,0x00,0xC4,0x2D,0x00,0x00,0x64,0x2E,0x00,0x00,
+ 0x54,0x2D,0x00,0x00,0x0C,0x00,0x10,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,
+ 0x24,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x88,0x01,0x00,0x00,0xF4,0x00,0x00,0x00,0x90,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x1D,0x00,0x00,0x00,
+ 0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x4D,0x6F,0x6E,0x73,0x74,
+ 0x65,0x72,0x53,0x74,0x6F,0x72,0x61,0x67,0x65,0x00,0x00,0x00,0xBA,0xFE,0xFF,0xFF,0x48,0x00,0x00,0x00,
+ 0x20,0x0B,0x00,0x00,0x88,0x27,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0xD5,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x62,0x69,0x64,0x69,0x00,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x73,0x74,0x72,0x65,
+ 0x61,0x6D,0x69,0x6E,0x67,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x47,0x65,0x74,0x4D,0x69,0x6E,0x4D,0x61,
+ 0x78,0x48,0x69,0x74,0x50,0x6F,0x69,0x6E,0x74,0x73,0x00,0x00,0x1E,0xFF,0xFF,0xFF,0x48,0x00,0x00,0x00,
+ 0xBC,0x0A,0x00,0x00,0x24,0x27,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x68,0xD5,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x06,0x00,0x00,0x00,0x63,0x6C,0x69,0x65,0x6E,0x74,0x00,0x00,0x09,0x00,0x00,0x00,0x73,0x74,0x72,0x65,
+ 0x61,0x6D,0x69,0x6E,0x67,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x47,0x65,0x74,0x4D,0x61,0x78,0x48,0x69,
+ 0x74,0x50,0x6F,0x69,0x6E,0x74,0x00,0x00,0x7E,0xFF,0xFF,0xFF,0x70,0x00,0x00,0x00,0xC8,0x26,0x00,0x00,
+ 0x58,0x0A,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x30,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xCC,0xD5,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x06,0x00,0x00,0x00,0x73,0x65,0x72,0x76,0x65,0x72,0x00,0x00,0x09,0x00,0x00,0x00,0x73,0x74,0x72,0x65,
+ 0x61,0x6D,0x69,0x6E,0x67,0x00,0x00,0x00,0xF4,0xD5,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x69,0x64,0x65,0x6D,0x70,0x6F,0x74,0x65,
+ 0x6E,0x74,0x00,0x00,0x08,0x00,0x00,0x00,0x52,0x65,0x74,0x72,0x69,0x65,0x76,0x65,0x00,0x00,0x0E,0x00,
+ 0x18,0x00,0x04,0x00,0x08,0x00,0x0C,0x00,0x10,0x00,0x14,0x00,0x0E,0x00,0x00,0x00,0x48,0x00,0x00,0x00,
+ 0xCC,0x09,0x00,0x00,0x34,0x26,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x58,0xD6,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x6E,0x6F,0x6E,0x65,0x00,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x73,0x74,0x72,0x65,
+ 0x61,0x6D,0x69,0x6E,0x67,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x53,0x74,0x6F,0x72,0x65,0x00,0x00,0x00,
+ 0x98,0xFD,0xFF,0xFF,0x00,0x00,0x00,0x01,0x34,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF2,0xD3,0xFF,0xFF,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0xDC,0x00,0x00,0x00,0xA4,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,
+ 0x22,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x41,
+ 0x6E,0x79,0x41,0x6D,0x62,0x69,0x67,0x75,0x6F,0x75,0x73,0x41,0x6C,0x69,0x61,0x73,0x65,0x73,0x00,0x00,
+ 0x66,0xFE,0xFF,0xFF,0x2C,0x00,0x00,0x00,0x10,0x09,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+ 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0xD4,0xFF,0xFF,
+ 0x00,0x00,0x00,0x0F,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x4D,0x33,0x00,0x00,0x9E,0xFE,0xFF,0xFF,
+ 0x2C,0x00,0x00,0x00,0xD8,0x08,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x96,0xD4,0xFF,0xFF,0x00,0x00,0x00,0x0F,
+ 0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x4D,0x32,0x00,0x00,0x76,0xFD,0xFF,0xFF,0x28,0x00,0x00,0x00,
+ 0xA0,0x08,0x00,0x00,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xCA,0xD4,0xFF,0xFF,0x00,0x00,0x00,0x0F,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x4D,0x31,0x00,0x00,0x16,0xFA,0xFF,0xFF,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x08,0xFA,0xFF,0xFF,0x04,0x00,0x00,0x00,0x4E,0x4F,0x4E,0x45,0x00,0x00,0x00,0x00,
+ 0xC4,0xFE,0xFF,0xFF,0x00,0x00,0x00,0x01,0x34,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0xD5,0xFF,0xFF,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0xEC,0x00,0x00,0x00,0xB0,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x28,0x00,0x00,0x00,
+ 0x1F,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x41,
+ 0x6E,0x79,0x55,0x6E,0x69,0x71,0x75,0x65,0x41,0x6C,0x69,0x61,0x73,0x65,0x73,0x00,0x8E,0xFF,0xFF,0xFF,
+ 0x2C,0x00,0x00,0x00,0x44,0x29,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x86,0xD5,0xFF,0xFF,0x00,0x00,0x00,0x0F,
+ 0x08,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x4D,0x32,0x00,0x00,0xC6,0xFF,0xFF,0xFF,0x2C,0x00,0x00,0x00,
+ 0x60,0x27,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBE,0xD5,0xFF,0xFF,0x00,0x00,0x00,0x0F,0x05,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x54,0x53,0x00,0x00,0x00,0x00,0x0E,0x00,0x20,0x00,0x04,0x00,0x14,0x00,0x08,0x00,
+ 0x0C,0x00,0x10,0x00,0x0E,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,0x68,0x07,0x00,0x00,0x18,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x06,0xD6,0xFF,0xFF,0x00,0x00,0x00,0x0F,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x4D,0x00,0x00,0x00,
+ 0x52,0xFB,0xFF,0xFF,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x44,0xFB,0xFF,0xFF,0x04,0x00,0x00,0x00,0x4E,0x4F,0x4E,0x45,0x00,0x00,0x00,0x00,0x10,0x00,0x18,0x00,
+ 0x08,0x00,0x0C,0x00,0x07,0x00,0x10,0x00,0x00,0x00,0x14,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x34,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x6A,0xD6,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
+ 0xC4,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,
+ 0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x41,0x6E,0x79,0x00,0x00,0x6E,0xFF,0xFF,0xFF,
+ 0x28,0x00,0x00,0x00,0x04,0x28,0x00,0x00,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC2,0xD6,0xFF,0xFF,0x00,0x00,0x00,0x0F,0x08,0x00,0x00,0x00,
+ 0x17,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x5F,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x32,0x5F,
+ 0x4D,0x6F,0x6E,0x73,0x74,0x65,0x72,0x00,0xB6,0xFF,0xFF,0xFF,0x28,0x00,0x00,0x00,0x10,0x26,0x00,0x00,
+ 0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x0A,0xD7,0xFF,0xFF,0x00,0x00,0x00,0x0F,0x05,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x54,0x65,0x73,0x74,
+ 0x53,0x69,0x6D,0x70,0x6C,0x65,0x54,0x61,0x62,0x6C,0x65,0x57,0x69,0x74,0x68,0x45,0x6E,0x75,0x6D,0x00,
+ 0x00,0x00,0x0E,0x00,0x1C,0x00,0x04,0x00,0x14,0x00,0x08,0x00,0x0C,0x00,0x10,0x00,0x0E,0x00,0x00,0x00,
+ 0x28,0x00,0x00,0x00,0x08,0x06,0x00,0x00,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x62,0xD7,0xFF,0xFF,0x00,0x00,0x00,0x0F,0x01,0x00,0x00,0x00,
+ 0x07,0x00,0x00,0x00,0x4D,0x6F,0x6E,0x73,0x74,0x65,0x72,0x00,0xB2,0xFC,0xFF,0xFF,0x14,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA4,0xFC,0xFF,0xFF,0x04,0x00,0x00,0x00,
+ 0x4E,0x4F,0x4E,0x45,0x00,0x00,0x00,0x00,0x38,0xFD,0xFF,0xFF,0x34,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB6,0xD7,0xFF,0xFF,0x00,0x00,0x00,0x03,
+ 0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xA0,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x48,0x00,0x00,0x00,
+ 0x1C,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,
+ 0x6C,0x65,0x2E,0x52,0x61,0x63,0x65,0x00,0xBE,0xFD,0xFF,0xFF,0x1C,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0xFD,0xFF,0xFF,
+ 0x03,0x00,0x00,0x00,0x45,0x6C,0x66,0x00,0xE6,0xFD,0xFF,0xFF,0x1C,0x00,0x00,0x00,0x14,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0xFD,0xFF,0xFF,
+ 0x05,0x00,0x00,0x00,0x44,0x77,0x61,0x72,0x66,0x00,0x00,0x00,0x7A,0xFD,0xFF,0xFF,0x14,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0xFD,0xFF,0xFF,0x05,0x00,0x00,0x00,
+ 0x48,0x75,0x6D,0x61,0x6E,0x00,0x00,0x00,0xBE,0xFE,0xFF,0xFF,0x20,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x9C,0xFD,0xFF,0xFF,0x04,0x00,0x00,0x00,0x4E,0x6F,0x6E,0x65,0x00,0x00,0x00,0x00,0x10,0x00,0x18,0x00,
+ 0x04,0x00,0x08,0x00,0x00,0x00,0x0C,0x00,0x10,0x00,0x14,0x00,0x10,0x00,0x00,0x00,0x90,0x00,0x00,0x00,
+ 0x7C,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x20,0x43,0x6F,0x6D,0x70,0x6F,0x73,0x69,0x74,0x65,0x20,0x63,
+ 0x6F,0x6D,0x70,0x6F,0x6E,0x65,0x6E,0x74,0x73,0x20,0x6F,0x66,0x20,0x4D,0x6F,0x6E,0x73,0x74,0x65,0x72,
+ 0x20,0x63,0x6F,0x6C,0x6F,0x72,0x2E,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xB0,0xDB,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x09,0x00,0x00,0x00,
+ 0x62,0x69,0x74,0x5F,0x66,0x6C,0x61,0x67,0x73,0x00,0x00,0x00,0x1E,0xD9,0xFF,0xFF,0x00,0x00,0x00,0x04,
+ 0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x84,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+ 0x14,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x43,
+ 0x6F,0x6C,0x6F,0x72,0x00,0x00,0x00,0x00,0x26,0xFF,0xFF,0xFF,0x44,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x1C,0x00,0x00,0x00,0x20,0x5C,0x62,0x72,0x69,0x65,0x66,0x20,0x63,0x6F,0x6C,0x6F,0x72,0x20,0x42,0x6C,
+ 0x75,0x65,0x20,0x28,0x31,0x75,0x20,0x3C,0x3C,0x20,0x33,0x29,0x00,0x00,0x00,0x00,0xB0,0xFE,0xFF,0xFF,
+ 0x04,0x00,0x00,0x00,0x42,0x6C,0x75,0x65,0x00,0x00,0x0E,0x00,0x1C,0x00,0x04,0x00,0x10,0x00,0x00,0x00,
+ 0x08,0x00,0x0C,0x00,0x0E,0x00,0x00,0x00,0x6C,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x34,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x27,0x00,0x00,0x00,0x20,0x47,0x72,0x65,0x65,0x6E,0x20,0x69,0x73,0x20,0x62,0x69,
+ 0x74,0x5F,0x66,0x6C,0x61,0x67,0x20,0x77,0x69,0x74,0x68,0x20,0x76,0x61,0x6C,0x75,0x65,0x20,0x28,0x31,
+ 0x75,0x20,0x3C,0x3C,0x20,0x31,0x29,0x00,0x13,0x00,0x00,0x00,0x20,0x5C,0x62,0x72,0x69,0x65,0x66,0x20,
+ 0x63,0x6F,0x6C,0x6F,0x72,0x20,0x47,0x72,0x65,0x65,0x6E,0x00,0x38,0xFF,0xFF,0xFF,0x05,0x00,0x00,0x00,
+ 0x47,0x72,0x65,0x65,0x6E,0x00,0x0E,0x00,0x18,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x08,0x00,0x0C,0x00,
+ 0x0E,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xFF,0xFF,0xFF,0x03,0x00,0x00,0x00,0x52,0x65,0x64,0x00,
+ 0x10,0x00,0x14,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x00,0x00,
+ 0x28,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x8E,0xDA,0xFF,0xFF,0x00,0x00,0x00,0x09,0x05,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
+ 0x21,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x4F,0x74,0x68,0x65,0x72,0x4E,0x61,0x6D,0x65,
+ 0x53,0x70,0x61,0x63,0x65,0x2E,0x46,0x72,0x6F,0x6D,0x49,0x6E,0x63,0x6C,0x75,0x64,0x65,0x00,0x0E,0x00,
+ 0x10,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0C,0x00,0x0E,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,
+ 0x0A,0x00,0x00,0x00,0x49,0x6E,0x63,0x6C,0x75,0x64,0x65,0x56,0x61,0x6C,0x00,0x00,0x8A,0xDB,0xFF,0xFF,
+ 0x48,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0xCC,0x00,0x00,0x00,0xA0,0x00,0x00,0x00,0xB4,0x01,0x00,0x00,0x60,0x01,0x00,0x00,
+ 0x0C,0x01,0x00,0x00,0xF8,0x01,0x00,0x00,0x7C,0x01,0x00,0x00,0x28,0x01,0x00,0x00,0xD4,0x00,0x00,0x00,
+ 0xC0,0x01,0x00,0x00,0x54,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x1A,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,
+ 0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x54,0x79,0x70,0x65,0x41,0x6C,0x69,0x61,0x73,
+ 0x65,0x73,0x00,0x00,0x26,0xDD,0xFF,0xFF,0x0B,0x00,0x1A,0x00,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xE5,0xFF,0xFF,0x00,0x00,0x0E,0x0C,0x04,0x00,0x00,0x00,
+ 0x76,0x66,0x36,0x34,0x00,0x00,0x00,0x00,0x52,0xDD,0xFF,0xFF,0x0A,0x00,0x18,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xE5,0xFF,0xFF,0x00,0x00,0x0E,0x03,
+ 0x02,0x00,0x00,0x00,0x76,0x38,0x00,0x00,0x7A,0xDD,0xFF,0xFF,0x09,0x00,0x16,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0xDB,0xFF,0xFF,0x00,0x00,0x00,0x0C,
+ 0x03,0x00,0x00,0x00,0x66,0x36,0x34,0x00,0xA2,0xDD,0xFF,0xFF,0x08,0x00,0x14,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5A,0xDB,0xFF,0xFF,0x00,0x00,0x00,0x0B,
+ 0x03,0x00,0x00,0x00,0x66,0x33,0x32,0x00,0xCA,0xDD,0xFF,0xFF,0x07,0x00,0x12,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x82,0xDB,0xFF,0xFF,0x00,0x00,0x00,0x0A,
+ 0x03,0x00,0x00,0x00,0x75,0x36,0x34,0x00,0xF2,0xDD,0xFF,0xFF,0x06,0x00,0x10,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAA,0xDB,0xFF,0xFF,0x00,0x00,0x00,0x09,
+ 0x03,0x00,0x00,0x00,0x69,0x36,0x34,0x00,0x1A,0xDE,0xFF,0xFF,0x05,0x00,0x0E,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD2,0xDB,0xFF,0xFF,0x00,0x00,0x00,0x08,
+ 0x03,0x00,0x00,0x00,0x75,0x33,0x32,0x00,0x42,0xDE,0xFF,0xFF,0x04,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFA,0xDB,0xFF,0xFF,0x00,0x00,0x00,0x07,
+ 0x03,0x00,0x00,0x00,0x69,0x33,0x32,0x00,0x6A,0xDE,0xFF,0xFF,0x03,0x00,0x0A,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0xDC,0xFF,0xFF,0x00,0x00,0x00,0x06,
+ 0x03,0x00,0x00,0x00,0x75,0x31,0x36,0x00,0x92,0xDE,0xFF,0xFF,0x02,0x00,0x08,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0xDC,0xFF,0xFF,0x00,0x00,0x00,0x05,
+ 0x03,0x00,0x00,0x00,0x69,0x31,0x36,0x00,0xBA,0xDE,0xFF,0xFF,0x01,0x00,0x06,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x72,0xDC,0xFF,0xFF,0x00,0x00,0x00,0x04,
+ 0x02,0x00,0x00,0x00,0x75,0x38,0x00,0x00,0x5E,0xDD,0xFF,0xFF,0x00,0x00,0x04,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9A,0xDC,0xFF,0xFF,0x00,0x00,0x00,0x03,
+ 0x02,0x00,0x00,0x00,0x69,0x38,0x00,0x00,0xDA,0xDD,0xFF,0xFF,0x18,0x01,0x00,0x00,0x4C,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x33,0x00,0x00,0x00,
+ 0x20,0x61,0x6E,0x20,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x20,0x64,0x6F,0x63,0x75,0x6D,0x65,0x6E,0x74,
+ 0x61,0x74,0x69,0x6F,0x6E,0x20,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x74,0x3A,0x20,0x22,0x6D,0x6F,0x6E,0x73,
+ 0x74,0x65,0x72,0x20,0x6F,0x62,0x6A,0x65,0x63,0x74,0x22,0x00,0x31,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,
+ 0x1C,0x02,0x00,0x00,0x7C,0x02,0x00,0x00,0xD4,0x02,0x00,0x00,0xB0,0x06,0x00,0x00,0x90,0x17,0x00,0x00,
+ 0xEC,0x14,0x00,0x00,0x04,0x0C,0x00,0x00,0x78,0x18,0x00,0x00,0xD8,0x19,0x00,0x00,0xF8,0x17,0x00,0x00,
+ 0x48,0x1A,0x00,0x00,0x2C,0x19,0x00,0x00,0x34,0x04,0x00,0x00,0x6C,0x0A,0x00,0x00,0xB0,0x1A,0x00,0x00,
+ 0xBC,0x00,0x00,0x00,0x08,0x09,0x00,0x00,0xA8,0x16,0x00,0x00,0x40,0x16,0x00,0x00,0x78,0x0B,0x00,0x00,
+ 0xF4,0x16,0x00,0x00,0x54,0x0E,0x00,0x00,0x40,0x0C,0x00,0x00,0xCC,0x15,0x00,0x00,0xA0,0x0C,0x00,0x00,
+ 0xF4,0x14,0x00,0x00,0x4C,0x13,0x00,0x00,0xA0,0x13,0x00,0x00,0xD8,0x0D,0x00,0x00,0x5C,0x0D,0x00,0x00,
+ 0xE8,0x0C,0x00,0x00,0xB0,0x12,0x00,0x00,0x88,0x10,0x00,0x00,0x98,0x11,0x00,0x00,0x0C,0x0F,0x00,0x00,
+ 0x18,0x12,0x00,0x00,0x90,0x0F,0x00,0x00,0x00,0x11,0x00,0x00,0x70,0x0E,0x00,0x00,0xCC,0x13,0x00,0x00,
+ 0xE4,0x04,0x00,0x00,0x64,0x0A,0x00,0x00,0xB4,0x00,0x00,0x00,0xBC,0x0A,0x00,0x00,0x8C,0x02,0x00,0x00,
+ 0x84,0x09,0x00,0x00,0xF0,0x06,0x00,0x00,0x98,0x07,0x00,0x00,0x16,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,
+ 0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x4D,0x6F,0x6E,0x73,0x74,0x65,0x72,0x00,0x00,
+ 0x00,0x00,0x1A,0x00,0x20,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x18,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x10,0x00,0x14,0x00,0x1A,0x00,0x00,0x00,0x30,0x00,0x64,0x00,0x4C,0x00,0x00,0x00,
+ 0x3C,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x88,0xE1,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x34,0x38,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,
+ 0xEE,0xDE,0xFF,0xFF,0x00,0x00,0x00,0x03,0x04,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x73,0x69,0x67,0x6E,
+ 0x65,0x64,0x5F,0x65,0x6E,0x75,0x6D,0x00,0x5A,0xE9,0xFF,0xFF,0x2F,0x00,0x62,0x00,0x44,0x00,0x00,0x00,
+ 0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0xE4,0xE1,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x34,0x37,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xD2,0xEA,0xFF,0xFF,0x00,0x00,0x0E,0x04,
+ 0x03,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x76,0x65,0x63,0x74,0x6F,0x72,0x5F,0x6F,0x66,0x5F,0x65,0x6E,
+ 0x75,0x6D,0x73,0x00,0xBA,0xE9,0xFF,0xFF,0x2E,0x00,0x60,0x00,0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x44,0xE2,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x34,0x36,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xAA,0xDF,0xFF,0xFF,0x00,0x00,0x00,0x10,0x01,0x00,0x00,0x00,
+ 0x0D,0x00,0x00,0x00,0x61,0x6E,0x79,0x5F,0x61,0x6D,0x62,0x69,0x67,0x75,0x6F,0x75,0x73,0x00,0x00,0x00,
+ 0x1A,0xEA,0xFF,0xFF,0x2D,0x00,0x5E,0x00,0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xA4,0xE2,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x34,0x35,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x0A,0xE0,0xFF,0xFF,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x12,0x00,0x00,0x00,
+ 0x61,0x6E,0x79,0x5F,0x61,0x6D,0x62,0x69,0x67,0x75,0x6F,0x75,0x73,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,
+ 0x7E,0xEA,0xFF,0xFF,0x2C,0x00,0x5C,0x00,0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0xE3,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x34,0x34,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x6E,0xE0,0xFF,0xFF,0x00,0x00,0x00,0x10,0x02,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,
+ 0x61,0x6E,0x79,0x5F,0x75,0x6E,0x69,0x71,0x75,0x65,0x00,0x00,0xDA,0xEA,0xFF,0xFF,0x2B,0x00,0x5A,0x00,
+ 0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x64,0xE3,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x34,0x33,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xCA,0xE0,0xFF,0xFF,
+ 0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x61,0x6E,0x79,0x5F,0x75,0x6E,0x69,0x71,
+ 0x75,0x65,0x5F,0x74,0x79,0x70,0x65,0x00,0x3A,0xEB,0xFF,0xFF,0x2A,0x00,0x58,0x00,0xFC,0x00,0x00,0x00,
+ 0xF0,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
+ 0xB0,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0xD4,0xE3,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x34,0x32,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xF0,0xE3,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x61,0x5F,0x36,0x34,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x18,0xE4,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x0B,0x00,0x00,0x00,0x52,0x65,0x66,0x65,0x72,0x72,0x61,0x62,0x6C,0x65,0x54,0x00,0x08,0x00,0x00,0x00,
+ 0x63,0x70,0x70,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0x44,0xE4,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,
+ 0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,0x5F,0x67,0x65,0x74,0x00,0x00,0x00,0x00,0x70,0xE4,0xFF,0xFF,
+ 0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6E,0x61,0x6B,0x65,0x64,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,
+ 0xDC,0xEB,0xFF,0xFF,0x00,0x00,0x0E,0x0A,0x1F,0x00,0x00,0x00,0x76,0x65,0x63,0x74,0x6F,0x72,0x5F,0x6F,
+ 0x66,0x5F,0x6E,0x6F,0x6E,0x5F,0x6F,0x77,0x6E,0x69,0x6E,0x67,0x5F,0x72,0x65,0x66,0x65,0x72,0x65,0x6E,
+ 0x63,0x65,0x73,0x00,0x62,0xEC,0xFF,0xFF,0x29,0x00,0x56,0x00,0xFC,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0xB0,0x00,0x00,0x00,
+ 0x80,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xFC,0xE4,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x34,0x31,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x18,0xE5,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+ 0x66,0x6E,0x76,0x31,0x61,0x5F,0x36,0x34,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,
+ 0x00,0x00,0x00,0x00,0x40,0xE5,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,
+ 0x52,0x65,0x66,0x65,0x72,0x72,0x61,0x62,0x6C,0x65,0x54,0x00,0x08,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,
+ 0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0x6C,0xE5,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,
+ 0x74,0x79,0x70,0x65,0x5F,0x67,0x65,0x74,0x00,0x00,0x00,0x00,0x98,0xE5,0xFF,0xFF,0x14,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6E,0x61,0x6B,0x65,0x64,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0x66,0xE2,0xFF,0xFF,
+ 0x00,0x00,0x00,0x0A,0x14,0x00,0x00,0x00,0x6E,0x6F,0x6E,0x5F,0x6F,0x77,0x6E,0x69,0x6E,0x67,0x5F,0x72,
+ 0x65,0x66,0x65,0x72,0x65,0x6E,0x63,0x65,0x00,0x00,0x00,0x00,0x82,0xED,0xFF,0xFF,0x28,0x00,0x54,0x00,
+ 0x0C,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x05,0x00,0x00,0x00,0xB4,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x24,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x1C,0xE6,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x34,0x30,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x38,0xE6,0xFF,0xFF,0x18,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x61,0x5F,0x36,0x34,0x00,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x60,0xE6,0xFF,0xFF,0x18,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x52,0x65,0x66,0x65,0x72,0x72,0x61,0x62,0x6C,0x65,0x54,0x00,
+ 0x08,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0x8C,0xE6,0xFF,0xFF,
+ 0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x2E,0x67,0x65,0x74,0x28,0x29,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,0x5F,0x67,0x65,0x74,
+ 0x00,0x00,0x00,0x00,0xBC,0xE6,0xFF,0xFF,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+ 0x64,0x65,0x66,0x61,0x75,0x6C,0x74,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,
+ 0x34,0xEE,0xFF,0xFF,0x00,0x00,0x0E,0x0A,0x1E,0x00,0x00,0x00,0x76,0x65,0x63,0x74,0x6F,0x72,0x5F,0x6F,
+ 0x66,0x5F,0x63,0x6F,0x5F,0x6F,0x77,0x6E,0x69,0x6E,0x67,0x5F,0x72,0x65,0x66,0x65,0x72,0x65,0x6E,0x63,
+ 0x65,0x73,0x00,0x00,0xBA,0xEE,0xFF,0xFF,0x27,0x00,0x52,0x00,0xCC,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x80,0x00,0x00,0x00,
+ 0x50,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x50,0xE7,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x33,0x39,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,
+ 0x6C,0xE7,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,
+ 0x61,0x5F,0x36,0x34,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,
+ 0x94,0xE7,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x52,0x65,0x66,0x65,
+ 0x72,0x72,0x61,0x62,0x6C,0x65,0x54,0x00,0x08,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x74,0x79,0x70,0x65,
+ 0x00,0x00,0x00,0x00,0xC0,0xE7,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
+ 0x6E,0x61,0x6B,0x65,0x64,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,
+ 0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0x8E,0xE4,0xFF,0xFF,0x00,0x00,0x00,0x0A,0x13,0x00,0x00,0x00,
+ 0x63,0x6F,0x5F,0x6F,0x77,0x6E,0x69,0x6E,0x67,0x5F,0x72,0x65,0x66,0x65,0x72,0x65,0x6E,0x63,0x65,0x00,
+ 0xA6,0xEF,0xFF,0xFF,0x26,0x00,0x50,0x00,0x80,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x34,0xE8,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x33,0x38,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x50,0xE8,0xFF,0xFF,0x20,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x64,0x65,0x66,0x61,0x75,0x6C,0x74,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,
+ 0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,
+ 0x00,0x00,0x00,0x00,0x5A,0xF1,0xFF,0xFF,0x00,0x00,0x0E,0x0F,0x02,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,
+ 0x76,0x65,0x63,0x74,0x6F,0x72,0x5F,0x6F,0x66,0x5F,0x73,0x74,0x72,0x6F,0x6E,0x67,0x5F,0x72,0x65,0x66,
+ 0x65,0x72,0x72,0x61,0x62,0x6C,0x65,0x73,0x00,0x00,0x00,0x00,0x52,0xF0,0xFF,0xFF,0x25,0x00,0x4E,0x00,
+ 0xCC,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0xE8,0xE8,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x33,0x37,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x04,0xE9,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x61,0x5F,0x36,0x34,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x2C,0xE9,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x0B,0x00,0x00,0x00,0x52,0x65,0x66,0x65,0x72,0x72,0x61,0x62,0x6C,0x65,0x54,0x00,0x08,0x00,0x00,0x00,
+ 0x63,0x70,0x70,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0x58,0xE9,0xFF,0xFF,0x14,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6E,0x61,0x6B,0x65,0x64,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0xC4,0xF0,0xFF,0xFF,
+ 0x00,0x00,0x0E,0x0A,0x19,0x00,0x00,0x00,0x76,0x65,0x63,0x74,0x6F,0x72,0x5F,0x6F,0x66,0x5F,0x77,0x65,
+ 0x61,0x6B,0x5F,0x72,0x65,0x66,0x65,0x72,0x65,0x6E,0x63,0x65,0x73,0x00,0x00,0x00,0x46,0xF1,0xFF,0xFF,
+ 0x24,0x00,0x4C,0x00,0xCC,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x24,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0xDC,0xE9,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x33,0x36,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xF8,0xE9,0xFF,0xFF,0x18,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x61,0x5F,0x36,0x34,0x00,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x20,0xEA,0xFF,0xFF,0x18,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x52,0x65,0x66,0x65,0x72,0x72,0x61,0x62,0x6C,0x65,0x54,0x00,
+ 0x08,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0x4C,0xEA,0xFF,0xFF,
+ 0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x6E,0x61,0x6B,0x65,0x64,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,
+ 0x1A,0xE7,0xFF,0xFF,0x00,0x00,0x00,0x0A,0x15,0x00,0x00,0x00,0x73,0x69,0x6E,0x67,0x6C,0x65,0x5F,0x77,
+ 0x65,0x61,0x6B,0x5F,0x72,0x65,0x66,0x65,0x72,0x65,0x6E,0x63,0x65,0x00,0x00,0x00,0x36,0xF2,0xFF,0xFF,
+ 0x23,0x00,0x4A,0x00,0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xC0,0xEA,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x33,0x35,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,
+ 0xAE,0xF3,0xFF,0xFF,0x00,0x00,0x0E,0x0F,0x02,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x76,0x65,0x63,0x74,
+ 0x6F,0x72,0x5F,0x6F,0x66,0x5F,0x72,0x65,0x66,0x65,0x72,0x72,0x61,0x62,0x6C,0x65,0x73,0x00,0x00,0x00,
+ 0x9E,0xF2,0xFF,0xFF,0x22,0x00,0x48,0x00,0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x28,0xEB,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x33,0x34,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x8E,0xE8,0xFF,0xFF,0x00,0x00,0x00,0x0F,0x09,0x00,0x00,0x00,0x15,0x00,0x00,0x00,
+ 0x70,0x61,0x72,0x65,0x6E,0x74,0x5F,0x6E,0x61,0x6D,0x65,0x73,0x70,0x61,0x63,0x65,0x5F,0x74,0x65,0x73,
+ 0x74,0x00,0x00,0x00,0x06,0xF3,0xFF,0xFF,0x21,0x00,0x46,0x00,0x40,0x00,0x00,0x00,0x34,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x90,0xEB,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x33,0x33,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xEC,0xF2,0xFF,0xFF,0x00,0x00,0x0E,0x0C,0x11,0x00,0x00,0x00,
+ 0x76,0x65,0x63,0x74,0x6F,0x72,0x5F,0x6F,0x66,0x5F,0x64,0x6F,0x75,0x62,0x6C,0x65,0x73,0x00,0x00,0x00,
+ 0x66,0xF3,0xFF,0xFF,0x20,0x00,0x44,0x00,0x40,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xF0,0xEB,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x33,0x32,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x4C,0xF3,0xFF,0xFF,0x00,0x00,0x0E,0x09,0x0F,0x00,0x00,0x00,0x76,0x65,0x63,0x74,
+ 0x6F,0x72,0x5F,0x6F,0x66,0x5F,0x6C,0x6F,0x6E,0x67,0x73,0x00,0xC2,0xF3,0xFF,0xFF,0x1F,0x00,0x42,0x00,
+ 0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x4C,0xEC,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x33,0x31,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x3A,0xF5,0xFF,0xFF,
+ 0x00,0x00,0x0E,0x0F,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x35,0x00,0x00,0x00,
+ 0x1A,0xF4,0xFF,0xFF,0x1E,0x00,0x40,0x00,0x68,0x00,0x00,0x00,0x5C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0xA8,0xEC,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x33,0x30,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xC4,0xEC,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x66,0x6C,0x65,0x78,0x62,0x75,0x66,0x66,
+ 0x65,0x72,0x00,0x00,0x28,0xF4,0xFF,0xFF,0x00,0x00,0x0E,0x04,0x04,0x00,0x00,0x00,0x66,0x6C,0x65,0x78,
+ 0x00,0x00,0x00,0x00,0x96,0xF4,0xFF,0xFF,0x1D,0x00,0x3E,0x00,0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x20,0xED,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x32,0x39,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x0E,0xF6,0xFF,0xFF,0x00,0x00,0x0E,0x0F,0x00,0x00,0x00,0x00,
+ 0x17,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x61,0x72,0x72,0x61,0x79,0x6F,0x66,0x73,0x6F,0x72,0x74,0x65,
+ 0x64,0x73,0x74,0x72,0x75,0x63,0x74,0x00,0xFE,0xF4,0xFF,0xFF,0x1C,0x00,0x3C,0x00,0x40,0x00,0x00,0x00,
+ 0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x88,0xED,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x32,0x38,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xE4,0xF4,0xFF,0xFF,0x00,0x00,0x0E,0x0D,
+ 0x12,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x61,0x72,0x72,0x61,0x79,0x6F,0x66,0x73,0x74,0x72,0x69,0x6E,
+ 0x67,0x32,0x00,0x00,0x5E,0xF5,0xFF,0xFF,0x1B,0x00,0x3A,0x00,0x40,0x00,0x00,0x00,0x34,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0xE8,0xED,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x32,0x37,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xA6,0xEA,0xFF,0xFF,0x00,0x00,0x00,0x0B,0x06,0x00,0x00,0x00,
+ 0x74,0x65,0x73,0x74,0x66,0x33,0x00,0x00,0x00,0x00,0x1A,0x00,0x20,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,
+ 0x06,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x14,0x00,0x1A,0x00,0x00,0x00,
+ 0x1A,0x00,0x38,0x00,0x48,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x60,0xEE,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x32,0x36,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x1E,0xEB,0xFF,0xFF,0x00,0x00,0x00,0x0B,0x06,0x00,0x00,0x00,
+ 0x74,0x65,0x73,0x74,0x66,0x32,0x00,0x00,0x00,0x00,0x1A,0x00,0x24,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,
+ 0x06,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x14,0x00,0x1A,0x00,0x00,0x00,
+ 0x19,0x00,0x36,0x00,0x4C,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+ 0x6E,0x86,0x1B,0xF0,0xF9,0x21,0x09,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0xDC,0xEE,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x32,0x35,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x9A,0xEB,0xFF,0xFF,0x00,0x00,0x00,0x0B,
+ 0x05,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x66,0x00,0x00,0x00,0xA6,0xF6,0xFF,0xFF,0x18,0x00,0x34,0x00,
+ 0x40,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x30,0xEF,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x32,0x34,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x8C,0xF6,0xFF,0xFF,
+ 0x00,0x00,0x0E,0x02,0x10,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x61,0x72,0x72,0x61,0x79,0x6F,0x66,0x62,
+ 0x6F,0x6F,0x6C,0x73,0x00,0x00,0x00,0x00,0x06,0xF7,0xFF,0xFF,0x17,0x00,0x32,0x00,0x6C,0x00,0x00,0x00,
+ 0x60,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x94,0xEF,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x32,0x33,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xB0,0xEF,0xFF,0xFF,
+ 0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x61,0x5F,0x36,0x34,
+ 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x7A,0xEC,0xFF,0xFF,
+ 0x00,0x00,0x00,0x0A,0x11,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x68,0x61,0x73,0x68,0x75,0x36,0x34,0x5F,
+ 0x66,0x6E,0x76,0x31,0x61,0x00,0x00,0x00,0x92,0xF7,0xFF,0xFF,0x16,0x00,0x30,0x00,0x6C,0x00,0x00,0x00,
+ 0x60,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x20,0xF0,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x32,0x32,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x3C,0xF0,0xFF,0xFF,
+ 0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x61,0x5F,0x36,0x34,
+ 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x06,0xED,0xFF,0xFF,
+ 0x00,0x00,0x00,0x09,0x11,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x68,0x61,0x73,0x68,0x73,0x36,0x34,0x5F,
+ 0x66,0x6E,0x76,0x31,0x61,0x00,0x00,0x00,0x1E,0xF8,0xFF,0xFF,0x15,0x00,0x2E,0x00,0xC8,0x00,0x00,0x00,
+ 0xBC,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x7C,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xB4,0xF0,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x32,0x31,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0xD0,0xF0,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+ 0x66,0x6E,0x76,0x31,0x61,0x5F,0x33,0x32,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,
+ 0x00,0x00,0x00,0x00,0xF8,0xF0,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x53,0x74,0x61,0x74,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x74,0x79,0x70,0x65,
+ 0x00,0x00,0x00,0x00,0x20,0xF1,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
+ 0x6E,0x61,0x6B,0x65,0x64,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x63,0x70,0x70,0x5F,0x70,0x74,0x72,0x5F,
+ 0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x00,0xEE,0xED,0xFF,0xFF,0x00,0x00,0x00,0x08,0x11,0x00,0x00,0x00,
+ 0x74,0x65,0x73,0x74,0x68,0x61,0x73,0x68,0x75,0x33,0x32,0x5F,0x66,0x6E,0x76,0x31,0x61,0x00,0x00,0x00,
+ 0x06,0xF9,0xFF,0xFF,0x14,0x00,0x2C,0x00,0x6C,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x94,0xF1,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x32,0x30,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xB0,0xF1,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x61,0x5F,0x33,0x32,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x7A,0xEE,0xFF,0xFF,0x00,0x00,0x00,0x07,0x11,0x00,0x00,0x00,
+ 0x74,0x65,0x73,0x74,0x68,0x61,0x73,0x68,0x73,0x33,0x32,0x5F,0x66,0x6E,0x76,0x31,0x61,0x00,0x00,0x00,
+ 0x92,0xF9,0xFF,0xFF,0x13,0x00,0x2A,0x00,0x68,0x00,0x00,0x00,0x5C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x20,0xF2,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x31,0x39,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x3C,0xF2,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x07,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x5F,0x36,0x34,0x00,0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,
+ 0x00,0x00,0x00,0x00,0x02,0xEF,0xFF,0xFF,0x00,0x00,0x00,0x0A,0x10,0x00,0x00,0x00,0x74,0x65,0x73,0x74,
+ 0x68,0x61,0x73,0x68,0x75,0x36,0x34,0x5F,0x66,0x6E,0x76,0x31,0x00,0x00,0x00,0x00,0x1A,0xFA,0xFF,0xFF,
+ 0x12,0x00,0x28,0x00,0x68,0x00,0x00,0x00,0x5C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xA8,0xF2,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x31,0x38,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0xC4,0xF2,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+ 0x66,0x6E,0x76,0x31,0x5F,0x36,0x34,0x00,0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,
+ 0x8A,0xEF,0xFF,0xFF,0x00,0x00,0x00,0x09,0x10,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x68,0x61,0x73,0x68,
+ 0x73,0x36,0x34,0x5F,0x66,0x6E,0x76,0x31,0x00,0x00,0x00,0x00,0xA2,0xFA,0xFF,0xFF,0x11,0x00,0x26,0x00,
+ 0x68,0x00,0x00,0x00,0x5C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x30,0xF3,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x31,0x37,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,
+ 0x4C,0xF3,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,
+ 0x5F,0x33,0x32,0x00,0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x12,0xF0,0xFF,0xFF,
+ 0x00,0x00,0x00,0x08,0x10,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x68,0x61,0x73,0x68,0x75,0x33,0x32,0x5F,
+ 0x66,0x6E,0x76,0x31,0x00,0x00,0x00,0x00,0x2A,0xFB,0xFF,0xFF,0x10,0x00,0x24,0x00,0x68,0x00,0x00,0x00,
+ 0x5C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xB8,0xF3,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x31,0x36,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xD4,0xF3,0xFF,0xFF,
+ 0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x5F,0x33,0x32,0x00,
+ 0x04,0x00,0x00,0x00,0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x9A,0xF0,0xFF,0xFF,0x00,0x00,0x00,0x07,
+ 0x10,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x68,0x61,0x73,0x68,0x73,0x33,0x32,0x5F,0x66,0x6E,0x76,0x31,
+ 0x00,0x00,0x00,0x00,0xB2,0xFB,0xFF,0xFF,0x0F,0x00,0x22,0x00,0x40,0x00,0x00,0x00,0x34,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x3C,0xF4,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x31,0x35,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xFA,0xF0,0xFF,0xFF,0x00,0x00,0x00,0x02,0x08,0x00,0x00,0x00,
+ 0x74,0x65,0x73,0x74,0x62,0x6F,0x6F,0x6C,0x00,0x00,0x00,0x00,0x0A,0xFC,0xFF,0xFF,0x0E,0x00,0x20,0x00,
+ 0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x94,0xF4,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x31,0x34,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xFA,0xF1,0xFF,0xFF,
+ 0x00,0x00,0x00,0x0F,0x03,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x65,0x6D,0x70,0x74,
+ 0x79,0x00,0x00,0x00,0x66,0xFC,0xFF,0xFF,0x0D,0x00,0x1E,0x00,0x74,0x00,0x00,0x00,0x68,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0xF4,0xF4,0xFF,0xFF,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
+ 0x4D,0x6F,0x6E,0x73,0x74,0x65,0x72,0x00,0x11,0x00,0x00,0x00,0x6E,0x65,0x73,0x74,0x65,0x64,0x5F,0x66,
+ 0x6C,0x61,0x74,0x62,0x75,0x66,0x66,0x65,0x72,0x00,0x00,0x00,0x24,0xF5,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x31,0x33,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,
+ 0x80,0xFC,0xFF,0xFF,0x00,0x00,0x0E,0x04,0x14,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x6E,0x65,0x73,0x74,
+ 0x65,0x64,0x66,0x6C,0x61,0x74,0x62,0x75,0x66,0x66,0x65,0x72,0x00,0x00,0x00,0x00,0xFE,0xFC,0xFF,0xFF,
+ 0x0C,0x00,0x1C,0x00,0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x88,0xF5,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x31,0x32,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,
+ 0xEE,0xF2,0xFF,0xFF,0x00,0x00,0x00,0x0F,0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x65,0x6E,0x65,0x6D,
+ 0x79,0x00,0x00,0x00,0x56,0xFD,0xFF,0xFF,0x0B,0x00,0x1A,0x00,0xB0,0x00,0x00,0x00,0xA0,0x00,0x00,0x00,
+ 0x78,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x0E,0x00,0x00,0x00,0x20,0x6D,0x75,0x6C,0x74,0x69,0x6C,0x69,0x6E,0x65,0x20,0x74,0x6F,0x6F,0x00,0x00,
+ 0x49,0x00,0x00,0x00,0x20,0x61,0x6E,0x20,0x65,0x78,0x61,0x6D,0x70,0x6C,0x65,0x20,0x64,0x6F,0x63,0x75,
+ 0x6D,0x65,0x6E,0x74,0x61,0x74,0x69,0x6F,0x6E,0x20,0x63,0x6F,0x6D,0x6D,0x65,0x6E,0x74,0x3A,0x20,0x74,
+ 0x68,0x69,0x73,0x20,0x77,0x69,0x6C,0x6C,0x20,0x65,0x6E,0x64,0x20,0x75,0x70,0x20,0x69,0x6E,0x20,0x74,
+ 0x68,0x65,0x20,0x67,0x65,0x6E,0x65,0x72,0x61,0x74,0x65,0x64,0x20,0x63,0x6F,0x64,0x65,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x4C,0xF6,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x31,0x31,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x3A,0xFF,0xFF,0xFF,
+ 0x00,0x00,0x0E,0x0F,0x01,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x61,0x72,0x72,0x61,
+ 0x79,0x6F,0x66,0x74,0x61,0x62,0x6C,0x65,0x73,0x00,0x00,0x00,0x26,0xFE,0xFF,0xFF,0x0A,0x00,0x18,0x00,
+ 0x40,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xB0,0xF6,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x31,0x30,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x0C,0xFE,0xFF,0xFF,
+ 0x00,0x00,0x0E,0x0D,0x11,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x61,0x72,0x72,0x61,0x79,0x6F,0x66,0x73,
+ 0x74,0x72,0x69,0x6E,0x67,0x00,0x00,0x00,0x86,0xFE,0xFF,0xFF,0x09,0x00,0x16,0x00,0x50,0x00,0x00,0x00,
+ 0x40,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x10,0xF7,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x39,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x00,0x00,0x0A,0x00,0x0C,0x00,0x06,0x00,
+ 0x07,0x00,0x08,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,0x0E,0x0F,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
+ 0x74,0x65,0x73,0x74,0x34,0x00,0x00,0x00,0xEA,0xFE,0xFF,0xFF,0x08,0x00,0x14,0x00,0x44,0x00,0x00,0x00,
+ 0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x74,0xF7,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x38,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xDA,0xF4,0xFF,0xFF,0x00,0x00,0x00,0x10,
+ 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x00,0x00,0x00,0x00,0x42,0xFF,0xFF,0xFF,
+ 0x07,0x00,0x12,0x00,0x44,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xCC,0xF7,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x37,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,
+ 0x32,0xF5,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x74,0x65,0x73,0x74,
+ 0x5F,0x74,0x79,0x70,0x65,0x00,0x00,0x00,0x4A,0xFD,0xFF,0xFF,0x06,0x00,0x10,0x00,0x50,0x00,0x00,0x00,
+ 0x40,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x34,0xF8,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x36,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x9A,0xF5,0xFF,0xFF,0x00,0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
+ 0x63,0x6F,0x6C,0x6F,0x72,0x00,0x1A,0x00,0x18,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x14,0x00,0x1A,0x00,0x00,0x00,0x05,0x00,0x0E,0x00,
+ 0x48,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xA4,0xF8,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x35,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x08,0x00,0x08,0x00,
+ 0x06,0x00,0x07,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x0E,0x04,0x09,0x00,0x00,0x00,0x69,0x6E,0x76,0x65,
+ 0x6E,0x74,0x6F,0x72,0x79,0x00,0x1A,0x00,0x1C,0x00,0x0C,0x00,0x10,0x00,0x08,0x00,0x0A,0x00,0x00,0x00,
+ 0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x18,0x00,0x1A,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x04,0x00,0x0C,0x00,0x90,0x00,0x00,0x00,0x84,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x4C,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x28,0xF9,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x31,0x00,0x00,0x00,
+ 0x08,0x00,0x00,0x00,0x70,0x72,0x69,0x6F,0x72,0x69,0x74,0x79,0x00,0x00,0x00,0x00,0x4C,0xF9,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x68,0xF9,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x30,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x64,0x65,0x70,0x72,0x65,0x63,0x61,0x74,0x65,0x64,0x00,0x00,
+ 0x2E,0xF6,0xFF,0xFF,0x00,0x00,0x00,0x02,0x08,0x00,0x00,0x00,0x66,0x72,0x69,0x65,0x6E,0x64,0x6C,0x79,
+ 0x00,0x00,0x1A,0x00,0x1C,0x00,0x0C,0x00,0x10,0x00,0x08,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x06,0x00,0x07,0x00,0x14,0x00,0x18,0x00,0x1A,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x03,0x00,0x0A,0x00,
+ 0x88,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x03,0x00,0x00,0x00,0x4C,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xEC,0xF9,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x08,0x00,0x00,0x00,
+ 0x72,0x65,0x71,0x75,0x69,0x72,0x65,0x64,0x00,0x00,0x00,0x00,0x10,0xFA,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x6B,0x65,0x79,0x00,
+ 0x2C,0xFA,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x33,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xEA,0xF6,0xFF,0xFF,0x00,0x00,0x00,0x0D,0x04,0x00,0x00,0x00,
+ 0x6E,0x61,0x6D,0x65,0x00,0x00,0x00,0x00,0xA2,0xFF,0xFF,0xFF,0x02,0x00,0x08,0x00,0x4C,0x00,0x00,0x00,
+ 0x40,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x8C,0xFA,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x4A,0xF7,0xFF,0xFF,0x00,0x00,0x00,0x05,0x02,0x00,0x00,0x00,0x68,0x70,0x00,0x00,
+ 0x00,0x00,0x1A,0x00,0x24,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x18,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x10,0x00,0x14,0x00,0x1A,0x00,0x00,0x00,0x01,0x00,0x06,0x00,0x4C,0x00,0x00,0x00,
+ 0x40,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0xFB,0xFF,0xFF,
+ 0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x31,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0xC2,0xF7,0xFF,0xFF,0x00,0x00,0x00,0x05,0x04,0x00,0x00,0x00,0x6D,0x61,0x6E,0x61,
+ 0x00,0x00,0x1A,0x00,0x18,0x00,0x08,0x00,0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x10,0x00,0x14,0x00,0x1A,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x44,0x00,0x00,0x00,
+ 0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x70,0xFB,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x30,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0xD6,0xF8,0xFF,0xFF,0x00,0x00,0x00,0x0F,
+ 0x07,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x70,0x6F,0x73,0x00,0x72,0xF9,0xFF,0xFF,0x1C,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x3C,0x00,0x00,0x00,0x19,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,
+ 0x6C,0x65,0x2E,0x52,0x65,0x66,0x65,0x72,0x72,0x61,0x62,0x6C,0x65,0x00,0x1A,0x00,0x18,0x00,0x08,0x00,
+ 0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x10,0x00,0x14,0x00,
+ 0x1A,0x00,0x00,0x00,0x00,0x01,0x04,0x00,0x6C,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x20,0xFC,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,
+ 0x03,0x00,0x00,0x00,0x6B,0x65,0x79,0x00,0x3C,0xFC,0xFF,0xFF,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x08,0x00,0x00,0x00,0x66,0x6E,0x76,0x31,0x61,0x5F,0x36,0x34,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x68,0x61,0x73,0x68,0x00,0x00,0x00,0x00,0x06,0xF9,0xFF,0xFF,0x00,0x00,0x00,0x0A,0x02,0x00,0x00,0x00,
+ 0x69,0x64,0x00,0x00,0x46,0xFA,0xFF,0xFF,0x24,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x74,0x00,0x00,0x00,
+ 0x48,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,
+ 0x6C,0x65,0x2E,0x53,0x74,0x61,0x74,0x00,0xB6,0xFB,0xFF,0xFF,0x02,0x00,0x08,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0xF9,0xFF,0xFF,0x00,0x00,0x00,0x06,
+ 0x05,0x00,0x00,0x00,0x63,0x6F,0x75,0x6E,0x74,0x00,0x00,0x00,0xE2,0xFB,0xFF,0xFF,0x01,0x00,0x06,0x00,
+ 0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x9A,0xF9,0xFF,0xFF,
+ 0x00,0x00,0x00,0x09,0x03,0x00,0x00,0x00,0x76,0x61,0x6C,0x00,0x86,0xFA,0xFF,0xFF,0x00,0x00,0x04,0x00,
+ 0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC2,0xF9,0xFF,0xFF,
+ 0x00,0x00,0x00,0x0D,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x5E,0xFA,0xFF,0xFF,0x00,0x00,0x00,0x01,
+ 0x24,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x16,0x00,0x00,0x00,
+ 0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x41,0x62,0x69,0x6C,0x69,
+ 0x74,0x79,0x00,0x00,0x7A,0xFC,0xFF,0xFF,0x01,0x00,0x04,0x00,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x32,0xFA,0xFF,0xFF,0x00,0x00,0x00,0x08,0x08,0x00,0x00,0x00,
+ 0x64,0x69,0x73,0x74,0x61,0x6E,0x63,0x65,0x00,0x00,0x1A,0x00,0x18,0x00,0x08,0x00,0x0C,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x10,0x00,0x14,0x00,0x1A,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x40,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xE4,0xFD,0xFF,0xFF,0x10,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x6B,0x65,0x79,0x00,
+ 0xA2,0xFA,0xFF,0xFF,0x00,0x00,0x00,0x08,0x02,0x00,0x00,0x00,0x69,0x64,0x00,0x00,0x00,0x00,0x12,0x00,
+ 0x20,0x00,0x08,0x00,0x0C,0x00,0x07,0x00,0x10,0x00,0x14,0x00,0x18,0x00,0x1C,0x00,0x12,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x01,0x64,0x00,0x00,0x00,0x44,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x50,0xFE,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
+ 0x0B,0x00,0x00,0x00,0x66,0x6F,0x72,0x63,0x65,0x5F,0x61,0x6C,0x69,0x67,0x6E,0x00,0x06,0x00,0x00,0x00,
+ 0x90,0x00,0x00,0x00,0x5C,0x00,0x00,0x00,0x28,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0xD4,0x00,0x00,0x00,
+ 0xA8,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,
+ 0x6C,0x65,0x2E,0x56,0x65,0x63,0x33,0x00,0xAA,0xFD,0xFF,0xFF,0x05,0x00,0x1A,0x00,0x1C,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0xFC,0xFF,0xFF,0x00,0x00,0x00,0x0F,
+ 0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x74,0x65,0x73,0x74,0x33,0x00,0x00,0x00,0xDA,0xFD,0xFF,0xFF,
+ 0x04,0x00,0x18,0x00,0x1C,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x3A,0xFC,0xFF,0xFF,0x00,0x00,0x00,0x04,0x03,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x74,0x65,0x73,0x74,
+ 0x32,0x00,0x00,0x00,0x0A,0xFE,0xFF,0xFF,0x03,0x00,0x10,0x00,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC2,0xFB,0xFF,0xFF,0x00,0x00,0x00,0x0C,0x05,0x00,0x00,0x00,
+ 0x74,0x65,0x73,0x74,0x31,0x00,0x00,0x00,0x36,0xFE,0xFF,0xFF,0x02,0x00,0x08,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEE,0xFB,0xFF,0xFF,0x00,0x00,0x00,0x0B,
+ 0x01,0x00,0x00,0x00,0x7A,0x00,0x00,0x00,0x5E,0xFE,0xFF,0xFF,0x01,0x00,0x04,0x00,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x16,0xFC,0xFF,0xFF,0x00,0x00,0x00,0x0B,
+ 0x01,0x00,0x00,0x00,0x79,0x00,0x00,0x00,0x56,0xFC,0xFF,0xFF,0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3A,0xFC,0xFF,0xFF,0x00,0x00,0x00,0x0B,0x01,0x00,0x00,0x00,
+ 0x78,0x00,0x12,0x00,0x18,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x10,0x00,0x14,0x00,
+ 0x12,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0xE0,0xFF,0xFF,0xFF,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,
+ 0x07,0x00,0x00,0x00,0x70,0x72,0x69,0x76,0x61,0x74,0x65,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x08,0x00,
+ 0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x30,0x00,0x00,0x00,
+ 0x0E,0x00,0x00,0x00,0x63,0x73,0x68,0x61,0x72,0x70,0x5F,0x70,0x61,0x72,0x74,0x69,0x61,0x6C,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x4C,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,
+ 0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x54,0x65,0x73,0x74,0x53,0x69,0x6D,0x70,0x6C,0x65,0x54,0x61,0x62,
+ 0x6C,0x65,0x57,0x69,0x74,0x68,0x45,0x6E,0x75,0x6D,0x00,0x00,0x00,0x00,0x1A,0x00,0x1C,0x00,0x08,0x00,
+ 0x0C,0x00,0x00,0x00,0x06,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
+ 0x1A,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x24,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
+ 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEA,0xFD,0xFF,0xFF,0x00,0x00,0x00,0x04,
+ 0x03,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x63,0x6F,0x6C,0x6F,0x72,0x00,0x00,0x00,0xE6,0xFD,0xFF,0xFF,
+ 0x00,0x00,0x00,0x01,0x24,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x64,0x00,0x00,0x00,0x38,0x00,0x00,0x00,
+ 0x13,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x2E,0x54,
+ 0x65,0x73,0x74,0x00,0x00,0x00,0x1A,0x00,0x14,0x00,0x08,0x00,0x0C,0x00,0x04,0x00,0x06,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x1A,0x00,0x00,0x00,0x01,0x00,0x02,0x00,
+ 0x18,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD2,0xFD,0xFF,0xFF,
+ 0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x62,0x00,0x00,0x00,0x12,0xFE,0xFF,0xFF,0x18,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0xFD,0xFF,0xFF,0x00,0x00,0x00,0x05,
+ 0x01,0x00,0x00,0x00,0x61,0x00,0x00,0x00,0x36,0xFF,0xFF,0xFF,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x17,0x00,0x00,0x00,
+ 0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x45,0x78,0x61,0x6D,0x70,0x6C,0x65,0x32,0x2E,0x4D,0x6F,0x6E,0x73,
+ 0x74,0x65,0x72,0x00,0x6E,0xFF,0xFF,0xFF,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,
+ 0x6D,0x65,0x2E,0x49,0x6E,0x50,0x61,0x72,0x65,0x6E,0x74,0x4E,0x61,0x6D,0x65,0x73,0x70,0x61,0x63,0x65,
+ 0x00,0x00,0x00,0x00,0xAA,0xFF,0xFF,0xFF,0x1C,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x06,0x00,0x00,0x00,
+ 0x54,0x61,0x62,0x6C,0x65,0x41,0x00,0x00,0x82,0xFF,0xFF,0xFF,0x00,0x00,0x04,0x00,0x1C,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x0F,
+ 0x0A,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x62,0x00,0x12,0x00,0x14,0x00,0x04,0x00,0x08,0x00,0x00,0x00,
+ 0x0C,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x12,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x10,0x00,0x00,0x00,
+ 0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,
+ 0x1C,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,0x6D,0x65,0x2E,0x4F,0x74,0x68,0x65,0x72,0x4E,0x61,0x6D,0x65,
+ 0x53,0x70,0x61,0x63,0x65,0x2E,0x54,0x61,0x62,0x6C,0x65,0x42,0x00,0x00,0x1A,0x00,0x14,0x00,0x08,0x00,
+ 0x0C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,
+ 0x1A,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x28,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x0C,0x00,0x07,0x00,0x00,0x00,0x08,0x00,0x0A,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x0F,0x0C,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x61,0x00,0x12,0x00,0x1C,0x00,0x08,0x00,
+ 0x0C,0x00,0x07,0x00,0x10,0x00,0x14,0x00,0x00,0x00,0x18,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
+ 0x20,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x4D,0x79,0x47,0x61,
+ 0x6D,0x65,0x2E,0x4F,0x74,0x68,0x65,0x72,0x4E,0x61,0x6D,0x65,0x53,0x70,0x61,0x63,0x65,0x2E,0x55,0x6E,
+ 0x75,0x73,0x65,0x64,0x00,0x00,0x1A,0x00,0x10,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1A,0x00,0x00,0x00,0x20,0x00,0x00,0x00,
+ 0x14,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x08,0x00,0x07,0x00,
+ 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x01,0x00,0x00,0x00,0x61,0x00,0x00,0x00
+ };
+ return bfbsData;
+ }
+ static size_t size() {
+ return 12176;
+ }
+ const uint8_t *begin() {
+ return data();
+ }
+ const uint8_t *end() {
+ return data() + size();
+ }
+};
+
+} // namespace Example
+} // namespace MyGame
+
+#endif // FLATBUFFERS_GENERATED_MONSTERTEST_MYGAME_EXAMPLE_BFBS_H_
diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h
index 3deadd93..ad87ffe3 100644
--- a/tests/monster_test_generated.h
+++ b/tests/monster_test_generated.h
@@ -10,11 +10,13 @@
namespace MyGame {
struct InParentNamespace;
+struct InParentNamespaceBuilder;
struct InParentNamespaceT;
namespace Example2 {
struct Monster;
+struct MonsterBuilder;
struct MonsterT;
} // namespace Example2
@@ -24,6 +26,7 @@ namespace Example {
struct Test;
struct TestSimpleTableWithEnum;
+struct TestSimpleTableWithEnumBuilder;
struct TestSimpleTableWithEnumT;
struct Vec3;
@@ -31,15 +34,19 @@ struct Vec3;
struct Ability;
struct Stat;
+struct StatBuilder;
struct StatT;
struct Referrable;
+struct ReferrableBuilder;
struct ReferrableT;
struct Monster;
+struct MonsterBuilder;
struct MonsterT;
struct TypeAliases;
+struct TypeAliasesBuilder;
struct TypeAliasesT;
} // namespace Example
@@ -99,9 +106,13 @@ inline const flatbuffers::TypeTable *MonsterTypeTable();
inline const flatbuffers::TypeTable *TypeAliasesTypeTable();
+/// Composite components of Monster color.
enum Color {
Color_Red = 1,
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
Color_Green = 2,
+ /// \brief color Blue (1u << 3)
Color_Blue = 8,
Color_NONE = 0,
Color_ANY = 11
@@ -117,7 +128,7 @@ inline const Color (&EnumValuesColor())[3] {
}
inline const char * const *EnumNamesColor() {
- static const char * const names[] = {
+ static const char * const names[9] = {
"Red",
"Green",
"",
@@ -132,11 +143,47 @@ inline const char * const *EnumNamesColor() {
}
inline const char *EnumNameColor(Color e) {
- if (e < Color_Red || e > Color_Blue) return "";
+ if (flatbuffers::IsOutRange(e, Color_Red, Color_Blue)) return "";
const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Color_Red);
return EnumNamesColor()[index];
}
+enum Race {
+ Race_None = -1,
+ Race_Human = 0,
+ Race_Dwarf = 1,
+ Race_Elf = 2,
+ Race_MIN = Race_None,
+ Race_MAX = Race_Elf
+};
+
+inline const Race (&EnumValuesRace())[4] {
+ static const Race values[] = {
+ Race_None,
+ Race_Human,
+ Race_Dwarf,
+ Race_Elf
+ };
+ return values;
+}
+
+inline const char * const *EnumNamesRace() {
+ static const char * const names[5] = {
+ "None",
+ "Human",
+ "Dwarf",
+ "Elf",
+ nullptr
+ };
+ return names;
+}
+
+inline const char *EnumNameRace(Race e) {
+ if (flatbuffers::IsOutRange(e, Race_None, Race_Elf)) return "";
+ const size_t index = static_cast<size_t>(e) - static_cast<size_t>(Race_None);
+ return EnumNamesRace()[index];
+}
+
enum Any {
Any_NONE = 0,
Any_Monster = 1,
@@ -157,7 +204,7 @@ inline const Any (&EnumValuesAny())[4] {
}
inline const char * const *EnumNamesAny() {
- static const char * const names[] = {
+ static const char * const names[5] = {
"NONE",
"Monster",
"TestSimpleTableWithEnum",
@@ -168,7 +215,7 @@ inline const char * const *EnumNamesAny() {
}
inline const char *EnumNameAny(Any e) {
- if (e < Any_NONE || e > Any_MyGame_Example2_Monster) return "";
+ if (flatbuffers::IsOutRange(e, Any_NONE, Any_MyGame_Example2_Monster)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesAny()[index];
}
@@ -177,11 +224,11 @@ template<typename T> struct AnyTraits {
static const Any enum_value = Any_NONE;
};
-template<> struct AnyTraits<Monster> {
+template<> struct AnyTraits<MyGame::Example::Monster> {
static const Any enum_value = Any_Monster;
};
-template<> struct AnyTraits<TestSimpleTableWithEnum> {
+template<> struct AnyTraits<MyGame::Example::TestSimpleTableWithEnum> {
static const Any enum_value = Any_TestSimpleTableWithEnum;
};
@@ -197,8 +244,8 @@ struct AnyUnion {
AnyUnion(AnyUnion&& u) FLATBUFFERS_NOEXCEPT :
type(Any_NONE), value(nullptr)
{ std::swap(type, u.type); std::swap(value, u.value); }
- AnyUnion(const AnyUnion &) FLATBUFFERS_NOEXCEPT;
- AnyUnion &operator=(const AnyUnion &u) FLATBUFFERS_NOEXCEPT
+ AnyUnion(const AnyUnion &);
+ AnyUnion &operator=(const AnyUnion &u)
{ AnyUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
AnyUnion &operator=(AnyUnion &&u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
@@ -221,21 +268,21 @@ struct AnyUnion {
static void *UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver);
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
- MonsterT *AsMonster() {
+ MyGame::Example::MonsterT *AsMonster() {
return type == Any_Monster ?
- reinterpret_cast<MonsterT *>(value) : nullptr;
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
}
- const MonsterT *AsMonster() const {
+ const MyGame::Example::MonsterT *AsMonster() const {
return type == Any_Monster ?
- reinterpret_cast<const MonsterT *>(value) : nullptr;
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
}
- TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() {
+ MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() {
return type == Any_TestSimpleTableWithEnum ?
- reinterpret_cast<TestSimpleTableWithEnumT *>(value) : nullptr;
+ reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
}
- const TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() const {
+ const MyGame::Example::TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() const {
return type == Any_TestSimpleTableWithEnum ?
- reinterpret_cast<const TestSimpleTableWithEnumT *>(value) : nullptr;
+ reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
}
MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() {
return type == Any_MyGame_Example2_Monster ?
@@ -255,12 +302,12 @@ inline bool operator==(const AnyUnion &lhs, const AnyUnion &rhs) {
return true;
}
case Any_Monster: {
- return *(reinterpret_cast<const MonsterT *>(lhs.value)) ==
- *(reinterpret_cast<const MonsterT *>(rhs.value));
+ return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+ *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
}
case Any_TestSimpleTableWithEnum: {
- return *(reinterpret_cast<const TestSimpleTableWithEnumT *>(lhs.value)) ==
- *(reinterpret_cast<const TestSimpleTableWithEnumT *>(rhs.value));
+ return *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(lhs.value)) ==
+ *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(rhs.value));
}
case Any_MyGame_Example2_Monster: {
return *(reinterpret_cast<const MyGame::Example2::MonsterT *>(lhs.value)) ==
@@ -282,7 +329,7 @@ bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<
enum AnyUniqueAliases {
AnyUniqueAliases_NONE = 0,
AnyUniqueAliases_M = 1,
- AnyUniqueAliases_T = 2,
+ AnyUniqueAliases_TS = 2,
AnyUniqueAliases_M2 = 3,
AnyUniqueAliases_MIN = AnyUniqueAliases_NONE,
AnyUniqueAliases_MAX = AnyUniqueAliases_M2
@@ -292,17 +339,17 @@ inline const AnyUniqueAliases (&EnumValuesAnyUniqueAliases())[4] {
static const AnyUniqueAliases values[] = {
AnyUniqueAliases_NONE,
AnyUniqueAliases_M,
- AnyUniqueAliases_T,
+ AnyUniqueAliases_TS,
AnyUniqueAliases_M2
};
return values;
}
inline const char * const *EnumNamesAnyUniqueAliases() {
- static const char * const names[] = {
+ static const char * const names[5] = {
"NONE",
"M",
- "T",
+ "TS",
"M2",
nullptr
};
@@ -310,7 +357,7 @@ inline const char * const *EnumNamesAnyUniqueAliases() {
}
inline const char *EnumNameAnyUniqueAliases(AnyUniqueAliases e) {
- if (e < AnyUniqueAliases_NONE || e > AnyUniqueAliases_M2) return "";
+ if (flatbuffers::IsOutRange(e, AnyUniqueAliases_NONE, AnyUniqueAliases_M2)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesAnyUniqueAliases()[index];
}
@@ -319,12 +366,12 @@ template<typename T> struct AnyUniqueAliasesTraits {
static const AnyUniqueAliases enum_value = AnyUniqueAliases_NONE;
};
-template<> struct AnyUniqueAliasesTraits<Monster> {
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::Monster> {
static const AnyUniqueAliases enum_value = AnyUniqueAliases_M;
};
-template<> struct AnyUniqueAliasesTraits<TestSimpleTableWithEnum> {
- static const AnyUniqueAliases enum_value = AnyUniqueAliases_T;
+template<> struct AnyUniqueAliasesTraits<MyGame::Example::TestSimpleTableWithEnum> {
+ static const AnyUniqueAliases enum_value = AnyUniqueAliases_TS;
};
template<> struct AnyUniqueAliasesTraits<MyGame::Example2::Monster> {
@@ -339,8 +386,8 @@ struct AnyUniqueAliasesUnion {
AnyUniqueAliasesUnion(AnyUniqueAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
type(AnyUniqueAliases_NONE), value(nullptr)
{ std::swap(type, u.type); std::swap(value, u.value); }
- AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &) FLATBUFFERS_NOEXCEPT;
- AnyUniqueAliasesUnion &operator=(const AnyUniqueAliasesUnion &u) FLATBUFFERS_NOEXCEPT
+ AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &);
+ AnyUniqueAliasesUnion &operator=(const AnyUniqueAliasesUnion &u)
{ AnyUniqueAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
AnyUniqueAliasesUnion &operator=(AnyUniqueAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
@@ -363,21 +410,21 @@ struct AnyUniqueAliasesUnion {
static void *UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver);
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
- MonsterT *AsM() {
+ MyGame::Example::MonsterT *AsM() {
return type == AnyUniqueAliases_M ?
- reinterpret_cast<MonsterT *>(value) : nullptr;
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
}
- const MonsterT *AsM() const {
+ const MyGame::Example::MonsterT *AsM() const {
return type == AnyUniqueAliases_M ?
- reinterpret_cast<const MonsterT *>(value) : nullptr;
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
}
- TestSimpleTableWithEnumT *AsT() {
- return type == AnyUniqueAliases_T ?
- reinterpret_cast<TestSimpleTableWithEnumT *>(value) : nullptr;
+ MyGame::Example::TestSimpleTableWithEnumT *AsTS() {
+ return type == AnyUniqueAliases_TS ?
+ reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
}
- const TestSimpleTableWithEnumT *AsT() const {
- return type == AnyUniqueAliases_T ?
- reinterpret_cast<const TestSimpleTableWithEnumT *>(value) : nullptr;
+ const MyGame::Example::TestSimpleTableWithEnumT *AsTS() const {
+ return type == AnyUniqueAliases_TS ?
+ reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value) : nullptr;
}
MyGame::Example2::MonsterT *AsM2() {
return type == AnyUniqueAliases_M2 ?
@@ -397,12 +444,12 @@ inline bool operator==(const AnyUniqueAliasesUnion &lhs, const AnyUniqueAliasesU
return true;
}
case AnyUniqueAliases_M: {
- return *(reinterpret_cast<const MonsterT *>(lhs.value)) ==
- *(reinterpret_cast<const MonsterT *>(rhs.value));
+ return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+ *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
}
- case AnyUniqueAliases_T: {
- return *(reinterpret_cast<const TestSimpleTableWithEnumT *>(lhs.value)) ==
- *(reinterpret_cast<const TestSimpleTableWithEnumT *>(rhs.value));
+ case AnyUniqueAliases_TS: {
+ return *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(lhs.value)) ==
+ *(reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(rhs.value));
}
case AnyUniqueAliases_M2: {
return *(reinterpret_cast<const MyGame::Example2::MonsterT *>(lhs.value)) ==
@@ -441,7 +488,7 @@ inline const AnyAmbiguousAliases (&EnumValuesAnyAmbiguousAliases())[4] {
}
inline const char * const *EnumNamesAnyAmbiguousAliases() {
- static const char * const names[] = {
+ static const char * const names[5] = {
"NONE",
"M1",
"M2",
@@ -452,7 +499,7 @@ inline const char * const *EnumNamesAnyAmbiguousAliases() {
}
inline const char *EnumNameAnyAmbiguousAliases(AnyAmbiguousAliases e) {
- if (e < AnyAmbiguousAliases_NONE || e > AnyAmbiguousAliases_M3) return "";
+ if (flatbuffers::IsOutRange(e, AnyAmbiguousAliases_NONE, AnyAmbiguousAliases_M3)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesAnyAmbiguousAliases()[index];
}
@@ -465,8 +512,8 @@ struct AnyAmbiguousAliasesUnion {
AnyAmbiguousAliasesUnion(AnyAmbiguousAliasesUnion&& u) FLATBUFFERS_NOEXCEPT :
type(AnyAmbiguousAliases_NONE), value(nullptr)
{ std::swap(type, u.type); std::swap(value, u.value); }
- AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &) FLATBUFFERS_NOEXCEPT;
- AnyAmbiguousAliasesUnion &operator=(const AnyAmbiguousAliasesUnion &u) FLATBUFFERS_NOEXCEPT
+ AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &);
+ AnyAmbiguousAliasesUnion &operator=(const AnyAmbiguousAliasesUnion &u)
{ AnyAmbiguousAliasesUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
AnyAmbiguousAliasesUnion &operator=(AnyAmbiguousAliasesUnion &&u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
@@ -477,29 +524,29 @@ struct AnyAmbiguousAliasesUnion {
static void *UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver);
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
- MonsterT *AsM1() {
+ MyGame::Example::MonsterT *AsM1() {
return type == AnyAmbiguousAliases_M1 ?
- reinterpret_cast<MonsterT *>(value) : nullptr;
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
}
- const MonsterT *AsM1() const {
+ const MyGame::Example::MonsterT *AsM1() const {
return type == AnyAmbiguousAliases_M1 ?
- reinterpret_cast<const MonsterT *>(value) : nullptr;
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
}
- MonsterT *AsM2() {
+ MyGame::Example::MonsterT *AsM2() {
return type == AnyAmbiguousAliases_M2 ?
- reinterpret_cast<MonsterT *>(value) : nullptr;
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
}
- const MonsterT *AsM2() const {
+ const MyGame::Example::MonsterT *AsM2() const {
return type == AnyAmbiguousAliases_M2 ?
- reinterpret_cast<const MonsterT *>(value) : nullptr;
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
}
- MonsterT *AsM3() {
+ MyGame::Example::MonsterT *AsM3() {
return type == AnyAmbiguousAliases_M3 ?
- reinterpret_cast<MonsterT *>(value) : nullptr;
+ reinterpret_cast<MyGame::Example::MonsterT *>(value) : nullptr;
}
- const MonsterT *AsM3() const {
+ const MyGame::Example::MonsterT *AsM3() const {
return type == AnyAmbiguousAliases_M3 ?
- reinterpret_cast<const MonsterT *>(value) : nullptr;
+ reinterpret_cast<const MyGame::Example::MonsterT *>(value) : nullptr;
}
};
@@ -511,16 +558,16 @@ inline bool operator==(const AnyAmbiguousAliasesUnion &lhs, const AnyAmbiguousAl
return true;
}
case AnyAmbiguousAliases_M1: {
- return *(reinterpret_cast<const MonsterT *>(lhs.value)) ==
- *(reinterpret_cast<const MonsterT *>(rhs.value));
+ return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+ *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
}
case AnyAmbiguousAliases_M2: {
- return *(reinterpret_cast<const MonsterT *>(lhs.value)) ==
- *(reinterpret_cast<const MonsterT *>(rhs.value));
+ return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+ *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
}
case AnyAmbiguousAliases_M3: {
- return *(reinterpret_cast<const MonsterT *>(lhs.value)) ==
- *(reinterpret_cast<const MonsterT *>(rhs.value));
+ return *(reinterpret_cast<const MyGame::Example::MonsterT *>(lhs.value)) ==
+ *(reinterpret_cast<const MyGame::Example::MonsterT *>(rhs.value));
}
default: {
return false;
@@ -587,9 +634,9 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
float z_;
int32_t padding0__;
double test1_;
- int8_t test2_;
+ uint8_t test2_;
int8_t padding1__;
- Test test3_;
+ MyGame::Example::Test test3_;
int16_t padding2__;
public:
@@ -599,13 +646,13 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
Vec3() {
memset(static_cast<void *>(this), 0, sizeof(Vec3));
}
- Vec3(float _x, float _y, float _z, double _test1, Color _test2, const Test &_test3)
+ Vec3(float _x, float _y, float _z, double _test1, MyGame::Example::Color _test2, const MyGame::Example::Test &_test3)
: x_(flatbuffers::EndianScalar(_x)),
y_(flatbuffers::EndianScalar(_y)),
z_(flatbuffers::EndianScalar(_z)),
padding0__(0),
test1_(flatbuffers::EndianScalar(_test1)),
- test2_(flatbuffers::EndianScalar(static_cast<int8_t>(_test2))),
+ test2_(flatbuffers::EndianScalar(static_cast<uint8_t>(_test2))),
padding1__(0),
test3_(_test3),
padding2__(0) {
@@ -637,16 +684,16 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Vec3 FLATBUFFERS_FINAL_CLASS {
void mutate_test1(double _test1) {
flatbuffers::WriteScalar(&test1_, _test1);
}
- Color test2() const {
- return static_cast<Color>(flatbuffers::EndianScalar(test2_));
+ MyGame::Example::Color test2() const {
+ return static_cast<MyGame::Example::Color>(flatbuffers::EndianScalar(test2_));
}
- void mutate_test2(Color _test2) {
- flatbuffers::WriteScalar(&test2_, static_cast<int8_t>(_test2));
+ void mutate_test2(MyGame::Example::Color _test2) {
+ flatbuffers::WriteScalar(&test2_, static_cast<uint8_t>(_test2));
}
- const Test &test3() const {
+ const MyGame::Example::Test &test3() const {
return test3_;
}
- Test &mutable_test3() {
+ MyGame::Example::Test &mutable_test3() {
return test3_;
}
};
@@ -734,6 +781,7 @@ inline bool operator!=(const InParentNamespaceT &lhs, const InParentNamespaceT &
struct InParentNamespace FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef InParentNamespaceT NativeTableType;
+ typedef InParentNamespaceBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return InParentNamespaceTypeTable();
}
@@ -747,6 +795,7 @@ struct InParentNamespace FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct InParentNamespaceBuilder {
+ typedef InParentNamespace Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
explicit InParentNamespaceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
@@ -788,6 +837,7 @@ inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef MonsterT NativeTableType;
+ typedef MonsterBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MonsterTypeTable();
}
@@ -801,6 +851,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct MonsterBuilder {
+ typedef Monster Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
@@ -829,9 +880,9 @@ namespace Example {
struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable {
typedef TestSimpleTableWithEnum TableType;
- Color color;
+ MyGame::Example::Color color;
TestSimpleTableWithEnumT()
- : color(Color_Green) {
+ : color(MyGame::Example::Color_Green) {
}
};
@@ -847,21 +898,22 @@ inline bool operator!=(const TestSimpleTableWithEnumT &lhs, const TestSimpleTabl
struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef TestSimpleTableWithEnumT NativeTableType;
+ typedef TestSimpleTableWithEnumBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TestSimpleTableWithEnumTypeTable();
}
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_COLOR = 4
};
- Color color() const {
- return static_cast<Color>(GetField<int8_t>(VT_COLOR, 2));
+ MyGame::Example::Color color() const {
+ return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 2));
}
- bool mutate_color(Color _color) {
- return SetField<int8_t>(VT_COLOR, static_cast<int8_t>(_color), 2);
+ bool mutate_color(MyGame::Example::Color _color) {
+ return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 2);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
- VerifyField<int8_t>(verifier, VT_COLOR) &&
+ VerifyField<uint8_t>(verifier, VT_COLOR) &&
verifier.EndTable();
}
TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
@@ -870,10 +922,11 @@ struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Ta
};
struct TestSimpleTableWithEnumBuilder {
+ typedef TestSimpleTableWithEnum Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
- void add_color(Color color) {
- fbb_.AddElement<int8_t>(TestSimpleTableWithEnum::VT_COLOR, static_cast<int8_t>(color), 2);
+ void add_color(MyGame::Example::Color color) {
+ fbb_.AddElement<uint8_t>(TestSimpleTableWithEnum::VT_COLOR, static_cast<uint8_t>(color), 2);
}
explicit TestSimpleTableWithEnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
@@ -889,7 +942,7 @@ struct TestSimpleTableWithEnumBuilder {
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(
flatbuffers::FlatBufferBuilder &_fbb,
- Color color = Color_Green) {
+ MyGame::Example::Color color = MyGame::Example::Color_Green) {
TestSimpleTableWithEnumBuilder builder_(_fbb);
builder_.add_color(color);
return builder_.Finish();
@@ -922,6 +975,7 @@ inline bool operator!=(const StatT &lhs, const StatT &rhs) {
struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef StatT NativeTableType;
+ typedef StatBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return StatTypeTable();
}
@@ -962,6 +1016,7 @@ struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct StatBuilder {
+ typedef Stat Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_id(flatbuffers::Offset<flatbuffers::String> id) {
@@ -1032,6 +1087,7 @@ inline bool operator!=(const ReferrableT &lhs, const ReferrableT &rhs) {
struct Referrable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef ReferrableT NativeTableType;
+ typedef ReferrableBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return ReferrableTypeTable();
}
@@ -1061,6 +1117,7 @@ struct Referrable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct ReferrableBuilder {
+ typedef Referrable Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_id(uint64_t id) {
@@ -1090,19 +1147,19 @@ flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferBuilder
struct MonsterT : public flatbuffers::NativeTable {
typedef Monster TableType;
- flatbuffers::unique_ptr<Vec3> pos;
+ flatbuffers::unique_ptr<MyGame::Example::Vec3> pos;
int16_t mana;
int16_t hp;
std::string name;
std::vector<uint8_t> inventory;
- Color color;
- AnyUnion test;
- std::vector<Test> test4;
+ MyGame::Example::Color color;
+ MyGame::Example::AnyUnion test;
+ std::vector<MyGame::Example::Test> test4;
std::vector<std::string> testarrayofstring;
- std::vector<flatbuffers::unique_ptr<MonsterT>> testarrayoftables;
- flatbuffers::unique_ptr<MonsterT> enemy;
+ std::vector<flatbuffers::unique_ptr<MyGame::Example::MonsterT>> testarrayoftables;
+ flatbuffers::unique_ptr<MyGame::Example::MonsterT> enemy;
std::vector<uint8_t> testnestedflatbuffer;
- flatbuffers::unique_ptr<StatT> testempty;
+ flatbuffers::unique_ptr<MyGame::Example::StatT> testempty;
bool testbool;
int32_t testhashs32_fnv1;
uint32_t testhashu32_fnv1;
@@ -1117,27 +1174,28 @@ struct MonsterT : public flatbuffers::NativeTable {
float testf2;
float testf3;
std::vector<std::string> testarrayofstring2;
- std::vector<Ability> testarrayofsortedstruct;
+ std::vector<MyGame::Example::Ability> testarrayofsortedstruct;
std::vector<uint8_t> flex;
- std::vector<Test> test5;
+ std::vector<MyGame::Example::Test> test5;
std::vector<int64_t> vector_of_longs;
std::vector<double> vector_of_doubles;
flatbuffers::unique_ptr<MyGame::InParentNamespaceT> parent_namespace_test;
- std::vector<flatbuffers::unique_ptr<ReferrableT>> vector_of_referrables;
+ std::vector<flatbuffers::unique_ptr<MyGame::Example::ReferrableT>> vector_of_referrables;
ReferrableT *single_weak_reference;
std::vector<ReferrableT *> vector_of_weak_references;
- std::vector<flatbuffers::unique_ptr<ReferrableT>> vector_of_strong_referrables;
+ std::vector<flatbuffers::unique_ptr<MyGame::Example::ReferrableT>> vector_of_strong_referrables;
ReferrableT *co_owning_reference;
std::vector<flatbuffers::unique_ptr<ReferrableT>> vector_of_co_owning_references;
ReferrableT *non_owning_reference;
std::vector<ReferrableT *> vector_of_non_owning_references;
- AnyUniqueAliasesUnion any_unique;
- AnyAmbiguousAliasesUnion any_ambiguous;
- std::vector<Color> vector_of_enums;
+ MyGame::Example::AnyUniqueAliasesUnion any_unique;
+ MyGame::Example::AnyAmbiguousAliasesUnion any_ambiguous;
+ std::vector<MyGame::Example::Color> vector_of_enums;
+ MyGame::Example::Race signed_enum;
MonsterT()
: mana(150),
hp(100),
- color(Color_Blue),
+ color(MyGame::Example::Color_Blue),
testbool(false),
testhashs32_fnv1(0),
testhashu32_fnv1(0),
@@ -1152,7 +1210,8 @@ struct MonsterT : public flatbuffers::NativeTable {
testf3(0.0f),
single_weak_reference(nullptr),
co_owning_reference(nullptr),
- non_owning_reference(nullptr) {
+ non_owning_reference(nullptr),
+ signed_enum(MyGame::Example::Race_None) {
}
};
@@ -1201,7 +1260,8 @@ inline bool operator==(const MonsterT &lhs, const MonsterT &rhs) {
(lhs.vector_of_non_owning_references == rhs.vector_of_non_owning_references) &&
(lhs.any_unique == rhs.any_unique) &&
(lhs.any_ambiguous == rhs.any_ambiguous) &&
- (lhs.vector_of_enums == rhs.vector_of_enums);
+ (lhs.vector_of_enums == rhs.vector_of_enums) &&
+ (lhs.signed_enum == rhs.signed_enum);
}
inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
@@ -1209,9 +1269,10 @@ inline bool operator!=(const MonsterT &lhs, const MonsterT &rhs) {
}
-/// an example documentation comment: monster object
+/// an example documentation comment: "monster object"
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef MonsterT NativeTableType;
+ typedef MonsterBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MonsterTypeTable();
}
@@ -1262,13 +1323,14 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_ANY_UNIQUE = 92,
VT_ANY_AMBIGUOUS_TYPE = 94,
VT_ANY_AMBIGUOUS = 96,
- VT_VECTOR_OF_ENUMS = 98
+ VT_VECTOR_OF_ENUMS = 98,
+ VT_SIGNED_ENUM = 100
};
- const Vec3 *pos() const {
- return GetStruct<const Vec3 *>(VT_POS);
+ const MyGame::Example::Vec3 *pos() const {
+ return GetStruct<const MyGame::Example::Vec3 *>(VT_POS);
}
- Vec3 *mutable_pos() {
- return GetStruct<Vec3 *>(VT_POS);
+ MyGame::Example::Vec3 *mutable_pos() {
+ return GetStruct<MyGame::Example::Vec3 *>(VT_POS);
}
int16_t mana() const {
return GetField<int16_t>(VT_MANA, 150);
@@ -1300,39 +1362,36 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
flatbuffers::Vector<uint8_t> *mutable_inventory() {
return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
}
- Color color() const {
- return static_cast<Color>(GetField<int8_t>(VT_COLOR, 8));
- }
- bool mutate_color(Color _color) {
- return SetField<int8_t>(VT_COLOR, static_cast<int8_t>(_color), 8);
+ MyGame::Example::Color color() const {
+ return static_cast<MyGame::Example::Color>(GetField<uint8_t>(VT_COLOR, 8));
}
- Any test_type() const {
- return static_cast<Any>(GetField<uint8_t>(VT_TEST_TYPE, 0));
+ bool mutate_color(MyGame::Example::Color _color) {
+ return SetField<uint8_t>(VT_COLOR, static_cast<uint8_t>(_color), 8);
}
- bool mutate_test_type(Any _test_type) {
- return SetField<uint8_t>(VT_TEST_TYPE, static_cast<uint8_t>(_test_type), 0);
+ MyGame::Example::Any test_type() const {
+ return static_cast<MyGame::Example::Any>(GetField<uint8_t>(VT_TEST_TYPE, 0));
}
const void *test() const {
return GetPointer<const void *>(VT_TEST);
}
template<typename T> const T *test_as() const;
- const Monster *test_as_Monster() const {
- return test_type() == Any_Monster ? static_cast<const Monster *>(test()) : nullptr;
+ const MyGame::Example::Monster *test_as_Monster() const {
+ return test_type() == MyGame::Example::Any_Monster ? static_cast<const MyGame::Example::Monster *>(test()) : nullptr;
}
- const TestSimpleTableWithEnum *test_as_TestSimpleTableWithEnum() const {
- return test_type() == Any_TestSimpleTableWithEnum ? static_cast<const TestSimpleTableWithEnum *>(test()) : nullptr;
+ const MyGame::Example::TestSimpleTableWithEnum *test_as_TestSimpleTableWithEnum() const {
+ return test_type() == MyGame::Example::Any_TestSimpleTableWithEnum ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(test()) : nullptr;
}
const MyGame::Example2::Monster *test_as_MyGame_Example2_Monster() const {
- return test_type() == Any_MyGame_Example2_Monster ? static_cast<const MyGame::Example2::Monster *>(test()) : nullptr;
+ return test_type() == MyGame::Example::Any_MyGame_Example2_Monster ? static_cast<const MyGame::Example2::Monster *>(test()) : nullptr;
}
void *mutable_test() {
return GetPointer<void *>(VT_TEST);
}
- const flatbuffers::Vector<const Test *> *test4() const {
- return GetPointer<const flatbuffers::Vector<const Test *> *>(VT_TEST4);
+ const flatbuffers::Vector<const MyGame::Example::Test *> *test4() const {
+ return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
}
- flatbuffers::Vector<const Test *> *mutable_test4() {
- return GetPointer<flatbuffers::Vector<const Test *> *>(VT_TEST4);
+ flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test4() {
+ return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST4);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING);
@@ -1342,17 +1401,17 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
}
/// an example documentation comment: this will end up in the generated code
/// multiline too
- const flatbuffers::Vector<flatbuffers::Offset<Monster>> *testarrayoftables() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Monster>> *>(VT_TESTARRAYOFTABLES);
+ const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
}
- flatbuffers::Vector<flatbuffers::Offset<Monster>> *mutable_testarrayoftables() {
- return GetPointer<flatbuffers::Vector<flatbuffers::Offset<Monster>> *>(VT_TESTARRAYOFTABLES);
+ flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *mutable_testarrayoftables() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>> *>(VT_TESTARRAYOFTABLES);
}
- const Monster *enemy() const {
- return GetPointer<const Monster *>(VT_ENEMY);
+ const MyGame::Example::Monster *enemy() const {
+ return GetPointer<const MyGame::Example::Monster *>(VT_ENEMY);
}
- Monster *mutable_enemy() {
- return GetPointer<Monster *>(VT_ENEMY);
+ MyGame::Example::Monster *mutable_enemy() {
+ return GetPointer<MyGame::Example::Monster *>(VT_ENEMY);
}
const flatbuffers::Vector<uint8_t> *testnestedflatbuffer() const {
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_TESTNESTEDFLATBUFFER);
@@ -1363,11 +1422,11 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const MyGame::Example::Monster *testnestedflatbuffer_nested_root() const {
return flatbuffers::GetRoot<MyGame::Example::Monster>(testnestedflatbuffer()->Data());
}
- const Stat *testempty() const {
- return GetPointer<const Stat *>(VT_TESTEMPTY);
+ const MyGame::Example::Stat *testempty() const {
+ return GetPointer<const MyGame::Example::Stat *>(VT_TESTEMPTY);
}
- Stat *mutable_testempty() {
- return GetPointer<Stat *>(VT_TESTEMPTY);
+ MyGame::Example::Stat *mutable_testempty() {
+ return GetPointer<MyGame::Example::Stat *>(VT_TESTEMPTY);
}
bool testbool() const {
return GetField<uint8_t>(VT_TESTBOOL, 0) != 0;
@@ -1453,11 +1512,11 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *mutable_testarrayofstring2() {
return GetPointer<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TESTARRAYOFSTRING2);
}
- const flatbuffers::Vector<const Ability *> *testarrayofsortedstruct() const {
- return GetPointer<const flatbuffers::Vector<const Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+ const flatbuffers::Vector<const MyGame::Example::Ability *> *testarrayofsortedstruct() const {
+ return GetPointer<const flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
}
- flatbuffers::Vector<const Ability *> *mutable_testarrayofsortedstruct() {
- return GetPointer<flatbuffers::Vector<const Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
+ flatbuffers::Vector<const MyGame::Example::Ability *> *mutable_testarrayofsortedstruct() {
+ return GetPointer<flatbuffers::Vector<const MyGame::Example::Ability *> *>(VT_TESTARRAYOFSORTEDSTRUCT);
}
const flatbuffers::Vector<uint8_t> *flex() const {
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_FLEX);
@@ -1468,11 +1527,11 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
flexbuffers::Reference flex_flexbuffer_root() const {
return flexbuffers::GetRoot(flex()->Data(), flex()->size());
}
- const flatbuffers::Vector<const Test *> *test5() const {
- return GetPointer<const flatbuffers::Vector<const Test *> *>(VT_TEST5);
+ const flatbuffers::Vector<const MyGame::Example::Test *> *test5() const {
+ return GetPointer<const flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
}
- flatbuffers::Vector<const Test *> *mutable_test5() {
- return GetPointer<flatbuffers::Vector<const Test *> *>(VT_TEST5);
+ flatbuffers::Vector<const MyGame::Example::Test *> *mutable_test5() {
+ return GetPointer<flatbuffers::Vector<const MyGame::Example::Test *> *>(VT_TEST5);
}
const flatbuffers::Vector<int64_t> *vector_of_longs() const {
return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_VECTOR_OF_LONGS);
@@ -1492,11 +1551,11 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
MyGame::InParentNamespace *mutable_parent_namespace_test() {
return GetPointer<MyGame::InParentNamespace *>(VT_PARENT_NAMESPACE_TEST);
}
- const flatbuffers::Vector<flatbuffers::Offset<Referrable>> *vector_of_referrables() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+ const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
}
- flatbuffers::Vector<flatbuffers::Offset<Referrable>> *mutable_vector_of_referrables() {
- return GetPointer<flatbuffers::Vector<flatbuffers::Offset<Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
+ flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_referrables() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_REFERRABLES);
}
uint64_t single_weak_reference() const {
return GetField<uint64_t>(VT_SINGLE_WEAK_REFERENCE, 0);
@@ -1510,11 +1569,11 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
flatbuffers::Vector<uint64_t> *mutable_vector_of_weak_references() {
return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_WEAK_REFERENCES);
}
- const flatbuffers::Vector<flatbuffers::Offset<Referrable>> *vector_of_strong_referrables() const {
- return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+ const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables() const {
+ return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
}
- flatbuffers::Vector<flatbuffers::Offset<Referrable>> *mutable_vector_of_strong_referrables() {
- return GetPointer<flatbuffers::Vector<flatbuffers::Offset<Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
+ flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *mutable_vector_of_strong_referrables() {
+ return GetPointer<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>> *>(VT_VECTOR_OF_STRONG_REFERRABLES);
}
uint64_t co_owning_reference() const {
return GetField<uint64_t>(VT_CO_OWNING_REFERENCE, 0);
@@ -1540,65 +1599,65 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
flatbuffers::Vector<uint64_t> *mutable_vector_of_non_owning_references() {
return GetPointer<flatbuffers::Vector<uint64_t> *>(VT_VECTOR_OF_NON_OWNING_REFERENCES);
}
- AnyUniqueAliases any_unique_type() const {
- return static_cast<AnyUniqueAliases>(GetField<uint8_t>(VT_ANY_UNIQUE_TYPE, 0));
- }
- bool mutate_any_unique_type(AnyUniqueAliases _any_unique_type) {
- return SetField<uint8_t>(VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(_any_unique_type), 0);
+ MyGame::Example::AnyUniqueAliases any_unique_type() const {
+ return static_cast<MyGame::Example::AnyUniqueAliases>(GetField<uint8_t>(VT_ANY_UNIQUE_TYPE, 0));
}
const void *any_unique() const {
return GetPointer<const void *>(VT_ANY_UNIQUE);
}
template<typename T> const T *any_unique_as() const;
- const Monster *any_unique_as_M() const {
- return any_unique_type() == AnyUniqueAliases_M ? static_cast<const Monster *>(any_unique()) : nullptr;
+ const MyGame::Example::Monster *any_unique_as_M() const {
+ return any_unique_type() == MyGame::Example::AnyUniqueAliases_M ? static_cast<const MyGame::Example::Monster *>(any_unique()) : nullptr;
}
- const TestSimpleTableWithEnum *any_unique_as_T() const {
- return any_unique_type() == AnyUniqueAliases_T ? static_cast<const TestSimpleTableWithEnum *>(any_unique()) : nullptr;
+ const MyGame::Example::TestSimpleTableWithEnum *any_unique_as_TS() const {
+ return any_unique_type() == MyGame::Example::AnyUniqueAliases_TS ? static_cast<const MyGame::Example::TestSimpleTableWithEnum *>(any_unique()) : nullptr;
}
const MyGame::Example2::Monster *any_unique_as_M2() const {
- return any_unique_type() == AnyUniqueAliases_M2 ? static_cast<const MyGame::Example2::Monster *>(any_unique()) : nullptr;
+ return any_unique_type() == MyGame::Example::AnyUniqueAliases_M2 ? static_cast<const MyGame::Example2::Monster *>(any_unique()) : nullptr;
}
void *mutable_any_unique() {
return GetPointer<void *>(VT_ANY_UNIQUE);
}
- AnyAmbiguousAliases any_ambiguous_type() const {
- return static_cast<AnyAmbiguousAliases>(GetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, 0));
- }
- bool mutate_any_ambiguous_type(AnyAmbiguousAliases _any_ambiguous_type) {
- return SetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(_any_ambiguous_type), 0);
+ MyGame::Example::AnyAmbiguousAliases any_ambiguous_type() const {
+ return static_cast<MyGame::Example::AnyAmbiguousAliases>(GetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, 0));
}
const void *any_ambiguous() const {
return GetPointer<const void *>(VT_ANY_AMBIGUOUS);
}
- const Monster *any_ambiguous_as_M1() const {
- return any_ambiguous_type() == AnyAmbiguousAliases_M1 ? static_cast<const Monster *>(any_ambiguous()) : nullptr;
+ const MyGame::Example::Monster *any_ambiguous_as_M1() const {
+ return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M1 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
}
- const Monster *any_ambiguous_as_M2() const {
- return any_ambiguous_type() == AnyAmbiguousAliases_M2 ? static_cast<const Monster *>(any_ambiguous()) : nullptr;
+ const MyGame::Example::Monster *any_ambiguous_as_M2() const {
+ return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M2 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
}
- const Monster *any_ambiguous_as_M3() const {
- return any_ambiguous_type() == AnyAmbiguousAliases_M3 ? static_cast<const Monster *>(any_ambiguous()) : nullptr;
+ const MyGame::Example::Monster *any_ambiguous_as_M3() const {
+ return any_ambiguous_type() == MyGame::Example::AnyAmbiguousAliases_M3 ? static_cast<const MyGame::Example::Monster *>(any_ambiguous()) : nullptr;
}
void *mutable_any_ambiguous() {
return GetPointer<void *>(VT_ANY_AMBIGUOUS);
}
- const flatbuffers::Vector<int8_t> *vector_of_enums() const {
- return GetPointer<const flatbuffers::Vector<int8_t> *>(VT_VECTOR_OF_ENUMS);
+ const flatbuffers::Vector<uint8_t> *vector_of_enums() const {
+ return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_VECTOR_OF_ENUMS);
+ }
+ flatbuffers::Vector<uint8_t> *mutable_vector_of_enums() {
+ return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_VECTOR_OF_ENUMS);
}
- flatbuffers::Vector<int8_t> *mutable_vector_of_enums() {
- return GetPointer<flatbuffers::Vector<int8_t> *>(VT_VECTOR_OF_ENUMS);
+ MyGame::Example::Race signed_enum() const {
+ return static_cast<MyGame::Example::Race>(GetField<int8_t>(VT_SIGNED_ENUM, -1));
+ }
+ bool mutate_signed_enum(MyGame::Example::Race _signed_enum) {
+ return SetField<int8_t>(VT_SIGNED_ENUM, static_cast<int8_t>(_signed_enum), -1);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
- VerifyField<Vec3>(verifier, VT_POS) &&
+ VerifyField<MyGame::Example::Vec3>(verifier, VT_POS) &&
VerifyField<int16_t>(verifier, VT_MANA) &&
VerifyField<int16_t>(verifier, VT_HP) &&
VerifyOffsetRequired(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyOffset(verifier, VT_INVENTORY) &&
verifier.VerifyVector(inventory()) &&
- VerifyField<int8_t>(verifier, VT_COLOR) &&
+ VerifyField<uint8_t>(verifier, VT_COLOR) &&
VerifyField<uint8_t>(verifier, VT_TEST_TYPE) &&
VerifyOffset(verifier, VT_TEST) &&
VerifyAny(verifier, test(), test_type()) &&
@@ -1668,6 +1727,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyAnyAmbiguousAliases(verifier, any_ambiguous(), any_ambiguous_type()) &&
VerifyOffset(verifier, VT_VECTOR_OF_ENUMS) &&
verifier.VerifyVector(vector_of_enums()) &&
+ VerifyField<int8_t>(verifier, VT_SIGNED_ENUM) &&
verifier.EndTable();
}
MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
@@ -1675,11 +1735,11 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
-template<> inline const Monster *Monster::test_as<Monster>() const {
+template<> inline const MyGame::Example::Monster *Monster::test_as<MyGame::Example::Monster>() const {
return test_as_Monster();
}
-template<> inline const TestSimpleTableWithEnum *Monster::test_as<TestSimpleTableWithEnum>() const {
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::test_as<MyGame::Example::TestSimpleTableWithEnum>() const {
return test_as_TestSimpleTableWithEnum();
}
@@ -1687,12 +1747,12 @@ template<> inline const MyGame::Example2::Monster *Monster::test_as<MyGame::Exam
return test_as_MyGame_Example2_Monster();
}
-template<> inline const Monster *Monster::any_unique_as<Monster>() const {
+template<> inline const MyGame::Example::Monster *Monster::any_unique_as<MyGame::Example::Monster>() const {
return any_unique_as_M();
}
-template<> inline const TestSimpleTableWithEnum *Monster::any_unique_as<TestSimpleTableWithEnum>() const {
- return any_unique_as_T();
+template<> inline const MyGame::Example::TestSimpleTableWithEnum *Monster::any_unique_as<MyGame::Example::TestSimpleTableWithEnum>() const {
+ return any_unique_as_TS();
}
template<> inline const MyGame::Example2::Monster *Monster::any_unique_as<MyGame::Example2::Monster>() const {
@@ -1700,9 +1760,10 @@ template<> inline const MyGame::Example2::Monster *Monster::any_unique_as<MyGame
}
struct MonsterBuilder {
+ typedef Monster Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
- void add_pos(const Vec3 *pos) {
+ void add_pos(const MyGame::Example::Vec3 *pos) {
fbb_.AddStruct(Monster::VT_POS, pos);
}
void add_mana(int16_t mana) {
@@ -1717,31 +1778,31 @@ struct MonsterBuilder {
void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) {
fbb_.AddOffset(Monster::VT_INVENTORY, inventory);
}
- void add_color(Color color) {
- fbb_.AddElement<int8_t>(Monster::VT_COLOR, static_cast<int8_t>(color), 8);
+ void add_color(MyGame::Example::Color color) {
+ fbb_.AddElement<uint8_t>(Monster::VT_COLOR, static_cast<uint8_t>(color), 8);
}
- void add_test_type(Any test_type) {
+ void add_test_type(MyGame::Example::Any test_type) {
fbb_.AddElement<uint8_t>(Monster::VT_TEST_TYPE, static_cast<uint8_t>(test_type), 0);
}
void add_test(flatbuffers::Offset<void> test) {
fbb_.AddOffset(Monster::VT_TEST, test);
}
- void add_test4(flatbuffers::Offset<flatbuffers::Vector<const Test *>> test4) {
+ void add_test4(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4) {
fbb_.AddOffset(Monster::VT_TEST4, test4);
}
void add_testarrayofstring(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring) {
fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING, testarrayofstring);
}
- void add_testarrayoftables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Monster>>> testarrayoftables) {
+ void add_testarrayoftables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables) {
fbb_.AddOffset(Monster::VT_TESTARRAYOFTABLES, testarrayoftables);
}
- void add_enemy(flatbuffers::Offset<Monster> enemy) {
+ void add_enemy(flatbuffers::Offset<MyGame::Example::Monster> enemy) {
fbb_.AddOffset(Monster::VT_ENEMY, enemy);
}
void add_testnestedflatbuffer(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer) {
fbb_.AddOffset(Monster::VT_TESTNESTEDFLATBUFFER, testnestedflatbuffer);
}
- void add_testempty(flatbuffers::Offset<Stat> testempty) {
+ void add_testempty(flatbuffers::Offset<MyGame::Example::Stat> testempty) {
fbb_.AddOffset(Monster::VT_TESTEMPTY, testempty);
}
void add_testbool(bool testbool) {
@@ -1786,13 +1847,13 @@ struct MonsterBuilder {
void add_testarrayofstring2(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2) {
fbb_.AddOffset(Monster::VT_TESTARRAYOFSTRING2, testarrayofstring2);
}
- void add_testarrayofsortedstruct(flatbuffers::Offset<flatbuffers::Vector<const Ability *>> testarrayofsortedstruct) {
+ void add_testarrayofsortedstruct(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct) {
fbb_.AddOffset(Monster::VT_TESTARRAYOFSORTEDSTRUCT, testarrayofsortedstruct);
}
void add_flex(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex) {
fbb_.AddOffset(Monster::VT_FLEX, flex);
}
- void add_test5(flatbuffers::Offset<flatbuffers::Vector<const Test *>> test5) {
+ void add_test5(flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5) {
fbb_.AddOffset(Monster::VT_TEST5, test5);
}
void add_vector_of_longs(flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs) {
@@ -1804,7 +1865,7 @@ struct MonsterBuilder {
void add_parent_namespace_test(flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test) {
fbb_.AddOffset(Monster::VT_PARENT_NAMESPACE_TEST, parent_namespace_test);
}
- void add_vector_of_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Referrable>>> vector_of_referrables) {
+ void add_vector_of_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables) {
fbb_.AddOffset(Monster::VT_VECTOR_OF_REFERRABLES, vector_of_referrables);
}
void add_single_weak_reference(uint64_t single_weak_reference) {
@@ -1813,7 +1874,7 @@ struct MonsterBuilder {
void add_vector_of_weak_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references) {
fbb_.AddOffset(Monster::VT_VECTOR_OF_WEAK_REFERENCES, vector_of_weak_references);
}
- void add_vector_of_strong_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Referrable>>> vector_of_strong_referrables) {
+ void add_vector_of_strong_referrables(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables) {
fbb_.AddOffset(Monster::VT_VECTOR_OF_STRONG_REFERRABLES, vector_of_strong_referrables);
}
void add_co_owning_reference(uint64_t co_owning_reference) {
@@ -1828,21 +1889,24 @@ struct MonsterBuilder {
void add_vector_of_non_owning_references(flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references) {
fbb_.AddOffset(Monster::VT_VECTOR_OF_NON_OWNING_REFERENCES, vector_of_non_owning_references);
}
- void add_any_unique_type(AnyUniqueAliases any_unique_type) {
+ void add_any_unique_type(MyGame::Example::AnyUniqueAliases any_unique_type) {
fbb_.AddElement<uint8_t>(Monster::VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(any_unique_type), 0);
}
void add_any_unique(flatbuffers::Offset<void> any_unique) {
fbb_.AddOffset(Monster::VT_ANY_UNIQUE, any_unique);
}
- void add_any_ambiguous_type(AnyAmbiguousAliases any_ambiguous_type) {
+ void add_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases any_ambiguous_type) {
fbb_.AddElement<uint8_t>(Monster::VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(any_ambiguous_type), 0);
}
void add_any_ambiguous(flatbuffers::Offset<void> any_ambiguous) {
fbb_.AddOffset(Monster::VT_ANY_AMBIGUOUS, any_ambiguous);
}
- void add_vector_of_enums(flatbuffers::Offset<flatbuffers::Vector<int8_t>> vector_of_enums) {
+ void add_vector_of_enums(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> vector_of_enums) {
fbb_.AddOffset(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
}
+ void add_signed_enum(MyGame::Example::Race signed_enum) {
+ fbb_.AddElement<int8_t>(Monster::VT_SIGNED_ENUM, static_cast<int8_t>(signed_enum), -1);
+ }
explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
@@ -1858,20 +1922,20 @@ struct MonsterBuilder {
inline flatbuffers::Offset<Monster> CreateMonster(
flatbuffers::FlatBufferBuilder &_fbb,
- const Vec3 *pos = 0,
+ const MyGame::Example::Vec3 *pos = 0,
int16_t mana = 150,
int16_t hp = 100,
flatbuffers::Offset<flatbuffers::String> name = 0,
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory = 0,
- Color color = Color_Blue,
- Any test_type = Any_NONE,
+ MyGame::Example::Color color = MyGame::Example::Color_Blue,
+ MyGame::Example::Any test_type = MyGame::Example::Any_NONE,
flatbuffers::Offset<void> test = 0,
- flatbuffers::Offset<flatbuffers::Vector<const Test *>> test4 = 0,
+ flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test4 = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Monster>>> testarrayoftables = 0,
- flatbuffers::Offset<Monster> enemy = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Monster>>> testarrayoftables = 0,
+ flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> testnestedflatbuffer = 0,
- flatbuffers::Offset<Stat> testempty = 0,
+ flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
bool testbool = false,
int32_t testhashs32_fnv1 = 0,
uint32_t testhashu32_fnv1 = 0,
@@ -1886,25 +1950,26 @@ inline flatbuffers::Offset<Monster> CreateMonster(
float testf2 = 3.0f,
float testf3 = 0.0f,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> testarrayofstring2 = 0,
- flatbuffers::Offset<flatbuffers::Vector<const Ability *>> testarrayofsortedstruct = 0,
+ flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Ability *>> testarrayofsortedstruct = 0,
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> flex = 0,
- flatbuffers::Offset<flatbuffers::Vector<const Test *>> test5 = 0,
+ flatbuffers::Offset<flatbuffers::Vector<const MyGame::Example::Test *>> test5 = 0,
flatbuffers::Offset<flatbuffers::Vector<int64_t>> vector_of_longs = 0,
flatbuffers::Offset<flatbuffers::Vector<double>> vector_of_doubles = 0,
flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Referrable>>> vector_of_referrables = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_referrables = 0,
uint64_t single_weak_reference = 0,
flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_weak_references = 0,
- flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Referrable>>> vector_of_strong_referrables = 0,
+ flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<MyGame::Example::Referrable>>> vector_of_strong_referrables = 0,
uint64_t co_owning_reference = 0,
flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_co_owning_references = 0,
uint64_t non_owning_reference = 0,
flatbuffers::Offset<flatbuffers::Vector<uint64_t>> vector_of_non_owning_references = 0,
- AnyUniqueAliases any_unique_type = AnyUniqueAliases_NONE,
+ MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases_NONE,
flatbuffers::Offset<void> any_unique = 0,
- AnyAmbiguousAliases any_ambiguous_type = AnyAmbiguousAliases_NONE,
+ MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases_NONE,
flatbuffers::Offset<void> any_ambiguous = 0,
- flatbuffers::Offset<flatbuffers::Vector<int8_t>> vector_of_enums = 0) {
+ flatbuffers::Offset<flatbuffers::Vector<uint8_t>> vector_of_enums = 0,
+ MyGame::Example::Race signed_enum = MyGame::Example::Race_None) {
MonsterBuilder builder_(_fbb);
builder_.add_non_owning_reference(non_owning_reference);
builder_.add_co_owning_reference(co_owning_reference);
@@ -1948,6 +2013,7 @@ inline flatbuffers::Offset<Monster> CreateMonster(
builder_.add_pos(pos);
builder_.add_hp(hp);
builder_.add_mana(mana);
+ builder_.add_signed_enum(signed_enum);
builder_.add_any_ambiguous_type(any_ambiguous_type);
builder_.add_any_unique_type(any_unique_type);
builder_.add_testbool(testbool);
@@ -1958,20 +2024,20 @@ inline flatbuffers::Offset<Monster> CreateMonster(
inline flatbuffers::Offset<Monster> CreateMonsterDirect(
flatbuffers::FlatBufferBuilder &_fbb,
- const Vec3 *pos = 0,
+ const MyGame::Example::Vec3 *pos = 0,
int16_t mana = 150,
int16_t hp = 100,
const char *name = nullptr,
const std::vector<uint8_t> *inventory = nullptr,
- Color color = Color_Blue,
- Any test_type = Any_NONE,
+ MyGame::Example::Color color = MyGame::Example::Color_Blue,
+ MyGame::Example::Any test_type = MyGame::Example::Any_NONE,
flatbuffers::Offset<void> test = 0,
- const std::vector<Test> *test4 = nullptr,
+ const std::vector<MyGame::Example::Test> *test4 = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring = nullptr,
- const std::vector<flatbuffers::Offset<Monster>> *testarrayoftables = nullptr,
- flatbuffers::Offset<Monster> enemy = 0,
+ std::vector<flatbuffers::Offset<MyGame::Example::Monster>> *testarrayoftables = nullptr,
+ flatbuffers::Offset<MyGame::Example::Monster> enemy = 0,
const std::vector<uint8_t> *testnestedflatbuffer = nullptr,
- flatbuffers::Offset<Stat> testempty = 0,
+ flatbuffers::Offset<MyGame::Example::Stat> testempty = 0,
bool testbool = false,
int32_t testhashs32_fnv1 = 0,
uint32_t testhashu32_fnv1 = 0,
@@ -1986,44 +2052,45 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(
float testf2 = 3.0f,
float testf3 = 0.0f,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *testarrayofstring2 = nullptr,
- const std::vector<Ability> *testarrayofsortedstruct = nullptr,
+ std::vector<MyGame::Example::Ability> *testarrayofsortedstruct = nullptr,
const std::vector<uint8_t> *flex = nullptr,
- const std::vector<Test> *test5 = nullptr,
+ const std::vector<MyGame::Example::Test> *test5 = nullptr,
const std::vector<int64_t> *vector_of_longs = nullptr,
const std::vector<double> *vector_of_doubles = nullptr,
flatbuffers::Offset<MyGame::InParentNamespace> parent_namespace_test = 0,
- const std::vector<flatbuffers::Offset<Referrable>> *vector_of_referrables = nullptr,
+ std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_referrables = nullptr,
uint64_t single_weak_reference = 0,
const std::vector<uint64_t> *vector_of_weak_references = nullptr,
- const std::vector<flatbuffers::Offset<Referrable>> *vector_of_strong_referrables = nullptr,
+ std::vector<flatbuffers::Offset<MyGame::Example::Referrable>> *vector_of_strong_referrables = nullptr,
uint64_t co_owning_reference = 0,
const std::vector<uint64_t> *vector_of_co_owning_references = nullptr,
uint64_t non_owning_reference = 0,
const std::vector<uint64_t> *vector_of_non_owning_references = nullptr,
- AnyUniqueAliases any_unique_type = AnyUniqueAliases_NONE,
+ MyGame::Example::AnyUniqueAliases any_unique_type = MyGame::Example::AnyUniqueAliases_NONE,
flatbuffers::Offset<void> any_unique = 0,
- AnyAmbiguousAliases any_ambiguous_type = AnyAmbiguousAliases_NONE,
+ MyGame::Example::AnyAmbiguousAliases any_ambiguous_type = MyGame::Example::AnyAmbiguousAliases_NONE,
flatbuffers::Offset<void> any_ambiguous = 0,
- const std::vector<int8_t> *vector_of_enums = nullptr) {
+ const std::vector<uint8_t> *vector_of_enums = nullptr,
+ MyGame::Example::Race signed_enum = MyGame::Example::Race_None) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto inventory__ = inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0;
- auto test4__ = test4 ? _fbb.CreateVectorOfStructs<Test>(*test4) : 0;
+ auto test4__ = test4 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test4) : 0;
auto testarrayofstring__ = testarrayofstring ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring) : 0;
- auto testarrayoftables__ = testarrayoftables ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(*testarrayoftables) : 0;
+ auto testarrayoftables__ = testarrayoftables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Monster>(testarrayoftables) : 0;
auto testnestedflatbuffer__ = testnestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testnestedflatbuffer) : 0;
auto testarrayofbools__ = testarrayofbools ? _fbb.CreateVector<uint8_t>(*testarrayofbools) : 0;
auto testarrayofstring2__ = testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0;
- auto testarrayofsortedstruct__ = testarrayofsortedstruct ? _fbb.CreateVectorOfStructs<Ability>(*testarrayofsortedstruct) : 0;
+ auto testarrayofsortedstruct__ = testarrayofsortedstruct ? _fbb.CreateVectorOfSortedStructs<MyGame::Example::Ability>(testarrayofsortedstruct) : 0;
auto flex__ = flex ? _fbb.CreateVector<uint8_t>(*flex) : 0;
- auto test5__ = test5 ? _fbb.CreateVectorOfStructs<Test>(*test5) : 0;
+ auto test5__ = test5 ? _fbb.CreateVectorOfStructs<MyGame::Example::Test>(*test5) : 0;
auto vector_of_longs__ = vector_of_longs ? _fbb.CreateVector<int64_t>(*vector_of_longs) : 0;
auto vector_of_doubles__ = vector_of_doubles ? _fbb.CreateVector<double>(*vector_of_doubles) : 0;
- auto vector_of_referrables__ = vector_of_referrables ? _fbb.CreateVector<flatbuffers::Offset<Referrable>>(*vector_of_referrables) : 0;
+ auto vector_of_referrables__ = vector_of_referrables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Referrable>(vector_of_referrables) : 0;
auto vector_of_weak_references__ = vector_of_weak_references ? _fbb.CreateVector<uint64_t>(*vector_of_weak_references) : 0;
- auto vector_of_strong_referrables__ = vector_of_strong_referrables ? _fbb.CreateVector<flatbuffers::Offset<Referrable>>(*vector_of_strong_referrables) : 0;
+ auto vector_of_strong_referrables__ = vector_of_strong_referrables ? _fbb.CreateVectorOfSortedTables<MyGame::Example::Referrable>(vector_of_strong_referrables) : 0;
auto vector_of_co_owning_references__ = vector_of_co_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_co_owning_references) : 0;
auto vector_of_non_owning_references__ = vector_of_non_owning_references ? _fbb.CreateVector<uint64_t>(*vector_of_non_owning_references) : 0;
- auto vector_of_enums__ = vector_of_enums ? _fbb.CreateVector<int8_t>(*vector_of_enums) : 0;
+ auto vector_of_enums__ = vector_of_enums ? _fbb.CreateVector<uint8_t>(*vector_of_enums) : 0;
return MyGame::Example::CreateMonster(
_fbb,
pos,
@@ -2072,7 +2139,8 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(
any_unique,
any_ambiguous_type,
any_ambiguous,
- vector_of_enums__);
+ vector_of_enums__,
+ signed_enum);
}
flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
@@ -2128,6 +2196,7 @@ inline bool operator!=(const TypeAliasesT &lhs, const TypeAliasesT &rhs) {
struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef TypeAliasesT NativeTableType;
+ typedef TypeAliasesBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TypeAliasesTypeTable();
}
@@ -2241,6 +2310,7 @@ struct TypeAliases FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct TypeAliasesBuilder {
+ typedef TypeAliases Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_i8(int8_t i8) {
@@ -2358,9 +2428,9 @@ flatbuffers::Offset<TypeAliases> CreateTypeAliases(flatbuffers::FlatBufferBuilde
} // namespace Example
inline InParentNamespaceT *InParentNamespace::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new InParentNamespaceT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::InParentNamespaceT> _o = flatbuffers::unique_ptr<MyGame::InParentNamespaceT>(new InParentNamespaceT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void InParentNamespace::UnPackTo(InParentNamespaceT *_o, const flatbuffers::resolver_function_t *_resolver) const {
@@ -2383,9 +2453,9 @@ inline flatbuffers::Offset<InParentNamespace> CreateInParentNamespace(flatbuffer
namespace Example2 {
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new MonsterT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::Example2::MonsterT> _o = flatbuffers::unique_ptr<MyGame::Example2::MonsterT>(new MonsterT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
@@ -2410,15 +2480,15 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
namespace Example {
inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new TestSimpleTableWithEnumT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::Example::TestSimpleTableWithEnumT> _o = flatbuffers::unique_ptr<MyGame::Example::TestSimpleTableWithEnumT>(new TestSimpleTableWithEnumT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void TestSimpleTableWithEnum::UnPackTo(TestSimpleTableWithEnumT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = color(); _o->color = _e; };
+ { auto _e = color(); _o->color = _e; }
}
inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -2436,17 +2506,17 @@ inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnu
}
inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new StatT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::Example::StatT> _o = flatbuffers::unique_ptr<MyGame::Example::StatT>(new StatT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void Stat::UnPackTo(StatT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = id(); if (_e) _o->id = _e->str(); };
- { auto _e = val(); _o->val = _e; };
- { auto _e = count(); _o->count = _e; };
+ { auto _e = id(); if (_e) _o->id = _e->str(); }
+ { auto _e = val(); _o->val = _e; }
+ { auto _e = count(); _o->count = _e; }
}
inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -2468,15 +2538,15 @@ inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb
}
inline ReferrableT *Referrable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new ReferrableT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::Example::ReferrableT> _o = flatbuffers::unique_ptr<MyGame::Example::ReferrableT>(new ReferrableT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void Referrable::UnPackTo(ReferrableT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = id(); _o->id = _e; };
+ { auto _e = id(); _o->id = _e; }
}
inline flatbuffers::Offset<Referrable> Referrable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ReferrableT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -2494,68 +2564,69 @@ inline flatbuffers::Offset<Referrable> CreateReferrable(flatbuffers::FlatBufferB
}
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new MonsterT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::Example::MonsterT> _o = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(new MonsterT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = pos(); if (_e) _o->pos = flatbuffers::unique_ptr<Vec3>(new Vec3(*_e)); };
- { auto _e = mana(); _o->mana = _e; };
- { auto _e = hp(); _o->hp = _e; };
- { auto _e = name(); if (_e) _o->name = _e->str(); };
- { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } };
- { auto _e = color(); _o->color = _e; };
- { auto _e = test_type(); _o->test.type = _e; };
- { auto _e = test(); if (_e) _o->test.value = AnyUnion::UnPack(_e, test_type(), _resolver); };
- { auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } };
- { auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } };
- { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = flatbuffers::unique_ptr<MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } };
- { auto _e = enemy(); if (_e) _o->enemy = flatbuffers::unique_ptr<MonsterT>(_e->UnPack(_resolver)); };
- { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer[_i] = _e->Get(_i); } } };
- { auto _e = testempty(); if (_e) _o->testempty = flatbuffers::unique_ptr<StatT>(_e->UnPack(_resolver)); };
- { auto _e = testbool(); _o->testbool = _e; };
- { auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; };
- { auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; };
- { auto _e = testhashs64_fnv1(); _o->testhashs64_fnv1 = _e; };
- { auto _e = testhashu64_fnv1(); _o->testhashu64_fnv1 = _e; };
- { auto _e = testhashs32_fnv1a(); _o->testhashs32_fnv1a = _e; };
+ { auto _e = pos(); if (_e) _o->pos = flatbuffers::unique_ptr<MyGame::Example::Vec3>(new MyGame::Example::Vec3(*_e)); }
+ { auto _e = mana(); _o->mana = _e; }
+ { auto _e = hp(); _o->hp = _e; }
+ { auto _e = name(); if (_e) _o->name = _e->str(); }
+ { auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } }
+ { auto _e = color(); _o->color = _e; }
+ { auto _e = test_type(); _o->test.type = _e; }
+ { auto _e = test(); if (_e) _o->test.value = MyGame::Example::AnyUnion::UnPack(_e, test_type(), _resolver); }
+ { auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } }
+ { auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } }
+ { auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } }
+ { auto _e = enemy(); if (_e) _o->enemy = flatbuffers::unique_ptr<MyGame::Example::MonsterT>(_e->UnPack(_resolver)); }
+ { auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer[_i] = _e->Get(_i); } } }
+ { auto _e = testempty(); if (_e) _o->testempty = flatbuffers::unique_ptr<MyGame::Example::StatT>(_e->UnPack(_resolver)); }
+ { auto _e = testbool(); _o->testbool = _e; }
+ { auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; }
+ { auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; }
+ { auto _e = testhashs64_fnv1(); _o->testhashs64_fnv1 = _e; }
+ { auto _e = testhashu64_fnv1(); _o->testhashu64_fnv1 = _e; }
+ { auto _e = testhashs32_fnv1a(); _o->testhashs32_fnv1a = _e; }
{ auto _e = testhashu32_fnv1a(); //scalar resolver, naked
-if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; };
- { auto _e = testhashs64_fnv1a(); _o->testhashs64_fnv1a = _e; };
- { auto _e = testhashu64_fnv1a(); _o->testhashu64_fnv1a = _e; };
- { auto _e = testarrayofbools(); if (_e) { _o->testarrayofbools.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofbools[_i] = _e->Get(_i) != 0; } } };
- { auto _e = testf(); _o->testf = _e; };
- { auto _e = testf2(); _o->testf2 = _e; };
- { auto _e = testf3(); _o->testf3 = _e; };
- { auto _e = testarrayofstring2(); if (_e) { _o->testarrayofstring2.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2[_i] = _e->Get(_i)->str(); } } };
- { auto _e = testarrayofsortedstruct(); if (_e) { _o->testarrayofsortedstruct.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofsortedstruct[_i] = *_e->Get(_i); } } };
- { auto _e = flex(); if (_e) { _o->flex.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->flex[_i] = _e->Get(_i); } } };
- { auto _e = test5(); if (_e) { _o->test5.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test5[_i] = *_e->Get(_i); } } };
- { auto _e = vector_of_longs(); if (_e) { _o->vector_of_longs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_longs[_i] = _e->Get(_i); } } };
- { auto _e = vector_of_doubles(); if (_e) { _o->vector_of_doubles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_doubles[_i] = _e->Get(_i); } } };
- { auto _e = parent_namespace_test(); if (_e) _o->parent_namespace_test = flatbuffers::unique_ptr<MyGame::InParentNamespaceT>(_e->UnPack(_resolver)); };
- { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_referrables[_i] = flatbuffers::unique_ptr<ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } };
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; }
+ { auto _e = testhashs64_fnv1a(); _o->testhashs64_fnv1a = _e; }
+ { auto _e = testhashu64_fnv1a(); _o->testhashu64_fnv1a = _e; }
+ { auto _e = testarrayofbools(); if (_e) { _o->testarrayofbools.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofbools[_i] = _e->Get(_i) != 0; } } }
+ { auto _e = testf(); _o->testf = _e; }
+ { auto _e = testf2(); _o->testf2 = _e; }
+ { auto _e = testf3(); _o->testf3 = _e; }
+ { auto _e = testarrayofstring2(); if (_e) { _o->testarrayofstring2.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2[_i] = _e->Get(_i)->str(); } } }
+ { auto _e = testarrayofsortedstruct(); if (_e) { _o->testarrayofsortedstruct.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofsortedstruct[_i] = *_e->Get(_i); } } }
+ { auto _e = flex(); if (_e) { _o->flex.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->flex[_i] = _e->Get(_i); } } }
+ { auto _e = test5(); if (_e) { _o->test5.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test5[_i] = *_e->Get(_i); } } }
+ { auto _e = vector_of_longs(); if (_e) { _o->vector_of_longs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_longs[_i] = _e->Get(_i); } } }
+ { auto _e = vector_of_doubles(); if (_e) { _o->vector_of_doubles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_doubles[_i] = _e->Get(_i); } } }
+ { auto _e = parent_namespace_test(); if (_e) _o->parent_namespace_test = flatbuffers::unique_ptr<MyGame::InParentNamespaceT>(_e->UnPack(_resolver)); }
+ { auto _e = vector_of_referrables(); if (_e) { _o->vector_of_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_referrables[_i] = flatbuffers::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = single_weak_reference(); //scalar resolver, naked
-if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->single_weak_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->single_weak_reference = nullptr; };
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->single_weak_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->single_weak_reference = nullptr; }
{ auto _e = vector_of_weak_references(); if (_e) { _o->vector_of_weak_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
-if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_weak_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_weak_references[_i] = nullptr; } } };
- { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_strong_referrables[_i] = flatbuffers::unique_ptr<ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } };
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_weak_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_weak_references[_i] = nullptr; } } }
+ { auto _e = vector_of_strong_referrables(); if (_e) { _o->vector_of_strong_referrables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_strong_referrables[_i] = flatbuffers::unique_ptr<MyGame::Example::ReferrableT>(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = co_owning_reference(); //scalar resolver, naked
-if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->co_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->co_owning_reference = nullptr; };
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->co_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->co_owning_reference = nullptr; }
{ auto _e = vector_of_co_owning_references(); if (_e) { _o->vector_of_co_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, default_ptr_type
-if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_co_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i)));/* else do nothing */; } } };
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_co_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i)));/* else do nothing */; } } }
{ auto _e = non_owning_reference(); //scalar resolver, naked
-if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->non_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->non_owning_reference = nullptr; };
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->non_owning_reference), static_cast<flatbuffers::hash_value_t>(_e)); else _o->non_owning_reference = nullptr; }
{ auto _e = vector_of_non_owning_references(); if (_e) { _o->vector_of_non_owning_references.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { //vector resolver, naked
-if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_non_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_non_owning_references[_i] = nullptr; } } };
- { auto _e = any_unique_type(); _o->any_unique.type = _e; };
- { auto _e = any_unique(); if (_e) _o->any_unique.value = AnyUniqueAliasesUnion::UnPack(_e, any_unique_type(), _resolver); };
- { auto _e = any_ambiguous_type(); _o->any_ambiguous.type = _e; };
- { auto _e = any_ambiguous(); if (_e) _o->any_ambiguous.value = AnyAmbiguousAliasesUnion::UnPack(_e, any_ambiguous_type(), _resolver); };
- { auto _e = vector_of_enums(); if (_e) { _o->vector_of_enums.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_enums[_i] = static_cast<Color>(_e->Get(_i)); } } };
+if (_resolver) (*_resolver)(reinterpret_cast<void **>(&_o->vector_of_non_owning_references[_i]), static_cast<flatbuffers::hash_value_t>(_e->Get(_i))); else _o->vector_of_non_owning_references[_i] = nullptr; } } }
+ { auto _e = any_unique_type(); _o->any_unique.type = _e; }
+ { auto _e = any_unique(); if (_e) _o->any_unique.value = MyGame::Example::AnyUniqueAliasesUnion::UnPack(_e, any_unique_type(), _resolver); }
+ { auto _e = any_ambiguous_type(); _o->any_ambiguous.type = _e; }
+ { auto _e = any_ambiguous(); if (_e) _o->any_ambiguous.value = MyGame::Example::AnyAmbiguousAliasesUnion::UnPack(_e, any_ambiguous_type(), _resolver); }
+ { auto _e = vector_of_enums(); if (_e) { _o->vector_of_enums.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vector_of_enums[_i] = static_cast<MyGame::Example::Color>(_e->Get(_i)); } } }
+ { auto _e = signed_enum(); _o->signed_enum = _e; }
}
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -2576,7 +2647,7 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
auto _test = _o->test.Pack(_fbb);
auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0;
auto _testarrayofstring = _o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0;
- auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<Monster>> (_o->testarrayoftables.size(), [](size_t i, _VectorArgs *__va) { return CreateMonster(*__va->__fbb, __va->__o->testarrayoftables[i].get(), __va->__rehasher); }, &_va ) : 0;
+ auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Monster>> (_o->testarrayoftables.size(), [](size_t i, _VectorArgs *__va) { return CreateMonster(*__va->__fbb, __va->__o->testarrayoftables[i].get(), __va->__rehasher); }, &_va ) : 0;
auto _enemy = _o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0;
auto _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
@@ -2600,10 +2671,10 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
auto _vector_of_longs = _o->vector_of_longs.size() ? _fbb.CreateVector(_o->vector_of_longs) : 0;
auto _vector_of_doubles = _o->vector_of_doubles.size() ? _fbb.CreateVector(_o->vector_of_doubles) : 0;
auto _parent_namespace_test = _o->parent_namespace_test ? CreateInParentNamespace(_fbb, _o->parent_namespace_test.get(), _rehasher) : 0;
- auto _vector_of_referrables = _o->vector_of_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<Referrable>> (_o->vector_of_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+ auto _vector_of_referrables = _o->vector_of_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
auto _single_weak_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->single_weak_reference)) : 0;
auto _vector_of_weak_references = _o->vector_of_weak_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_weak_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_weak_references[i])) : 0; }, &_va ) : 0;
- auto _vector_of_strong_referrables = _o->vector_of_strong_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<Referrable>> (_o->vector_of_strong_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_strong_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
+ auto _vector_of_strong_referrables = _o->vector_of_strong_referrables.size() ? _fbb.CreateVector<flatbuffers::Offset<MyGame::Example::Referrable>> (_o->vector_of_strong_referrables.size(), [](size_t i, _VectorArgs *__va) { return CreateReferrable(*__va->__fbb, __va->__o->vector_of_strong_referrables[i].get(), __va->__rehasher); }, &_va ) : 0;
auto _co_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->co_owning_reference)) : 0;
auto _vector_of_co_owning_references = _o->vector_of_co_owning_references.size() ? _fbb.CreateVector<uint64_t>(_o->vector_of_co_owning_references.size(), [](size_t i, _VectorArgs *__va) { return __va->__rehasher ? static_cast<uint64_t>((*__va->__rehasher)(__va->__o->vector_of_co_owning_references[i].get())) : 0; }, &_va ) : 0;
auto _non_owning_reference = _rehasher ? static_cast<uint64_t>((*_rehasher)(_o->non_owning_reference)) : 0;
@@ -2612,7 +2683,8 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
auto _any_unique = _o->any_unique.Pack(_fbb);
auto _any_ambiguous_type = _o->any_ambiguous.type;
auto _any_ambiguous = _o->any_ambiguous.Pack(_fbb);
- auto _vector_of_enums = _o->vector_of_enums.size() ? _fbb.CreateVectorScalarCast<int8_t>(flatbuffers::data(_o->vector_of_enums), _o->vector_of_enums.size()) : 0;
+ auto _vector_of_enums = _o->vector_of_enums.size() ? _fbb.CreateVectorScalarCast<uint8_t>(flatbuffers::data(_o->vector_of_enums), _o->vector_of_enums.size()) : 0;
+ auto _signed_enum = _o->signed_enum;
return MyGame::Example::CreateMonster(
_fbb,
_pos,
@@ -2661,30 +2733,31 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
_any_unique,
_any_ambiguous_type,
_any_ambiguous,
- _vector_of_enums);
+ _vector_of_enums,
+ _signed_enum);
}
inline TypeAliasesT *TypeAliases::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new TypeAliasesT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MyGame::Example::TypeAliasesT> _o = flatbuffers::unique_ptr<MyGame::Example::TypeAliasesT>(new TypeAliasesT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void TypeAliases::UnPackTo(TypeAliasesT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = i8(); _o->i8 = _e; };
- { auto _e = u8(); _o->u8 = _e; };
- { auto _e = i16(); _o->i16 = _e; };
- { auto _e = u16(); _o->u16 = _e; };
- { auto _e = i32(); _o->i32 = _e; };
- { auto _e = u32(); _o->u32 = _e; };
- { auto _e = i64(); _o->i64 = _e; };
- { auto _e = u64(); _o->u64 = _e; };
- { auto _e = f32(); _o->f32 = _e; };
- { auto _e = f64(); _o->f64 = _e; };
- { auto _e = v8(); if (_e) { _o->v8.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->v8[_i] = _e->Get(_i); } } };
- { auto _e = vf64(); if (_e) { _o->vf64.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vf64[_i] = _e->Get(_i); } } };
+ { auto _e = i8(); _o->i8 = _e; }
+ { auto _e = u8(); _o->u8 = _e; }
+ { auto _e = i16(); _o->i16 = _e; }
+ { auto _e = u16(); _o->u16 = _e; }
+ { auto _e = i32(); _o->i32 = _e; }
+ { auto _e = u32(); _o->u32 = _e; }
+ { auto _e = i64(); _o->i64 = _e; }
+ { auto _e = u64(); _o->u64 = _e; }
+ { auto _e = f32(); _o->f32 = _e; }
+ { auto _e = f64(); _o->f64 = _e; }
+ { auto _e = v8(); if (_e) { _o->v8.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->v8[_i] = _e->Get(_i); } } }
+ { auto _e = vf64(); if (_e) { _o->vf64.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vf64[_i] = _e->Get(_i); } } }
}
inline flatbuffers::Offset<TypeAliases> TypeAliases::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TypeAliasesT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -2729,18 +2802,18 @@ inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *obj, Any type
return true;
}
case Any_Monster: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return verifier.VerifyTable(ptr);
}
case Any_TestSimpleTableWithEnum: {
- auto ptr = reinterpret_cast<const TestSimpleTableWithEnum *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
return verifier.VerifyTable(ptr);
}
case Any_MyGame_Example2_Monster: {
auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
return verifier.VerifyTable(ptr);
}
- default: return false;
+ default: return true;
}
}
@@ -2759,11 +2832,11 @@ inline bool VerifyAnyVector(flatbuffers::Verifier &verifier, const flatbuffers::
inline void *AnyUnion::UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver) {
switch (type) {
case Any_Monster: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return ptr->UnPack(resolver);
}
case Any_TestSimpleTableWithEnum: {
- auto ptr = reinterpret_cast<const TestSimpleTableWithEnum *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
return ptr->UnPack(resolver);
}
case Any_MyGame_Example2_Monster: {
@@ -2777,11 +2850,11 @@ inline void *AnyUnion::UnPack(const void *obj, Any type, const flatbuffers::reso
inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
switch (type) {
case Any_Monster: {
- auto ptr = reinterpret_cast<const MonsterT *>(value);
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
return CreateMonster(_fbb, ptr, _rehasher).Union();
}
case Any_TestSimpleTableWithEnum: {
- auto ptr = reinterpret_cast<const TestSimpleTableWithEnumT *>(value);
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
}
case Any_MyGame_Example2_Monster: {
@@ -2792,14 +2865,14 @@ inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &
}
}
-inline AnyUnion::AnyUnion(const AnyUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+inline AnyUnion::AnyUnion(const AnyUnion &u) : type(u.type), value(nullptr) {
switch (type) {
case Any_Monster: {
- FLATBUFFERS_ASSERT(false); // MonsterT not copyable.
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
break;
}
case Any_TestSimpleTableWithEnum: {
- value = new TestSimpleTableWithEnumT(*reinterpret_cast<TestSimpleTableWithEnumT *>(u.value));
+ value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
break;
}
case Any_MyGame_Example2_Monster: {
@@ -2814,12 +2887,12 @@ inline AnyUnion::AnyUnion(const AnyUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type)
inline void AnyUnion::Reset() {
switch (type) {
case Any_Monster: {
- auto ptr = reinterpret_cast<MonsterT *>(value);
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
delete ptr;
break;
}
case Any_TestSimpleTableWithEnum: {
- auto ptr = reinterpret_cast<TestSimpleTableWithEnumT *>(value);
+ auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
delete ptr;
break;
}
@@ -2840,18 +2913,18 @@ inline bool VerifyAnyUniqueAliases(flatbuffers::Verifier &verifier, const void *
return true;
}
case AnyUniqueAliases_M: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return verifier.VerifyTable(ptr);
}
- case AnyUniqueAliases_T: {
- auto ptr = reinterpret_cast<const TestSimpleTableWithEnum *>(obj);
+ case AnyUniqueAliases_TS: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
return verifier.VerifyTable(ptr);
}
case AnyUniqueAliases_M2: {
auto ptr = reinterpret_cast<const MyGame::Example2::Monster *>(obj);
return verifier.VerifyTable(ptr);
}
- default: return false;
+ default: return true;
}
}
@@ -2870,11 +2943,11 @@ inline bool VerifyAnyUniqueAliasesVector(flatbuffers::Verifier &verifier, const
inline void *AnyUniqueAliasesUnion::UnPack(const void *obj, AnyUniqueAliases type, const flatbuffers::resolver_function_t *resolver) {
switch (type) {
case AnyUniqueAliases_M: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return ptr->UnPack(resolver);
}
- case AnyUniqueAliases_T: {
- auto ptr = reinterpret_cast<const TestSimpleTableWithEnum *>(obj);
+ case AnyUniqueAliases_TS: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnum *>(obj);
return ptr->UnPack(resolver);
}
case AnyUniqueAliases_M2: {
@@ -2888,11 +2961,11 @@ inline void *AnyUniqueAliasesUnion::UnPack(const void *obj, AnyUniqueAliases typ
inline flatbuffers::Offset<void> AnyUniqueAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
switch (type) {
case AnyUniqueAliases_M: {
- auto ptr = reinterpret_cast<const MonsterT *>(value);
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
return CreateMonster(_fbb, ptr, _rehasher).Union();
}
- case AnyUniqueAliases_T: {
- auto ptr = reinterpret_cast<const TestSimpleTableWithEnumT *>(value);
+ case AnyUniqueAliases_TS: {
+ auto ptr = reinterpret_cast<const MyGame::Example::TestSimpleTableWithEnumT *>(value);
return CreateTestSimpleTableWithEnum(_fbb, ptr, _rehasher).Union();
}
case AnyUniqueAliases_M2: {
@@ -2903,14 +2976,14 @@ inline flatbuffers::Offset<void> AnyUniqueAliasesUnion::Pack(flatbuffers::FlatBu
}
}
-inline AnyUniqueAliasesUnion::AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+inline AnyUniqueAliasesUnion::AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion &u) : type(u.type), value(nullptr) {
switch (type) {
case AnyUniqueAliases_M: {
- FLATBUFFERS_ASSERT(false); // MonsterT not copyable.
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
break;
}
- case AnyUniqueAliases_T: {
- value = new TestSimpleTableWithEnumT(*reinterpret_cast<TestSimpleTableWithEnumT *>(u.value));
+ case AnyUniqueAliases_TS: {
+ value = new MyGame::Example::TestSimpleTableWithEnumT(*reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(u.value));
break;
}
case AnyUniqueAliases_M2: {
@@ -2925,12 +2998,12 @@ inline AnyUniqueAliasesUnion::AnyUniqueAliasesUnion(const AnyUniqueAliasesUnion
inline void AnyUniqueAliasesUnion::Reset() {
switch (type) {
case AnyUniqueAliases_M: {
- auto ptr = reinterpret_cast<MonsterT *>(value);
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
delete ptr;
break;
}
- case AnyUniqueAliases_T: {
- auto ptr = reinterpret_cast<TestSimpleTableWithEnumT *>(value);
+ case AnyUniqueAliases_TS: {
+ auto ptr = reinterpret_cast<MyGame::Example::TestSimpleTableWithEnumT *>(value);
delete ptr;
break;
}
@@ -2951,18 +3024,18 @@ inline bool VerifyAnyAmbiguousAliases(flatbuffers::Verifier &verifier, const voi
return true;
}
case AnyAmbiguousAliases_M1: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return verifier.VerifyTable(ptr);
}
case AnyAmbiguousAliases_M2: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return verifier.VerifyTable(ptr);
}
case AnyAmbiguousAliases_M3: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return verifier.VerifyTable(ptr);
}
- default: return false;
+ default: return true;
}
}
@@ -2981,15 +3054,15 @@ inline bool VerifyAnyAmbiguousAliasesVector(flatbuffers::Verifier &verifier, con
inline void *AnyAmbiguousAliasesUnion::UnPack(const void *obj, AnyAmbiguousAliases type, const flatbuffers::resolver_function_t *resolver) {
switch (type) {
case AnyAmbiguousAliases_M1: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return ptr->UnPack(resolver);
}
case AnyAmbiguousAliases_M2: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return ptr->UnPack(resolver);
}
case AnyAmbiguousAliases_M3: {
- auto ptr = reinterpret_cast<const Monster *>(obj);
+ auto ptr = reinterpret_cast<const MyGame::Example::Monster *>(obj);
return ptr->UnPack(resolver);
}
default: return nullptr;
@@ -2999,33 +3072,33 @@ inline void *AnyAmbiguousAliasesUnion::UnPack(const void *obj, AnyAmbiguousAlias
inline flatbuffers::Offset<void> AnyAmbiguousAliasesUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
switch (type) {
case AnyAmbiguousAliases_M1: {
- auto ptr = reinterpret_cast<const MonsterT *>(value);
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
return CreateMonster(_fbb, ptr, _rehasher).Union();
}
case AnyAmbiguousAliases_M2: {
- auto ptr = reinterpret_cast<const MonsterT *>(value);
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
return CreateMonster(_fbb, ptr, _rehasher).Union();
}
case AnyAmbiguousAliases_M3: {
- auto ptr = reinterpret_cast<const MonsterT *>(value);
+ auto ptr = reinterpret_cast<const MyGame::Example::MonsterT *>(value);
return CreateMonster(_fbb, ptr, _rehasher).Union();
}
default: return 0;
}
}
-inline AnyAmbiguousAliasesUnion::AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+inline AnyAmbiguousAliasesUnion::AnyAmbiguousAliasesUnion(const AnyAmbiguousAliasesUnion &u) : type(u.type), value(nullptr) {
switch (type) {
case AnyAmbiguousAliases_M1: {
- FLATBUFFERS_ASSERT(false); // MonsterT not copyable.
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
break;
}
case AnyAmbiguousAliases_M2: {
- FLATBUFFERS_ASSERT(false); // MonsterT not copyable.
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
break;
}
case AnyAmbiguousAliases_M3: {
- FLATBUFFERS_ASSERT(false); // MonsterT not copyable.
+ FLATBUFFERS_ASSERT(false); // MyGame::Example::MonsterT not copyable.
break;
}
default:
@@ -3036,17 +3109,17 @@ inline AnyAmbiguousAliasesUnion::AnyAmbiguousAliasesUnion(const AnyAmbiguousAlia
inline void AnyAmbiguousAliasesUnion::Reset() {
switch (type) {
case AnyAmbiguousAliases_M1: {
- auto ptr = reinterpret_cast<MonsterT *>(value);
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
delete ptr;
break;
}
case AnyAmbiguousAliases_M2: {
- auto ptr = reinterpret_cast<MonsterT *>(value);
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
delete ptr;
break;
}
case AnyAmbiguousAliases_M3: {
- auto ptr = reinterpret_cast<MonsterT *>(value);
+ auto ptr = reinterpret_cast<MyGame::Example::MonsterT *>(value);
delete ptr;
break;
}
@@ -3058,12 +3131,12 @@ inline void AnyAmbiguousAliasesUnion::Reset() {
inline const flatbuffers::TypeTable *ColorTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
- { flatbuffers::ET_CHAR, 0, 0 },
- { flatbuffers::ET_CHAR, 0, 0 },
- { flatbuffers::ET_CHAR, 0, 0 }
+ { flatbuffers::ET_UCHAR, 0, 0 },
+ { flatbuffers::ET_UCHAR, 0, 0 },
+ { flatbuffers::ET_UCHAR, 0, 0 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- ColorTypeTable
+ MyGame::Example::ColorTypeTable
};
static const int64_t values[] = { 1, 2, 8 };
static const char * const names[] = {
@@ -3077,6 +3150,29 @@ inline const flatbuffers::TypeTable *ColorTypeTable() {
return &tt;
}
+inline const flatbuffers::TypeTable *RaceTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_CHAR, 0, 0 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ MyGame::Example::RaceTypeTable
+ };
+ static const int64_t values[] = { -1, 0, 1, 2 };
+ static const char * const names[] = {
+ "None",
+ "Human",
+ "Dwarf",
+ "Elf"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_ENUM, 4, type_codes, type_refs, values, names
+ };
+ return &tt;
+}
+
inline const flatbuffers::TypeTable *AnyTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
{ flatbuffers::ET_SEQUENCE, 0, -1 },
@@ -3085,8 +3181,8 @@ inline const flatbuffers::TypeTable *AnyTypeTable() {
{ flatbuffers::ET_SEQUENCE, 0, 2 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- MonsterTypeTable,
- TestSimpleTableWithEnumTypeTable,
+ MyGame::Example::MonsterTypeTable,
+ MyGame::Example::TestSimpleTableWithEnumTypeTable,
MyGame::Example2::MonsterTypeTable
};
static const char * const names[] = {
@@ -3109,14 +3205,14 @@ inline const flatbuffers::TypeTable *AnyUniqueAliasesTypeTable() {
{ flatbuffers::ET_SEQUENCE, 0, 2 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- MonsterTypeTable,
- TestSimpleTableWithEnumTypeTable,
+ MyGame::Example::MonsterTypeTable,
+ MyGame::Example::TestSimpleTableWithEnumTypeTable,
MyGame::Example2::MonsterTypeTable
};
static const char * const names[] = {
"NONE",
"M",
- "T",
+ "TS",
"M2"
};
static const flatbuffers::TypeTable tt = {
@@ -3133,7 +3229,7 @@ inline const flatbuffers::TypeTable *AnyAmbiguousAliasesTypeTable() {
{ flatbuffers::ET_SEQUENCE, 0, 0 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- MonsterTypeTable
+ MyGame::Example::MonsterTypeTable
};
static const char * const names[] = {
"NONE",
@@ -3187,10 +3283,10 @@ inline const flatbuffers::TypeTable *TestTypeTable() {
inline const flatbuffers::TypeTable *TestSimpleTableWithEnumTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
- { flatbuffers::ET_CHAR, 0, 0 }
+ { flatbuffers::ET_UCHAR, 0, 0 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- ColorTypeTable
+ MyGame::Example::ColorTypeTable
};
static const char * const names[] = {
"color"
@@ -3207,12 +3303,12 @@ inline const flatbuffers::TypeTable *Vec3TypeTable() {
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_FLOAT, 0, -1 },
{ flatbuffers::ET_DOUBLE, 0, -1 },
- { flatbuffers::ET_CHAR, 0, 0 },
+ { flatbuffers::ET_UCHAR, 0, 0 },
{ flatbuffers::ET_SEQUENCE, 0, 1 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- ColorTypeTable,
- TestTypeTable
+ MyGame::Example::ColorTypeTable,
+ MyGame::Example::TestTypeTable
};
static const int64_t values[] = { 0, 4, 8, 16, 24, 26, 32 };
static const char * const names[] = {
@@ -3283,7 +3379,7 @@ inline const flatbuffers::TypeTable *MonsterTypeTable() {
{ flatbuffers::ET_STRING, 0, -1 },
{ flatbuffers::ET_BOOL, 0, -1 },
{ flatbuffers::ET_UCHAR, 1, -1 },
- { flatbuffers::ET_CHAR, 0, 1 },
+ { flatbuffers::ET_UCHAR, 0, 1 },
{ flatbuffers::ET_UTYPE, 0, 2 },
{ flatbuffers::ET_SEQUENCE, 0, 2 },
{ flatbuffers::ET_SEQUENCE, 1, 3 },
@@ -3324,20 +3420,22 @@ inline const flatbuffers::TypeTable *MonsterTypeTable() {
{ flatbuffers::ET_SEQUENCE, 0, 9 },
{ flatbuffers::ET_UTYPE, 0, 10 },
{ flatbuffers::ET_SEQUENCE, 0, 10 },
- { flatbuffers::ET_CHAR, 1, 1 }
+ { flatbuffers::ET_UCHAR, 1, 1 },
+ { flatbuffers::ET_CHAR, 0, 11 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- Vec3TypeTable,
- ColorTypeTable,
- AnyTypeTable,
- TestTypeTable,
- MonsterTypeTable,
- StatTypeTable,
- AbilityTypeTable,
+ MyGame::Example::Vec3TypeTable,
+ MyGame::Example::ColorTypeTable,
+ MyGame::Example::AnyTypeTable,
+ MyGame::Example::TestTypeTable,
+ MyGame::Example::MonsterTypeTable,
+ MyGame::Example::StatTypeTable,
+ MyGame::Example::AbilityTypeTable,
MyGame::InParentNamespaceTypeTable,
- ReferrableTypeTable,
- AnyUniqueAliasesTypeTable,
- AnyAmbiguousAliasesTypeTable
+ MyGame::Example::ReferrableTypeTable,
+ MyGame::Example::AnyUniqueAliasesTypeTable,
+ MyGame::Example::AnyAmbiguousAliasesTypeTable,
+ MyGame::Example::RaceTypeTable
};
static const char * const names[] = {
"pos",
@@ -3387,10 +3485,11 @@ inline const flatbuffers::TypeTable *MonsterTypeTable() {
"any_unique",
"any_ambiguous_type",
"any_ambiguous",
- "vector_of_enums"
+ "vector_of_enums",
+ "signed_enum"
};
static const flatbuffers::TypeTable tt = {
- flatbuffers::ST_TABLE, 48, type_codes, type_refs, nullptr, names
+ flatbuffers::ST_TABLE, 49, type_codes, type_refs, nullptr, names
};
return &tt;
}
@@ -3477,10 +3576,16 @@ inline void FinishSizePrefixedMonsterBuffer(
fbb.FinishSizePrefixed(root, MonsterIdentifier());
}
-inline flatbuffers::unique_ptr<MonsterT> UnPackMonster(
+inline flatbuffers::unique_ptr<MyGame::Example::MonsterT> UnPackMonster(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<MyGame::Example::MonsterT>(GetMonster(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<MyGame::Example::MonsterT> UnPackSizePrefixedMonster(
const void *buf,
const flatbuffers::resolver_function_t *res = nullptr) {
- return flatbuffers::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(res));
+ return flatbuffers::unique_ptr<MyGame::Example::MonsterT>(GetSizePrefixedMonster(buf)->UnPack(res));
}
} // namespace Example
diff --git a/tests/monster_test_generated.js b/tests/monster_test_generated.js
index cfa82d1f..bc7db45b 100644
--- a/tests/monster_test_generated.js
+++ b/tests/monster_test_generated.js
@@ -25,21 +25,63 @@ MyGame.Example2 = MyGame.Example2 || {};
MyGame.OtherNameSpace = MyGame.OtherNameSpace || {};
/**
+ * Composite components of Monster color.
+ *
* @enum {number}
*/
MyGame.Example.Color = {
Red: 1,
+
+ /**
+ * \brief color Green
+ * Green is bit_flag with value (1u << 1)
+ */
Green: 2,
+
+ /**
+ * \brief color Blue (1u << 3)
+ */
Blue: 8
};
/**
+ * Composite components of Monster color.
+ *
* @enum {string}
*/
MyGame.Example.ColorName = {
- 1: 'Red',
- 2: 'Green',
- 8: 'Blue'
+ '1': 'Red',
+
+ /**
+ * \brief color Green
+ * Green is bit_flag with value (1u << 1)
+ */
+ '2': 'Green',
+
+ /**
+ * \brief color Blue (1u << 3)
+ */
+ '8': 'Blue'
+};
+
+/**
+ * @enum {number}
+ */
+MyGame.Example.Race = {
+ None: -1,
+ Human: 0,
+ Dwarf: 1,
+ Elf: 2
+};
+
+/**
+ * @enum {string}
+ */
+MyGame.Example.RaceName = {
+ '-1': 'None',
+ '0': 'Human',
+ '1': 'Dwarf',
+ '2': 'Elf'
};
/**
@@ -56,10 +98,10 @@ MyGame.Example.Any = {
* @enum {string}
*/
MyGame.Example.AnyName = {
- 0: 'NONE',
- 1: 'Monster',
- 2: 'TestSimpleTableWithEnum',
- 3: 'MyGame_Example2_Monster'
+ '0': 'NONE',
+ '1': 'Monster',
+ '2': 'TestSimpleTableWithEnum',
+ '3': 'MyGame_Example2_Monster'
};
/**
@@ -68,7 +110,7 @@ MyGame.Example.AnyName = {
MyGame.Example.AnyUniqueAliases = {
NONE: 0,
M: 1,
- T: 2,
+ TS: 2,
M2: 3
};
@@ -76,10 +118,10 @@ MyGame.Example.AnyUniqueAliases = {
* @enum {string}
*/
MyGame.Example.AnyUniqueAliasesName = {
- 0: 'NONE',
- 1: 'M',
- 2: 'T',
- 3: 'M2'
+ '0': 'NONE',
+ '1': 'M',
+ '2': 'TS',
+ '3': 'M2'
};
/**
@@ -96,10 +138,10 @@ MyGame.Example.AnyAmbiguousAliases = {
* @enum {string}
*/
MyGame.Example.AnyAmbiguousAliasesName = {
- 0: 'NONE',
- 1: 'M1',
- 2: 'M2',
- 3: 'M3'
+ '0': 'NONE',
+ '1': 'M1',
+ '2': 'M2',
+ '3': 'M3'
};
/**
@@ -138,6 +180,16 @@ MyGame.InParentNamespace.getRootAsInParentNamespace = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.InParentNamespace=} obj
+ * @returns {MyGame.InParentNamespace}
+ */
+MyGame.InParentNamespace.getSizePrefixedRootAsInParentNamespace = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new MyGame.InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @param {flatbuffers.Builder} builder
*/
MyGame.InParentNamespace.startInParentNamespace = function(builder) {
@@ -198,6 +250,16 @@ MyGame.Example2.Monster.getRootAsMonster = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example2.Monster=} obj
+ * @returns {MyGame.Example2.Monster}
+ */
+MyGame.Example2.Monster.getSizePrefixedRootAsMonster = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new MyGame.Example2.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @param {flatbuffers.Builder} builder
*/
MyGame.Example2.Monster.startMonster = function(builder) {
@@ -342,11 +404,21 @@ MyGame.Example.TestSimpleTableWithEnum.getRootAsTestSimpleTableWithEnum = functi
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TestSimpleTableWithEnum=} obj
+ * @returns {MyGame.Example.TestSimpleTableWithEnum}
+ */
+MyGame.Example.TestSimpleTableWithEnum.getSizePrefixedRootAsTestSimpleTableWithEnum = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new MyGame.Example.TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @returns {MyGame.Example.Color}
*/
MyGame.Example.TestSimpleTableWithEnum.prototype.color = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
- return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readInt8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
+ return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
};
/**
@@ -360,7 +432,7 @@ MyGame.Example.TestSimpleTableWithEnum.prototype.mutate_color = function(value)
return false;
}
- this.bb.writeInt8(this.bb_pos + offset, value);
+ this.bb.writeUint8(this.bb_pos + offset, value);
return true;
};
@@ -517,7 +589,7 @@ MyGame.Example.Vec3.prototype.mutate_test1 = function(value) {
* @returns {MyGame.Example.Color}
*/
MyGame.Example.Vec3.prototype.test2 = function() {
- return /** @type {MyGame.Example.Color} */ (this.bb.readInt8(this.bb_pos + 24));
+ return /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + 24));
};
/**
@@ -531,7 +603,7 @@ MyGame.Example.Vec3.prototype.mutate_test2 = function(value) {
return false;
}
- this.bb.writeInt8(this.bb_pos + offset, value);
+ this.bb.writeUint8(this.bb_pos + offset, value);
return true;
};
@@ -690,6 +762,16 @@ MyGame.Example.Stat.getRootAsStat = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Stat=} obj
+ * @returns {MyGame.Example.Stat}
+ */
+MyGame.Example.Stat.getSizePrefixedRootAsStat = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new MyGame.Example.Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array|null}
*/
@@ -835,6 +917,16 @@ MyGame.Example.Referrable.getRootAsReferrable = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Referrable=} obj
+ * @returns {MyGame.Example.Referrable}
+ */
+MyGame.Example.Referrable.getSizePrefixedRootAsReferrable = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new MyGame.Example.Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @returns {flatbuffers.Long}
*/
MyGame.Example.Referrable.prototype.id = function() {
@@ -893,7 +985,7 @@ MyGame.Example.Referrable.createReferrable = function(builder, id) {
}
/**
- * an example documentation comment: monster object
+ * an example documentation comment: "monster object"
*
* @constructor
*/
@@ -931,6 +1023,16 @@ MyGame.Example.Monster.getRootAsMonster = function(bb, obj) {
/**
* @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.Monster=} obj
+ * @returns {MyGame.Example.Monster}
+ */
+MyGame.Example.Monster.getSizePrefixedRootAsMonster = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new MyGame.Example.Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
* @returns {boolean}
*/
MyGame.Example.Monster.bufferHasIdentifier = function(bb) {
@@ -1031,7 +1133,7 @@ MyGame.Example.Monster.prototype.inventoryArray = function() {
*/
MyGame.Example.Monster.prototype.color = function() {
var offset = this.bb.__offset(this.bb_pos, 16);
- return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readInt8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
+ return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
};
/**
@@ -1045,7 +1147,7 @@ MyGame.Example.Monster.prototype.mutate_color = function(value) {
return false;
}
- this.bb.writeInt8(this.bb_pos + offset, value);
+ this.bb.writeUint8(this.bb_pos + offset, value);
return true;
};
@@ -1058,21 +1160,6 @@ MyGame.Example.Monster.prototype.testType = function() {
};
/**
- * @param {MyGame.Example.Any} value
- * @returns {boolean}
- */
-MyGame.Example.Monster.prototype.mutate_test_type = function(value) {
- var offset = this.bb.__offset(this.bb_pos, 18);
-
- if (offset === 0) {
- return false;
- }
-
- this.bb.writeUint8(this.bb_pos + offset, value);
- return true;
-};
-
-/**
* @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table}
*/
@@ -1777,21 +1864,6 @@ MyGame.Example.Monster.prototype.anyUniqueType = function() {
};
/**
- * @param {MyGame.Example.AnyUniqueAliases} value
- * @returns {boolean}
- */
-MyGame.Example.Monster.prototype.mutate_any_unique_type = function(value) {
- var offset = this.bb.__offset(this.bb_pos, 90);
-
- if (offset === 0) {
- return false;
- }
-
- this.bb.writeUint8(this.bb_pos + offset, value);
- return true;
-};
-
-/**
* @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table}
*/
@@ -1809,21 +1881,6 @@ MyGame.Example.Monster.prototype.anyAmbiguousType = function() {
};
/**
- * @param {MyGame.Example.AnyAmbiguousAliases} value
- * @returns {boolean}
- */
-MyGame.Example.Monster.prototype.mutate_any_ambiguous_type = function(value) {
- var offset = this.bb.__offset(this.bb_pos, 94);
-
- if (offset === 0) {
- return false;
- }
-
- this.bb.writeUint8(this.bb_pos + offset, value);
- return true;
-};
-
-/**
* @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table}
*/
@@ -1838,7 +1895,7 @@ MyGame.Example.Monster.prototype.anyAmbiguous = function(obj) {
*/
MyGame.Example.Monster.prototype.vectorOfEnums = function(index) {
var offset = this.bb.__offset(this.bb_pos, 98);
- return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {MyGame.Example.Color} */ (0);
+ return offset ? /** @type {MyGame.Example.Color} */ (this.bb.readUint8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {MyGame.Example.Color} */ (0);
};
/**
@@ -1850,18 +1907,41 @@ MyGame.Example.Monster.prototype.vectorOfEnumsLength = function() {
};
/**
- * @returns {Int8Array}
+ * @returns {Uint8Array}
*/
MyGame.Example.Monster.prototype.vectorOfEnumsArray = function() {
var offset = this.bb.__offset(this.bb_pos, 98);
- return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+ return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns {MyGame.Example.Race}
+ */
+MyGame.Example.Monster.prototype.signedEnum = function() {
+ var offset = this.bb.__offset(this.bb_pos, 100);
+ return offset ? /** @type {MyGame.Example.Race} */ (this.bb.readInt8(this.bb_pos + offset)) : MyGame.Example.Race.None;
+};
+
+/**
+ * @param {MyGame.Example.Race} value
+ * @returns {boolean}
+ */
+MyGame.Example.Monster.prototype.mutate_signed_enum = function(value) {
+ var offset = this.bb.__offset(this.bb_pos, 100);
+
+ if (offset === 0) {
+ return false;
+ }
+
+ this.bb.writeInt8(this.bb_pos + offset, value);
+ return true;
};
/**
* @param {flatbuffers.Builder} builder
*/
MyGame.Example.Monster.startMonster = function(builder) {
- builder.startObject(48);
+ builder.startObject(49);
};
/**
@@ -2581,6 +2661,14 @@ MyGame.Example.Monster.startVectorOfEnumsVector = function(builder, numElems) {
/**
* @param {flatbuffers.Builder} builder
+ * @param {MyGame.Example.Race} signedEnum
+ */
+MyGame.Example.Monster.addSignedEnum = function(builder, signedEnum) {
+ builder.addFieldInt8(48, signedEnum, MyGame.Example.Race.None);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
MyGame.Example.Monster.endMonster = function(builder) {
@@ -2599,6 +2687,14 @@ MyGame.Example.Monster.finishMonsterBuffer = function(builder, offset) {
/**
* @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+MyGame.Example.Monster.finishSizePrefixedMonsterBuffer = function(builder, offset) {
+ builder.finish(offset, 'MONS', true);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} posOffset
* @param {number} mana
* @param {number} hp
@@ -2646,9 +2742,10 @@ MyGame.Example.Monster.finishMonsterBuffer = function(builder, offset) {
* @param {MyGame.Example.AnyAmbiguousAliases} anyAmbiguousType
* @param {flatbuffers.Offset} anyAmbiguousOffset
* @param {flatbuffers.Offset} vectorOfEnumsOffset
+ * @param {MyGame.Example.Race} signedEnum
* @returns {flatbuffers.Offset}
*/
-MyGame.Example.Monster.createMonster = function(builder, posOffset, mana, hp, nameOffset, inventoryOffset, color, testType, testOffset, test4Offset, testarrayofstringOffset, testarrayoftablesOffset, enemyOffset, testnestedflatbufferOffset, testemptyOffset, testbool, testhashs32Fnv1, testhashu32Fnv1, testhashs64Fnv1, testhashu64Fnv1, testhashs32Fnv1a, testhashu32Fnv1a, testhashs64Fnv1a, testhashu64Fnv1a, testarrayofboolsOffset, testf, testf2, testf3, testarrayofstring2Offset, testarrayofsortedstructOffset, flexOffset, test5Offset, vectorOfLongsOffset, vectorOfDoublesOffset, parentNamespaceTestOffset, vectorOfReferrablesOffset, singleWeakReference, vectorOfWeakReferencesOffset, vectorOfStrongReferrablesOffset, coOwningReference, vectorOfCoOwningReferencesOffset, nonOwningReference, vectorOfNonOwningReferencesOffset, anyUniqueType, anyUniqueOffset, anyAmbiguousType, anyAmbiguousOffset, vectorOfEnumsOffset) {
+MyGame.Example.Monster.createMonster = function(builder, posOffset, mana, hp, nameOffset, inventoryOffset, color, testType, testOffset, test4Offset, testarrayofstringOffset, testarrayoftablesOffset, enemyOffset, testnestedflatbufferOffset, testemptyOffset, testbool, testhashs32Fnv1, testhashu32Fnv1, testhashs64Fnv1, testhashu64Fnv1, testhashs32Fnv1a, testhashu32Fnv1a, testhashs64Fnv1a, testhashu64Fnv1a, testarrayofboolsOffset, testf, testf2, testf3, testarrayofstring2Offset, testarrayofsortedstructOffset, flexOffset, test5Offset, vectorOfLongsOffset, vectorOfDoublesOffset, parentNamespaceTestOffset, vectorOfReferrablesOffset, singleWeakReference, vectorOfWeakReferencesOffset, vectorOfStrongReferrablesOffset, coOwningReference, vectorOfCoOwningReferencesOffset, nonOwningReference, vectorOfNonOwningReferencesOffset, anyUniqueType, anyUniqueOffset, anyAmbiguousType, anyAmbiguousOffset, vectorOfEnumsOffset, signedEnum) {
MyGame.Example.Monster.startMonster(builder);
MyGame.Example.Monster.addPos(builder, posOffset);
MyGame.Example.Monster.addMana(builder, mana);
@@ -2697,6 +2794,7 @@ MyGame.Example.Monster.createMonster = function(builder, posOffset, mana, hp, na
MyGame.Example.Monster.addAnyAmbiguousType(builder, anyAmbiguousType);
MyGame.Example.Monster.addAnyAmbiguous(builder, anyAmbiguousOffset);
MyGame.Example.Monster.addVectorOfEnums(builder, vectorOfEnumsOffset);
+ MyGame.Example.Monster.addSignedEnum(builder, signedEnum);
return MyGame.Example.Monster.endMonster(builder);
}
@@ -2736,6 +2834,16 @@ MyGame.Example.TypeAliases.getRootAsTypeAliases = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {MyGame.Example.TypeAliases=} obj
+ * @returns {MyGame.Example.TypeAliases}
+ */
+MyGame.Example.TypeAliases.getSizePrefixedRootAsTypeAliases = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new MyGame.Example.TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @returns {number}
*/
MyGame.Example.TypeAliases.prototype.i8 = function() {
diff --git a/tests/monster_test_generated.lobster b/tests/monster_test_generated.lobster
index bda8b6a0..d56aef4b 100644
--- a/tests/monster_test_generated.lobster
+++ b/tests/monster_test_generated.lobster
@@ -1,87 +1,102 @@
// automatically generated by the FlatBuffers compiler, do not modify
-
-include "flatbuffers.lobster"
+import flatbuffers
namespace MyGame_Example
-enum +
- Color_Red = 1,
- Color_Green = 2,
+/// Composite components of Monster color.
+enum Color:
+ Color_Red = 1
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
+ Color_Green = 2
+ /// \brief color Blue (1u << 3)
Color_Blue = 8
-enum +
- Any_NONE = 0,
- Any_Monster = 1,
- Any_TestSimpleTableWithEnum = 2,
+enum Race:
+ Race_None = -1
+ Race_Human = 0
+ Race_Dwarf = 1
+ Race_Elf = 2
+
+enum Any:
+ Any_NONE = 0
+ Any_Monster = 1
+ Any_TestSimpleTableWithEnum = 2
Any_MyGame_Example2_Monster = 3
-enum +
- AnyUniqueAliases_NONE = 0,
- AnyUniqueAliases_M = 1,
- AnyUniqueAliases_T = 2,
+enum AnyUniqueAliases:
+ AnyUniqueAliases_NONE = 0
+ AnyUniqueAliases_M = 1
+ AnyUniqueAliases_TS = 2
AnyUniqueAliases_M2 = 3
-enum +
- AnyAmbiguousAliases_NONE = 0,
- AnyAmbiguousAliases_M1 = 1,
- AnyAmbiguousAliases_M2 = 2,
+enum AnyAmbiguousAliases:
+ AnyAmbiguousAliases_NONE = 0
+ AnyAmbiguousAliases_M1 = 1
+ AnyAmbiguousAliases_M2 = 2
AnyAmbiguousAliases_M3 = 3
namespace MyGame
-struct InParentNamespace
+class InParentNamespace
namespace MyGame_Example2
-struct Monster
+class Monster
namespace MyGame_Example
-struct Test
+class Test
-struct TestSimpleTableWithEnum
+class TestSimpleTableWithEnum
-struct Vec3
+class Vec3
-struct Ability
+class Ability
-struct Stat
+class Stat
-struct Referrable
+class Referrable
-struct Monster
+class Monster
-struct TypeAliases
+class TypeAliases
namespace MyGame
-struct InParentNamespace : flatbuffers_handle
+class InParentNamespace : flatbuffers_handle
-def GetRootAsInParentNamespace(buf:string): InParentNamespace { buf, buf.flatbuffers_indirect(0) }
+def GetRootAsInParentNamespace(buf:string): return InParentNamespace { buf, buf.flatbuffers_indirect(0) }
-def InParentNamespaceStart(b_:flatbuffers_builder):
- b_.StartObject(0)
-def InParentNamespaceEnd(b_:flatbuffers_builder):
- b_.EndObject()
+struct InParentNamespaceBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(0)
+ return this
+ def end():
+ return b_.EndObject()
namespace MyGame_Example2
-struct Monster : flatbuffers_handle
+class Monster : flatbuffers_handle
-def GetRootAsMonster(buf:string): Monster { buf, buf.flatbuffers_indirect(0) }
+def GetRootAsMonster(buf:string): return Monster { buf, buf.flatbuffers_indirect(0) }
-def MonsterStart(b_:flatbuffers_builder):
- b_.StartObject(0)
-def MonsterEnd(b_:flatbuffers_builder):
- b_.EndObject()
+struct MonsterBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(0)
+ return this
+ def end():
+ return b_.EndObject()
namespace MyGame_Example
-struct Test : flatbuffers_handle
+class Test : flatbuffers_handle
def a():
- buf_.read_int16_le(pos_ + 0)
+ return buf_.read_int16_le(pos_ + 0)
def b():
- buf_.read_int8_le(pos_ + 2)
+ return buf_.read_int8_le(pos_ + 2)
def CreateTest(b_:flatbuffers_builder, a:int, b:int):
b_.Prep(2, 4)
@@ -90,34 +105,38 @@ def CreateTest(b_:flatbuffers_builder, a:int, b:int):
b_.PrependInt16(a)
return b_.Offset()
-struct TestSimpleTableWithEnum : flatbuffers_handle
+class TestSimpleTableWithEnum : flatbuffers_handle
def color():
- buf_.flatbuffers_field_int8(pos_, 4, 2)
-
-def GetRootAsTestSimpleTableWithEnum(buf:string): TestSimpleTableWithEnum { buf, buf.flatbuffers_indirect(0) }
-
-def TestSimpleTableWithEnumStart(b_:flatbuffers_builder):
- b_.StartObject(1)
-def TestSimpleTableWithEnumAddColor(b_:flatbuffers_builder, color:int):
- b_.PrependInt8Slot(0, color, 2)
-def TestSimpleTableWithEnumEnd(b_:flatbuffers_builder):
- b_.EndObject()
-
-struct Vec3 : flatbuffers_handle
+ return Color(buf_.flatbuffers_field_int8(pos_, 4, 2))
+
+def GetRootAsTestSimpleTableWithEnum(buf:string): return TestSimpleTableWithEnum { buf, buf.flatbuffers_indirect(0) }
+
+struct TestSimpleTableWithEnumBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(1)
+ return this
+ def add_color(color:Color):
+ b_.PrependUint8Slot(0, color, 2)
+ return this
+ def end():
+ return b_.EndObject()
+
+class Vec3 : flatbuffers_handle
def x():
- buf_.read_float32_le(pos_ + 0)
+ return buf_.read_float32_le(pos_ + 0)
def y():
- buf_.read_float32_le(pos_ + 4)
+ return buf_.read_float32_le(pos_ + 4)
def z():
- buf_.read_float32_le(pos_ + 8)
+ return buf_.read_float32_le(pos_ + 8)
def test1():
- buf_.read_float64_le(pos_ + 16)
+ return buf_.read_float64_le(pos_ + 16)
def test2():
- buf_.read_int8_le(pos_ + 24)
+ return Color(buf_.read_int8_le(pos_ + 24))
def test3():
- MyGame_Example_Test{ buf_, pos_ + 26 }
+ return MyGame_Example_Test{ buf_, pos_ + 26 }
-def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float, test1:float, test2:int, test3_a:int, test3_b:int):
+def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float, test1:float, test2:Color, test3_a:int, test3_b:int):
b_.Prep(8, 32)
b_.Pad(2)
b_.Prep(2, 4)
@@ -125,7 +144,7 @@ def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float, test1:float, t
b_.PrependInt8(test3_b)
b_.PrependInt16(test3_a)
b_.Pad(1)
- b_.PrependInt8(test2)
+ b_.PrependUint8(test2)
b_.PrependFloat64(test1)
b_.Pad(4)
b_.PrependFloat32(z)
@@ -133,11 +152,11 @@ def CreateVec3(b_:flatbuffers_builder, x:float, y:float, z:float, test1:float, t
b_.PrependFloat32(x)
return b_.Offset()
-struct Ability : flatbuffers_handle
+class Ability : flatbuffers_handle
def id():
- buf_.read_int32_le(pos_ + 0)
+ return buf_.read_int32_le(pos_ + 0)
def distance():
- buf_.read_int32_le(pos_ + 4)
+ return buf_.read_int32_le(pos_ + 4)
def CreateAbility(b_:flatbuffers_builder, id:int, distance:int):
b_.Prep(4, 8)
@@ -145,458 +164,558 @@ def CreateAbility(b_:flatbuffers_builder, id:int, distance:int):
b_.PrependUint32(id)
return b_.Offset()
-struct Stat : flatbuffers_handle
+class Stat : flatbuffers_handle
def id():
- buf_.flatbuffers_field_string(pos_, 4)
+ return buf_.flatbuffers_field_string(pos_, 4)
def val():
- buf_.flatbuffers_field_int64(pos_, 6, 0)
+ return buf_.flatbuffers_field_int64(pos_, 6, 0)
def count():
- buf_.flatbuffers_field_int16(pos_, 8, 0)
-
-def GetRootAsStat(buf:string): Stat { buf, buf.flatbuffers_indirect(0) }
-
-def StatStart(b_:flatbuffers_builder):
- b_.StartObject(3)
-def StatAddId(b_:flatbuffers_builder, id:int):
- b_.PrependUOffsetTRelativeSlot(0, id, 0)
-def StatAddVal(b_:flatbuffers_builder, val:int):
- b_.PrependInt64Slot(1, val, 0)
-def StatAddCount(b_:flatbuffers_builder, count:int):
- b_.PrependUint16Slot(2, count, 0)
-def StatEnd(b_:flatbuffers_builder):
- b_.EndObject()
-
-struct Referrable : flatbuffers_handle
+ return buf_.flatbuffers_field_int16(pos_, 8, 0)
+
+def GetRootAsStat(buf:string): return Stat { buf, buf.flatbuffers_indirect(0) }
+
+struct StatBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(3)
+ return this
+ def add_id(id:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(0, id)
+ return this
+ def add_val(val:int):
+ b_.PrependInt64Slot(1, val, 0)
+ return this
+ def add_count(count:int):
+ b_.PrependUint16Slot(2, count, 0)
+ return this
+ def end():
+ return b_.EndObject()
+
+class Referrable : flatbuffers_handle
def id():
- buf_.flatbuffers_field_int64(pos_, 4, 0)
-
-def GetRootAsReferrable(buf:string): Referrable { buf, buf.flatbuffers_indirect(0) }
-
-def ReferrableStart(b_:flatbuffers_builder):
- b_.StartObject(1)
-def ReferrableAddId(b_:flatbuffers_builder, id:int):
- b_.PrependUint64Slot(0, id, 0)
-def ReferrableEnd(b_:flatbuffers_builder):
- b_.EndObject()
-
-/// an example documentation comment: monster object
-struct Monster : flatbuffers_handle
+ return buf_.flatbuffers_field_int64(pos_, 4, 0)
+
+def GetRootAsReferrable(buf:string): return Referrable { buf, buf.flatbuffers_indirect(0) }
+
+struct ReferrableBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(1)
+ return this
+ def add_id(id:int):
+ b_.PrependUint64Slot(0, id, 0)
+ return this
+ def end():
+ return b_.EndObject()
+
+/// an example documentation comment: "monster object"
+class Monster : flatbuffers_handle
def pos():
- o := buf_.flatbuffers_field_struct(pos_, 4)
- if o: MyGame_Example_Vec3 { buf_, o } else: nil
+ let o = buf_.flatbuffers_field_struct(pos_, 4)
+ return if o: MyGame_Example_Vec3 { buf_, o } else: nil
def mana():
- buf_.flatbuffers_field_int16(pos_, 6, 150)
+ return buf_.flatbuffers_field_int16(pos_, 6, 150)
def hp():
- buf_.flatbuffers_field_int16(pos_, 8, 100)
+ return buf_.flatbuffers_field_int16(pos_, 8, 100)
def name():
- buf_.flatbuffers_field_string(pos_, 10)
+ return buf_.flatbuffers_field_string(pos_, 10)
def inventory(i:int):
- buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
+ return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 14) + i * 1)
def inventory_length():
- buf_.flatbuffers_field_vector_len(pos_, 14)
+ return buf_.flatbuffers_field_vector_len(pos_, 14)
def color():
- buf_.flatbuffers_field_int8(pos_, 16, 8)
+ return Color(buf_.flatbuffers_field_int8(pos_, 16, 8))
def test_type():
- buf_.flatbuffers_field_int8(pos_, 18, 0)
+ return Any(buf_.flatbuffers_field_int8(pos_, 18, 0))
def test_as_Monster():
- MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+ return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
def test_as_TestSimpleTableWithEnum():
- MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+ return MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 20) }
def test_as_MyGame_Example2_Monster():
- MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
+ return MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 20) }
def test4(i:int):
- MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 22) + i * 4 }
+ return MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 22) + i * 4 }
def test4_length():
- buf_.flatbuffers_field_vector_len(pos_, 22)
+ return buf_.flatbuffers_field_vector_len(pos_, 22)
def testarrayofstring(i:int):
- buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 24) + i * 4)
+ return buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 24) + i * 4)
def testarrayofstring_length():
- buf_.flatbuffers_field_vector_len(pos_, 24)
+ return buf_.flatbuffers_field_vector_len(pos_, 24)
/// an example documentation comment: this will end up in the generated code
/// multiline too
def testarrayoftables(i:int):
- MyGame_Example_Monster { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 26) + i * 4) }
+ return MyGame_Example_Monster { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 26) + i * 4) }
def testarrayoftables_length():
- buf_.flatbuffers_field_vector_len(pos_, 26)
+ return buf_.flatbuffers_field_vector_len(pos_, 26)
def enemy():
- o := buf_.flatbuffers_field_table(pos_, 28)
- if o: MyGame_Example_Monster { buf_, o } else: nil
+ let o = buf_.flatbuffers_field_table(pos_, 28)
+ return if o: MyGame_Example_Monster { buf_, o } else: nil
def testnestedflatbuffer(i:int):
- buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 30) + i * 1)
+ return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 30) + i * 1)
def testnestedflatbuffer_length():
- buf_.flatbuffers_field_vector_len(pos_, 30)
+ return buf_.flatbuffers_field_vector_len(pos_, 30)
def testempty():
- o := buf_.flatbuffers_field_table(pos_, 32)
- if o: MyGame_Example_Stat { buf_, o } else: nil
+ let o = buf_.flatbuffers_field_table(pos_, 32)
+ return if o: MyGame_Example_Stat { buf_, o } else: nil
def testbool():
- buf_.flatbuffers_field_int8(pos_, 34, 0)
+ return buf_.flatbuffers_field_int8(pos_, 34, 0)
def testhashs32_fnv1():
- buf_.flatbuffers_field_int32(pos_, 36, 0)
+ return buf_.flatbuffers_field_int32(pos_, 36, 0)
def testhashu32_fnv1():
- buf_.flatbuffers_field_int32(pos_, 38, 0)
+ return buf_.flatbuffers_field_int32(pos_, 38, 0)
def testhashs64_fnv1():
- buf_.flatbuffers_field_int64(pos_, 40, 0)
+ return buf_.flatbuffers_field_int64(pos_, 40, 0)
def testhashu64_fnv1():
- buf_.flatbuffers_field_int64(pos_, 42, 0)
+ return buf_.flatbuffers_field_int64(pos_, 42, 0)
def testhashs32_fnv1a():
- buf_.flatbuffers_field_int32(pos_, 44, 0)
+ return buf_.flatbuffers_field_int32(pos_, 44, 0)
def testhashu32_fnv1a():
- buf_.flatbuffers_field_int32(pos_, 46, 0)
+ return buf_.flatbuffers_field_int32(pos_, 46, 0)
def testhashs64_fnv1a():
- buf_.flatbuffers_field_int64(pos_, 48, 0)
+ return buf_.flatbuffers_field_int64(pos_, 48, 0)
def testhashu64_fnv1a():
- buf_.flatbuffers_field_int64(pos_, 50, 0)
+ return buf_.flatbuffers_field_int64(pos_, 50, 0)
def testarrayofbools(i:int):
- buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 52) + i * 1)
+ return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 52) + i * 1)
def testarrayofbools_length():
- buf_.flatbuffers_field_vector_len(pos_, 52)
+ return buf_.flatbuffers_field_vector_len(pos_, 52)
def testf():
- buf_.flatbuffers_field_float32(pos_, 54, 3.14159)
+ return buf_.flatbuffers_field_float32(pos_, 54, 3.14159)
def testf2():
- buf_.flatbuffers_field_float32(pos_, 56, 3.0)
+ return buf_.flatbuffers_field_float32(pos_, 56, 3.0)
def testf3():
- buf_.flatbuffers_field_float32(pos_, 58, 0.0)
+ return buf_.flatbuffers_field_float32(pos_, 58, 0.0)
def testarrayofstring2(i:int):
- buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 60) + i * 4)
+ return buf_.flatbuffers_string(buf_.flatbuffers_field_vector(pos_, 60) + i * 4)
def testarrayofstring2_length():
- buf_.flatbuffers_field_vector_len(pos_, 60)
+ return buf_.flatbuffers_field_vector_len(pos_, 60)
def testarrayofsortedstruct(i:int):
- MyGame_Example_Ability { buf_, buf_.flatbuffers_field_vector(pos_, 62) + i * 8 }
+ return MyGame_Example_Ability { buf_, buf_.flatbuffers_field_vector(pos_, 62) + i * 8 }
def testarrayofsortedstruct_length():
- buf_.flatbuffers_field_vector_len(pos_, 62)
+ return buf_.flatbuffers_field_vector_len(pos_, 62)
def flex(i:int):
- buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 64) + i * 1)
+ return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 64) + i * 1)
def flex_length():
- buf_.flatbuffers_field_vector_len(pos_, 64)
+ return buf_.flatbuffers_field_vector_len(pos_, 64)
def test5(i:int):
- MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 66) + i * 4 }
+ return MyGame_Example_Test { buf_, buf_.flatbuffers_field_vector(pos_, 66) + i * 4 }
def test5_length():
- buf_.flatbuffers_field_vector_len(pos_, 66)
+ return buf_.flatbuffers_field_vector_len(pos_, 66)
def vector_of_longs(i:int):
- buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 68) + i * 8)
+ return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 68) + i * 8)
def vector_of_longs_length():
- buf_.flatbuffers_field_vector_len(pos_, 68)
+ return buf_.flatbuffers_field_vector_len(pos_, 68)
def vector_of_doubles(i:int):
- buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 70) + i * 8)
+ return buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 70) + i * 8)
def vector_of_doubles_length():
- buf_.flatbuffers_field_vector_len(pos_, 70)
+ return buf_.flatbuffers_field_vector_len(pos_, 70)
def parent_namespace_test():
- o := buf_.flatbuffers_field_table(pos_, 72)
- if o: MyGame_InParentNamespace { buf_, o } else: nil
+ let o = buf_.flatbuffers_field_table(pos_, 72)
+ return if o: MyGame_InParentNamespace { buf_, o } else: nil
def vector_of_referrables(i:int):
- MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 74) + i * 4) }
+ return MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 74) + i * 4) }
def vector_of_referrables_length():
- buf_.flatbuffers_field_vector_len(pos_, 74)
+ return buf_.flatbuffers_field_vector_len(pos_, 74)
def single_weak_reference():
- buf_.flatbuffers_field_int64(pos_, 76, 0)
+ return buf_.flatbuffers_field_int64(pos_, 76, 0)
def vector_of_weak_references(i:int):
- buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 78) + i * 8)
+ return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 78) + i * 8)
def vector_of_weak_references_length():
- buf_.flatbuffers_field_vector_len(pos_, 78)
+ return buf_.flatbuffers_field_vector_len(pos_, 78)
def vector_of_strong_referrables(i:int):
- MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 80) + i * 4) }
+ return MyGame_Example_Referrable { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 80) + i * 4) }
def vector_of_strong_referrables_length():
- buf_.flatbuffers_field_vector_len(pos_, 80)
+ return buf_.flatbuffers_field_vector_len(pos_, 80)
def co_owning_reference():
- buf_.flatbuffers_field_int64(pos_, 82, 0)
+ return buf_.flatbuffers_field_int64(pos_, 82, 0)
def vector_of_co_owning_references(i:int):
- buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 84) + i * 8)
+ return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 84) + i * 8)
def vector_of_co_owning_references_length():
- buf_.flatbuffers_field_vector_len(pos_, 84)
+ return buf_.flatbuffers_field_vector_len(pos_, 84)
def non_owning_reference():
- buf_.flatbuffers_field_int64(pos_, 86, 0)
+ return buf_.flatbuffers_field_int64(pos_, 86, 0)
def vector_of_non_owning_references(i:int):
- buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 88) + i * 8)
+ return buf_.read_int64_le(buf_.flatbuffers_field_vector(pos_, 88) + i * 8)
def vector_of_non_owning_references_length():
- buf_.flatbuffers_field_vector_len(pos_, 88)
+ return buf_.flatbuffers_field_vector_len(pos_, 88)
def any_unique_type():
- buf_.flatbuffers_field_int8(pos_, 90, 0)
+ return AnyUniqueAliases(buf_.flatbuffers_field_int8(pos_, 90, 0))
def any_unique_as_M():
- MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 92) }
- def any_unique_as_T():
- MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+ return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+ def any_unique_as_TS():
+ return MyGame_Example_TestSimpleTableWithEnum { buf_, buf_.flatbuffers_field_table(pos_, 92) }
def any_unique_as_M2():
- MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 92) }
+ return MyGame_Example2_Monster { buf_, buf_.flatbuffers_field_table(pos_, 92) }
def any_ambiguous_type():
- buf_.flatbuffers_field_int8(pos_, 94, 0)
+ return AnyAmbiguousAliases(buf_.flatbuffers_field_int8(pos_, 94, 0))
def any_ambiguous_as_M1():
- MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+ return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
def any_ambiguous_as_M2():
- MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+ return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
def any_ambiguous_as_M3():
- MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
+ return MyGame_Example_Monster { buf_, buf_.flatbuffers_field_table(pos_, 96) }
def vector_of_enums(i:int):
- buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 98) + i * 1)
+ return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 98) + i * 1)
def vector_of_enums_length():
- buf_.flatbuffers_field_vector_len(pos_, 98)
-
-def GetRootAsMonster(buf:string): Monster { buf, buf.flatbuffers_indirect(0) }
-
-def MonsterStart(b_:flatbuffers_builder):
- b_.StartObject(48)
-def MonsterAddPos(b_:flatbuffers_builder, pos:int):
- b_.PrependStructSlot(0, pos, 0)
-def MonsterAddMana(b_:flatbuffers_builder, mana:int):
- b_.PrependInt16Slot(1, mana, 150)
-def MonsterAddHp(b_:flatbuffers_builder, hp:int):
- b_.PrependInt16Slot(2, hp, 100)
-def MonsterAddName(b_:flatbuffers_builder, name:int):
- b_.PrependUOffsetTRelativeSlot(3, name, 0)
-def MonsterAddInventory(b_:flatbuffers_builder, inventory:int):
- b_.PrependUOffsetTRelativeSlot(5, inventory, 0)
+ return buf_.flatbuffers_field_vector_len(pos_, 98)
+ def signed_enum():
+ return Race(buf_.flatbuffers_field_int8(pos_, 100, -1))
+
+def GetRootAsMonster(buf:string): return Monster { buf, buf.flatbuffers_indirect(0) }
+
+struct MonsterBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(49)
+ return this
+ def add_pos(pos:flatbuffers_offset):
+ b_.PrependStructSlot(0, pos)
+ return this
+ def add_mana(mana:int):
+ b_.PrependInt16Slot(1, mana, 150)
+ return this
+ def add_hp(hp:int):
+ b_.PrependInt16Slot(2, hp, 100)
+ return this
+ def add_name(name:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(3, name)
+ return this
+ def add_inventory(inventory:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(5, inventory)
+ return this
+ def add_color(color:Color):
+ b_.PrependUint8Slot(6, color, 8)
+ return this
+ def add_test_type(test_type:Any):
+ b_.PrependUint8Slot(7, test_type, 0)
+ return this
+ def add_test(test:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(8, test)
+ return this
+ def add_test4(test4:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(9, test4)
+ return this
+ def add_testarrayofstring(testarrayofstring:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(10, testarrayofstring)
+ return this
+ def add_testarrayoftables(testarrayoftables:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(11, testarrayoftables)
+ return this
+ def add_enemy(enemy:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(12, enemy)
+ return this
+ def add_testnestedflatbuffer(testnestedflatbuffer:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(13, testnestedflatbuffer)
+ return this
+ def add_testempty(testempty:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(14, testempty)
+ return this
+ def add_testbool(testbool:int):
+ b_.PrependBoolSlot(15, testbool, 0)
+ return this
+ def add_testhashs32_fnv1(testhashs32_fnv1:int):
+ b_.PrependInt32Slot(16, testhashs32_fnv1, 0)
+ return this
+ def add_testhashu32_fnv1(testhashu32_fnv1:int):
+ b_.PrependUint32Slot(17, testhashu32_fnv1, 0)
+ return this
+ def add_testhashs64_fnv1(testhashs64_fnv1:int):
+ b_.PrependInt64Slot(18, testhashs64_fnv1, 0)
+ return this
+ def add_testhashu64_fnv1(testhashu64_fnv1:int):
+ b_.PrependUint64Slot(19, testhashu64_fnv1, 0)
+ return this
+ def add_testhashs32_fnv1a(testhashs32_fnv1a:int):
+ b_.PrependInt32Slot(20, testhashs32_fnv1a, 0)
+ return this
+ def add_testhashu32_fnv1a(testhashu32_fnv1a:int):
+ b_.PrependUint32Slot(21, testhashu32_fnv1a, 0)
+ return this
+ def add_testhashs64_fnv1a(testhashs64_fnv1a:int):
+ b_.PrependInt64Slot(22, testhashs64_fnv1a, 0)
+ return this
+ def add_testhashu64_fnv1a(testhashu64_fnv1a:int):
+ b_.PrependUint64Slot(23, testhashu64_fnv1a, 0)
+ return this
+ def add_testarrayofbools(testarrayofbools:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(24, testarrayofbools)
+ return this
+ def add_testf(testf:float):
+ b_.PrependFloat32Slot(25, testf, 3.14159)
+ return this
+ def add_testf2(testf2:float):
+ b_.PrependFloat32Slot(26, testf2, 3.0)
+ return this
+ def add_testf3(testf3:float):
+ b_.PrependFloat32Slot(27, testf3, 0.0)
+ return this
+ def add_testarrayofstring2(testarrayofstring2:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(28, testarrayofstring2)
+ return this
+ def add_testarrayofsortedstruct(testarrayofsortedstruct:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(29, testarrayofsortedstruct)
+ return this
+ def add_flex(flex:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(30, flex)
+ return this
+ def add_test5(test5:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(31, test5)
+ return this
+ def add_vector_of_longs(vector_of_longs:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(32, vector_of_longs)
+ return this
+ def add_vector_of_doubles(vector_of_doubles:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(33, vector_of_doubles)
+ return this
+ def add_parent_namespace_test(parent_namespace_test:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(34, parent_namespace_test)
+ return this
+ def add_vector_of_referrables(vector_of_referrables:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(35, vector_of_referrables)
+ return this
+ def add_single_weak_reference(single_weak_reference:int):
+ b_.PrependUint64Slot(36, single_weak_reference, 0)
+ return this
+ def add_vector_of_weak_references(vector_of_weak_references:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(37, vector_of_weak_references)
+ return this
+ def add_vector_of_strong_referrables(vector_of_strong_referrables:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(38, vector_of_strong_referrables)
+ return this
+ def add_co_owning_reference(co_owning_reference:int):
+ b_.PrependUint64Slot(39, co_owning_reference, 0)
+ return this
+ def add_vector_of_co_owning_references(vector_of_co_owning_references:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(40, vector_of_co_owning_references)
+ return this
+ def add_non_owning_reference(non_owning_reference:int):
+ b_.PrependUint64Slot(41, non_owning_reference, 0)
+ return this
+ def add_vector_of_non_owning_references(vector_of_non_owning_references:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(42, vector_of_non_owning_references)
+ return this
+ def add_any_unique_type(any_unique_type:AnyUniqueAliases):
+ b_.PrependUint8Slot(43, any_unique_type, 0)
+ return this
+ def add_any_unique(any_unique:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(44, any_unique)
+ return this
+ def add_any_ambiguous_type(any_ambiguous_type:AnyAmbiguousAliases):
+ b_.PrependUint8Slot(45, any_ambiguous_type, 0)
+ return this
+ def add_any_ambiguous(any_ambiguous:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(46, any_ambiguous)
+ return this
+ def add_vector_of_enums(vector_of_enums:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(47, vector_of_enums)
+ return this
+ def add_signed_enum(signed_enum:Race):
+ b_.PrependInt8Slot(48, signed_enum, -1)
+ return this
+ def end():
+ return b_.EndObject()
+
def MonsterStartInventoryVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(1, n_, 1)
def MonsterCreateInventoryVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(1, v_.length, 1)
reverse(v_) e_: b_.PrependUint8(e_)
- b_.EndVector(v_.length)
-def MonsterAddColor(b_:flatbuffers_builder, color:int):
- b_.PrependInt8Slot(6, color, 8)
-def MonsterAddTestType(b_:flatbuffers_builder, test_type:int):
- b_.PrependUint8Slot(7, test_type, 0)
-def MonsterAddTest(b_:flatbuffers_builder, test:int):
- b_.PrependUOffsetTRelativeSlot(8, test, 0)
-def MonsterAddTest4(b_:flatbuffers_builder, test4:int):
- b_.PrependUOffsetTRelativeSlot(9, test4, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartTest4Vector(b_:flatbuffers_builder, n_:int):
b_.StartVector(4, n_, 2)
-def MonsterAddTestarrayofstring(b_:flatbuffers_builder, testarrayofstring:int):
- b_.PrependUOffsetTRelativeSlot(10, testarrayofstring, 0)
+
def MonsterStartTestarrayofstringVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(4, n_, 4)
-def MonsterCreateTestarrayofstringVector(b_:flatbuffers_builder, v_:[int]):
+def MonsterCreateTestarrayofstringVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
b_.StartVector(4, v_.length, 4)
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
- b_.EndVector(v_.length)
-def MonsterAddTestarrayoftables(b_:flatbuffers_builder, testarrayoftables:int):
- b_.PrependUOffsetTRelativeSlot(11, testarrayoftables, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartTestarrayoftablesVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(4, n_, 4)
-def MonsterCreateTestarrayoftablesVector(b_:flatbuffers_builder, v_:[int]):
+def MonsterCreateTestarrayoftablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
b_.StartVector(4, v_.length, 4)
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
- b_.EndVector(v_.length)
-def MonsterAddEnemy(b_:flatbuffers_builder, enemy:int):
- b_.PrependUOffsetTRelativeSlot(12, enemy, 0)
-def MonsterAddTestnestedflatbuffer(b_:flatbuffers_builder, testnestedflatbuffer:int):
- b_.PrependUOffsetTRelativeSlot(13, testnestedflatbuffer, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartTestnestedflatbufferVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(1, n_, 1)
def MonsterCreateTestnestedflatbufferVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(1, v_.length, 1)
reverse(v_) e_: b_.PrependUint8(e_)
- b_.EndVector(v_.length)
-def MonsterAddTestempty(b_:flatbuffers_builder, testempty:int):
- b_.PrependUOffsetTRelativeSlot(14, testempty, 0)
-def MonsterAddTestbool(b_:flatbuffers_builder, testbool:int):
- b_.PrependBoolSlot(15, testbool, 0)
-def MonsterAddTesthashs32Fnv1(b_:flatbuffers_builder, testhashs32_fnv1:int):
- b_.PrependInt32Slot(16, testhashs32_fnv1, 0)
-def MonsterAddTesthashu32Fnv1(b_:flatbuffers_builder, testhashu32_fnv1:int):
- b_.PrependUint32Slot(17, testhashu32_fnv1, 0)
-def MonsterAddTesthashs64Fnv1(b_:flatbuffers_builder, testhashs64_fnv1:int):
- b_.PrependInt64Slot(18, testhashs64_fnv1, 0)
-def MonsterAddTesthashu64Fnv1(b_:flatbuffers_builder, testhashu64_fnv1:int):
- b_.PrependUint64Slot(19, testhashu64_fnv1, 0)
-def MonsterAddTesthashs32Fnv1a(b_:flatbuffers_builder, testhashs32_fnv1a:int):
- b_.PrependInt32Slot(20, testhashs32_fnv1a, 0)
-def MonsterAddTesthashu32Fnv1a(b_:flatbuffers_builder, testhashu32_fnv1a:int):
- b_.PrependUint32Slot(21, testhashu32_fnv1a, 0)
-def MonsterAddTesthashs64Fnv1a(b_:flatbuffers_builder, testhashs64_fnv1a:int):
- b_.PrependInt64Slot(22, testhashs64_fnv1a, 0)
-def MonsterAddTesthashu64Fnv1a(b_:flatbuffers_builder, testhashu64_fnv1a:int):
- b_.PrependUint64Slot(23, testhashu64_fnv1a, 0)
-def MonsterAddTestarrayofbools(b_:flatbuffers_builder, testarrayofbools:int):
- b_.PrependUOffsetTRelativeSlot(24, testarrayofbools, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartTestarrayofboolsVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(1, n_, 1)
def MonsterCreateTestarrayofboolsVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(1, v_.length, 1)
reverse(v_) e_: b_.PrependBool(e_)
- b_.EndVector(v_.length)
-def MonsterAddTestf(b_:flatbuffers_builder, testf:float):
- b_.PrependFloat32Slot(25, testf, 3.14159)
-def MonsterAddTestf2(b_:flatbuffers_builder, testf2:float):
- b_.PrependFloat32Slot(26, testf2, 3.0)
-def MonsterAddTestf3(b_:flatbuffers_builder, testf3:float):
- b_.PrependFloat32Slot(27, testf3, 0.0)
-def MonsterAddTestarrayofstring2(b_:flatbuffers_builder, testarrayofstring2:int):
- b_.PrependUOffsetTRelativeSlot(28, testarrayofstring2, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartTestarrayofstring2Vector(b_:flatbuffers_builder, n_:int):
b_.StartVector(4, n_, 4)
-def MonsterCreateTestarrayofstring2Vector(b_:flatbuffers_builder, v_:[int]):
+def MonsterCreateTestarrayofstring2Vector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
b_.StartVector(4, v_.length, 4)
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
- b_.EndVector(v_.length)
-def MonsterAddTestarrayofsortedstruct(b_:flatbuffers_builder, testarrayofsortedstruct:int):
- b_.PrependUOffsetTRelativeSlot(29, testarrayofsortedstruct, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartTestarrayofsortedstructVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(8, n_, 4)
-def MonsterAddFlex(b_:flatbuffers_builder, flex:int):
- b_.PrependUOffsetTRelativeSlot(30, flex, 0)
+
def MonsterStartFlexVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(1, n_, 1)
def MonsterCreateFlexVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(1, v_.length, 1)
reverse(v_) e_: b_.PrependUint8(e_)
- b_.EndVector(v_.length)
-def MonsterAddTest5(b_:flatbuffers_builder, test5:int):
- b_.PrependUOffsetTRelativeSlot(31, test5, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartTest5Vector(b_:flatbuffers_builder, n_:int):
b_.StartVector(4, n_, 2)
-def MonsterAddVectorOfLongs(b_:flatbuffers_builder, vector_of_longs:int):
- b_.PrependUOffsetTRelativeSlot(32, vector_of_longs, 0)
+
def MonsterStartVectorOfLongsVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(8, n_, 8)
def MonsterCreateVectorOfLongsVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(8, v_.length, 8)
reverse(v_) e_: b_.PrependInt64(e_)
- b_.EndVector(v_.length)
-def MonsterAddVectorOfDoubles(b_:flatbuffers_builder, vector_of_doubles:int):
- b_.PrependUOffsetTRelativeSlot(33, vector_of_doubles, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartVectorOfDoublesVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(8, n_, 8)
def MonsterCreateVectorOfDoublesVector(b_:flatbuffers_builder, v_:[float]):
b_.StartVector(8, v_.length, 8)
reverse(v_) e_: b_.PrependFloat64(e_)
- b_.EndVector(v_.length)
-def MonsterAddParentNamespaceTest(b_:flatbuffers_builder, parent_namespace_test:int):
- b_.PrependUOffsetTRelativeSlot(34, parent_namespace_test, 0)
-def MonsterAddVectorOfReferrables(b_:flatbuffers_builder, vector_of_referrables:int):
- b_.PrependUOffsetTRelativeSlot(35, vector_of_referrables, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartVectorOfReferrablesVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(4, n_, 4)
-def MonsterCreateVectorOfReferrablesVector(b_:flatbuffers_builder, v_:[int]):
+def MonsterCreateVectorOfReferrablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
b_.StartVector(4, v_.length, 4)
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
- b_.EndVector(v_.length)
-def MonsterAddSingleWeakReference(b_:flatbuffers_builder, single_weak_reference:int):
- b_.PrependUint64Slot(36, single_weak_reference, 0)
-def MonsterAddVectorOfWeakReferences(b_:flatbuffers_builder, vector_of_weak_references:int):
- b_.PrependUOffsetTRelativeSlot(37, vector_of_weak_references, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartVectorOfWeakReferencesVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(8, n_, 8)
def MonsterCreateVectorOfWeakReferencesVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(8, v_.length, 8)
reverse(v_) e_: b_.PrependUint64(e_)
- b_.EndVector(v_.length)
-def MonsterAddVectorOfStrongReferrables(b_:flatbuffers_builder, vector_of_strong_referrables:int):
- b_.PrependUOffsetTRelativeSlot(38, vector_of_strong_referrables, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartVectorOfStrongReferrablesVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(4, n_, 4)
-def MonsterCreateVectorOfStrongReferrablesVector(b_:flatbuffers_builder, v_:[int]):
+def MonsterCreateVectorOfStrongReferrablesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
b_.StartVector(4, v_.length, 4)
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
- b_.EndVector(v_.length)
-def MonsterAddCoOwningReference(b_:flatbuffers_builder, co_owning_reference:int):
- b_.PrependUint64Slot(39, co_owning_reference, 0)
-def MonsterAddVectorOfCoOwningReferences(b_:flatbuffers_builder, vector_of_co_owning_references:int):
- b_.PrependUOffsetTRelativeSlot(40, vector_of_co_owning_references, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartVectorOfCoOwningReferencesVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(8, n_, 8)
def MonsterCreateVectorOfCoOwningReferencesVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(8, v_.length, 8)
reverse(v_) e_: b_.PrependUint64(e_)
- b_.EndVector(v_.length)
-def MonsterAddNonOwningReference(b_:flatbuffers_builder, non_owning_reference:int):
- b_.PrependUint64Slot(41, non_owning_reference, 0)
-def MonsterAddVectorOfNonOwningReferences(b_:flatbuffers_builder, vector_of_non_owning_references:int):
- b_.PrependUOffsetTRelativeSlot(42, vector_of_non_owning_references, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartVectorOfNonOwningReferencesVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(8, n_, 8)
def MonsterCreateVectorOfNonOwningReferencesVector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(8, v_.length, 8)
reverse(v_) e_: b_.PrependUint64(e_)
- b_.EndVector(v_.length)
-def MonsterAddAnyUniqueType(b_:flatbuffers_builder, any_unique_type:int):
- b_.PrependUint8Slot(43, any_unique_type, 0)
-def MonsterAddAnyUnique(b_:flatbuffers_builder, any_unique:int):
- b_.PrependUOffsetTRelativeSlot(44, any_unique, 0)
-def MonsterAddAnyAmbiguousType(b_:flatbuffers_builder, any_ambiguous_type:int):
- b_.PrependUint8Slot(45, any_ambiguous_type, 0)
-def MonsterAddAnyAmbiguous(b_:flatbuffers_builder, any_ambiguous:int):
- b_.PrependUOffsetTRelativeSlot(46, any_ambiguous, 0)
-def MonsterAddVectorOfEnums(b_:flatbuffers_builder, vector_of_enums:int):
- b_.PrependUOffsetTRelativeSlot(47, vector_of_enums, 0)
+ return b_.EndVector(v_.length)
+
def MonsterStartVectorOfEnumsVector(b_:flatbuffers_builder, n_:int):
b_.StartVector(1, n_, 1)
-def MonsterCreateVectorOfEnumsVector(b_:flatbuffers_builder, v_:[int]):
+def MonsterCreateVectorOfEnumsVector(b_:flatbuffers_builder, v_:[Color]):
b_.StartVector(1, v_.length, 1)
- reverse(v_) e_: b_.PrependInt8(e_)
- b_.EndVector(v_.length)
-def MonsterEnd(b_:flatbuffers_builder):
- b_.EndObject()
+ reverse(v_) e_: b_.PrependUint8(e_)
+ return b_.EndVector(v_.length)
-struct TypeAliases : flatbuffers_handle
+class TypeAliases : flatbuffers_handle
def i8():
- buf_.flatbuffers_field_int8(pos_, 4, 0)
+ return buf_.flatbuffers_field_int8(pos_, 4, 0)
def u8():
- buf_.flatbuffers_field_int8(pos_, 6, 0)
+ return buf_.flatbuffers_field_int8(pos_, 6, 0)
def i16():
- buf_.flatbuffers_field_int16(pos_, 8, 0)
+ return buf_.flatbuffers_field_int16(pos_, 8, 0)
def u16():
- buf_.flatbuffers_field_int16(pos_, 10, 0)
+ return buf_.flatbuffers_field_int16(pos_, 10, 0)
def i32():
- buf_.flatbuffers_field_int32(pos_, 12, 0)
+ return buf_.flatbuffers_field_int32(pos_, 12, 0)
def u32():
- buf_.flatbuffers_field_int32(pos_, 14, 0)
+ return buf_.flatbuffers_field_int32(pos_, 14, 0)
def i64():
- buf_.flatbuffers_field_int64(pos_, 16, 0)
+ return buf_.flatbuffers_field_int64(pos_, 16, 0)
def u64():
- buf_.flatbuffers_field_int64(pos_, 18, 0)
+ return buf_.flatbuffers_field_int64(pos_, 18, 0)
def f32():
- buf_.flatbuffers_field_float32(pos_, 20, 0.0)
+ return buf_.flatbuffers_field_float32(pos_, 20, 0.0)
def f64():
- buf_.flatbuffers_field_float64(pos_, 22, 0.0)
+ return buf_.flatbuffers_field_float64(pos_, 22, 0.0)
def v8(i:int):
- buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 24) + i * 1)
+ return buf_.read_int8_le(buf_.flatbuffers_field_vector(pos_, 24) + i * 1)
def v8_length():
- buf_.flatbuffers_field_vector_len(pos_, 24)
+ return buf_.flatbuffers_field_vector_len(pos_, 24)
def vf64(i:int):
- buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 26) + i * 8)
+ return buf_.read_float64_le(buf_.flatbuffers_field_vector(pos_, 26) + i * 8)
def vf64_length():
- buf_.flatbuffers_field_vector_len(pos_, 26)
-
-def GetRootAsTypeAliases(buf:string): TypeAliases { buf, buf.flatbuffers_indirect(0) }
-
-def TypeAliasesStart(b_:flatbuffers_builder):
- b_.StartObject(12)
-def TypeAliasesAddI8(b_:flatbuffers_builder, i8:int):
- b_.PrependInt8Slot(0, i8, 0)
-def TypeAliasesAddU8(b_:flatbuffers_builder, u8:int):
- b_.PrependUint8Slot(1, u8, 0)
-def TypeAliasesAddI16(b_:flatbuffers_builder, i16:int):
- b_.PrependInt16Slot(2, i16, 0)
-def TypeAliasesAddU16(b_:flatbuffers_builder, u16:int):
- b_.PrependUint16Slot(3, u16, 0)
-def TypeAliasesAddI32(b_:flatbuffers_builder, i32:int):
- b_.PrependInt32Slot(4, i32, 0)
-def TypeAliasesAddU32(b_:flatbuffers_builder, u32:int):
- b_.PrependUint32Slot(5, u32, 0)
-def TypeAliasesAddI64(b_:flatbuffers_builder, i64:int):
- b_.PrependInt64Slot(6, i64, 0)
-def TypeAliasesAddU64(b_:flatbuffers_builder, u64:int):
- b_.PrependUint64Slot(7, u64, 0)
-def TypeAliasesAddF32(b_:flatbuffers_builder, f32:float):
- b_.PrependFloat32Slot(8, f32, 0.0)
-def TypeAliasesAddF64(b_:flatbuffers_builder, f64:float):
- b_.PrependFloat64Slot(9, f64, 0.0)
-def TypeAliasesAddV8(b_:flatbuffers_builder, v8:int):
- b_.PrependUOffsetTRelativeSlot(10, v8, 0)
+ return buf_.flatbuffers_field_vector_len(pos_, 26)
+
+def GetRootAsTypeAliases(buf:string): return TypeAliases { buf, buf.flatbuffers_indirect(0) }
+
+struct TypeAliasesBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(12)
+ return this
+ def add_i8(i8:int):
+ b_.PrependInt8Slot(0, i8, 0)
+ return this
+ def add_u8(u8:int):
+ b_.PrependUint8Slot(1, u8, 0)
+ return this
+ def add_i16(i16:int):
+ b_.PrependInt16Slot(2, i16, 0)
+ return this
+ def add_u16(u16:int):
+ b_.PrependUint16Slot(3, u16, 0)
+ return this
+ def add_i32(i32:int):
+ b_.PrependInt32Slot(4, i32, 0)
+ return this
+ def add_u32(u32:int):
+ b_.PrependUint32Slot(5, u32, 0)
+ return this
+ def add_i64(i64:int):
+ b_.PrependInt64Slot(6, i64, 0)
+ return this
+ def add_u64(u64:int):
+ b_.PrependUint64Slot(7, u64, 0)
+ return this
+ def add_f32(f32:float):
+ b_.PrependFloat32Slot(8, f32, 0.0)
+ return this
+ def add_f64(f64:float):
+ b_.PrependFloat64Slot(9, f64, 0.0)
+ return this
+ def add_v8(v8:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(10, v8)
+ return this
+ def add_vf64(vf64:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(11, vf64)
+ return this
+ def end():
+ return b_.EndObject()
+
def TypeAliasesStartV8Vector(b_:flatbuffers_builder, n_:int):
b_.StartVector(1, n_, 1)
def TypeAliasesCreateV8Vector(b_:flatbuffers_builder, v_:[int]):
b_.StartVector(1, v_.length, 1)
reverse(v_) e_: b_.PrependInt8(e_)
- b_.EndVector(v_.length)
-def TypeAliasesAddVf64(b_:flatbuffers_builder, vf64:int):
- b_.PrependUOffsetTRelativeSlot(11, vf64, 0)
+ return b_.EndVector(v_.length)
+
def TypeAliasesStartVf64Vector(b_:flatbuffers_builder, n_:int):
b_.StartVector(8, n_, 8)
def TypeAliasesCreateVf64Vector(b_:flatbuffers_builder, v_:[float]):
b_.StartVector(8, v_.length, 8)
reverse(v_) e_: b_.PrependFloat64(e_)
- b_.EndVector(v_.length)
-def TypeAliasesEnd(b_:flatbuffers_builder):
- b_.EndObject()
+ return b_.EndVector(v_.length)
diff --git a/tests/monster_test_generated.rs b/tests/monster_test_generated.rs
index 6a0f37a5..528505c3 100644
--- a/tests/monster_test_generated.rs
+++ b/tests/monster_test_generated.rs
@@ -2,6 +2,8 @@
+use crate::include_test1_generated::*;
+use crate::include_test2_generated::*;
use std::mem;
use std::cmp::Ordering;
@@ -11,6 +13,8 @@ use self::flatbuffers::EndianScalar;
#[allow(unused_imports, dead_code)]
pub mod my_game {
+ use crate::include_test1_generated::*;
+ use crate::include_test2_generated::*;
use std::mem;
use std::cmp::Ordering;
@@ -35,6 +39,10 @@ impl<'a> flatbuffers::Follow<'a> for InParentNamespace<'a> {
}
impl<'a> InParentNamespace<'a> {
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.InParentNamespace"
+ }
+
#[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
InParentNamespace {
@@ -83,6 +91,8 @@ impl<'a: 'b, 'b> InParentNamespaceBuilder<'a, 'b> {
#[allow(unused_imports, dead_code)]
pub mod example_2 {
+ use crate::include_test1_generated::*;
+ use crate::include_test2_generated::*;
use std::mem;
use std::cmp::Ordering;
@@ -107,6 +117,10 @@ impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
}
impl<'a> Monster<'a> {
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example2.Monster"
+ }
+
#[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
Monster {
@@ -157,24 +171,30 @@ impl<'a: 'b, 'b> MonsterBuilder<'a, 'b> {
#[allow(unused_imports, dead_code)]
pub mod example {
+ use crate::include_test1_generated::*;
+ use crate::include_test2_generated::*;
use std::mem;
use std::cmp::Ordering;
extern crate flatbuffers;
use self::flatbuffers::EndianScalar;
+/// Composite components of Monster color.
#[allow(non_camel_case_types)]
-#[repr(i8)]
+#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Color {
Red = 1,
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
Green = 2,
+ /// \brief color Blue (1u << 3)
Blue = 8,
}
-const ENUM_MIN_COLOR: i8 = 1;
-const ENUM_MAX_COLOR: i8 = 8;
+pub const ENUM_MIN_COLOR: u8 = 1;
+pub const ENUM_MAX_COLOR: u8 = 8;
impl<'a> flatbuffers::Follow<'a> for Color {
type Inner = Self;
@@ -187,14 +207,14 @@ impl<'a> flatbuffers::Follow<'a> for Color {
impl flatbuffers::EndianScalar for Color {
#[inline]
fn to_little_endian(self) -> Self {
- let n = i8::to_le(self as i8);
- let p = &n as *const i8 as *const Color;
+ let n = u8::to_le(self as u8);
+ let p = &n as *const u8 as *const Color;
unsafe { *p }
}
#[inline]
fn from_little_endian(self) -> Self {
- let n = i8::from_le(self as i8);
- let p = &n as *const i8 as *const Color;
+ let n = u8::from_le(self as u8);
+ let p = &n as *const u8 as *const Color;
unsafe { *p }
}
}
@@ -208,14 +228,14 @@ impl flatbuffers::Push for Color {
}
#[allow(non_camel_case_types)]
-const ENUM_VALUES_COLOR:[Color; 3] = [
+pub const ENUM_VALUES_COLOR:[Color; 3] = [
Color::Red,
Color::Green,
Color::Blue
];
#[allow(non_camel_case_types)]
-const ENUM_NAMES_COLOR:[&'static str; 8] = [
+pub const ENUM_NAMES_COLOR:[&'static str; 8] = [
"Red",
"Green",
"",
@@ -227,11 +247,77 @@ const ENUM_NAMES_COLOR:[&'static str; 8] = [
];
pub fn enum_name_color(e: Color) -> &'static str {
- let index = e as i8 - Color::Red as i8;
+ let index = e as u8 - Color::Red as u8;
ENUM_NAMES_COLOR[index as usize]
}
#[allow(non_camel_case_types)]
+#[repr(i8)]
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+pub enum Race {
+ None = -1,
+ Human = 0,
+ Dwarf = 1,
+ Elf = 2,
+
+}
+
+pub const ENUM_MIN_RACE: i8 = -1;
+pub const ENUM_MAX_RACE: i8 = 2;
+
+impl<'a> flatbuffers::Follow<'a> for Race {
+ type Inner = Self;
+ #[inline]
+ fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
+ flatbuffers::read_scalar_at::<Self>(buf, loc)
+ }
+}
+
+impl flatbuffers::EndianScalar for Race {
+ #[inline]
+ fn to_little_endian(self) -> Self {
+ let n = i8::to_le(self as i8);
+ let p = &n as *const i8 as *const Race;
+ unsafe { *p }
+ }
+ #[inline]
+ fn from_little_endian(self) -> Self {
+ let n = i8::from_le(self as i8);
+ let p = &n as *const i8 as *const Race;
+ unsafe { *p }
+ }
+}
+
+impl flatbuffers::Push for Race {
+ type Output = Race;
+ #[inline]
+ fn push(&self, dst: &mut [u8], _rest: &[u8]) {
+ flatbuffers::emplace_scalar::<Race>(dst, *self);
+ }
+}
+
+#[allow(non_camel_case_types)]
+pub const ENUM_VALUES_RACE:[Race; 4] = [
+ Race::None,
+ Race::Human,
+ Race::Dwarf,
+ Race::Elf
+];
+
+#[allow(non_camel_case_types)]
+pub const ENUM_NAMES_RACE:[&'static str; 4] = [
+ "None",
+ "Human",
+ "Dwarf",
+ "Elf"
+];
+
+pub fn enum_name_race(e: Race) -> &'static str {
+ let index = e as i8 - Race::None as i8;
+ ENUM_NAMES_RACE[index as usize]
+}
+
+#[allow(non_camel_case_types)]
#[repr(u8)]
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub enum Any {
@@ -242,8 +328,8 @@ pub enum Any {
}
-const ENUM_MIN_ANY: u8 = 0;
-const ENUM_MAX_ANY: u8 = 3;
+pub const ENUM_MIN_ANY: u8 = 0;
+pub const ENUM_MAX_ANY: u8 = 3;
impl<'a> flatbuffers::Follow<'a> for Any {
type Inner = Self;
@@ -277,7 +363,7 @@ impl flatbuffers::Push for Any {
}
#[allow(non_camel_case_types)]
-const ENUM_VALUES_ANY:[Any; 4] = [
+pub const ENUM_VALUES_ANY:[Any; 4] = [
Any::NONE,
Any::Monster,
Any::TestSimpleTableWithEnum,
@@ -285,7 +371,7 @@ const ENUM_VALUES_ANY:[Any; 4] = [
];
#[allow(non_camel_case_types)]
-const ENUM_NAMES_ANY:[&'static str; 4] = [
+pub const ENUM_NAMES_ANY:[&'static str; 4] = [
"NONE",
"Monster",
"TestSimpleTableWithEnum",
@@ -304,13 +390,13 @@ pub struct AnyUnionTableOffset {}
pub enum AnyUniqueAliases {
NONE = 0,
M = 1,
- T = 2,
+ TS = 2,
M2 = 3,
}
-const ENUM_MIN_ANY_UNIQUE_ALIASES: u8 = 0;
-const ENUM_MAX_ANY_UNIQUE_ALIASES: u8 = 3;
+pub const ENUM_MIN_ANY_UNIQUE_ALIASES: u8 = 0;
+pub const ENUM_MAX_ANY_UNIQUE_ALIASES: u8 = 3;
impl<'a> flatbuffers::Follow<'a> for AnyUniqueAliases {
type Inner = Self;
@@ -344,18 +430,18 @@ impl flatbuffers::Push for AnyUniqueAliases {
}
#[allow(non_camel_case_types)]
-const ENUM_VALUES_ANY_UNIQUE_ALIASES:[AnyUniqueAliases; 4] = [
+pub const ENUM_VALUES_ANY_UNIQUE_ALIASES:[AnyUniqueAliases; 4] = [
AnyUniqueAliases::NONE,
AnyUniqueAliases::M,
- AnyUniqueAliases::T,
+ AnyUniqueAliases::TS,
AnyUniqueAliases::M2
];
#[allow(non_camel_case_types)]
-const ENUM_NAMES_ANY_UNIQUE_ALIASES:[&'static str; 4] = [
+pub const ENUM_NAMES_ANY_UNIQUE_ALIASES:[&'static str; 4] = [
"NONE",
"M",
- "T",
+ "TS",
"M2"
];
@@ -376,8 +462,8 @@ pub enum AnyAmbiguousAliases {
}
-const ENUM_MIN_ANY_AMBIGUOUS_ALIASES: u8 = 0;
-const ENUM_MAX_ANY_AMBIGUOUS_ALIASES: u8 = 3;
+pub const ENUM_MIN_ANY_AMBIGUOUS_ALIASES: u8 = 0;
+pub const ENUM_MAX_ANY_AMBIGUOUS_ALIASES: u8 = 3;
impl<'a> flatbuffers::Follow<'a> for AnyAmbiguousAliases {
type Inner = Self;
@@ -411,7 +497,7 @@ impl flatbuffers::Push for AnyAmbiguousAliases {
}
#[allow(non_camel_case_types)]
-const ENUM_VALUES_ANY_AMBIGUOUS_ALIASES:[AnyAmbiguousAliases; 4] = [
+pub const ENUM_VALUES_ANY_AMBIGUOUS_ALIASES:[AnyAmbiguousAliases; 4] = [
AnyAmbiguousAliases::NONE,
AnyAmbiguousAliases::M1,
AnyAmbiguousAliases::M2,
@@ -419,7 +505,7 @@ const ENUM_VALUES_ANY_AMBIGUOUS_ALIASES:[AnyAmbiguousAliases; 4] = [
];
#[allow(non_camel_case_types)]
-const ENUM_NAMES_ANY_AMBIGUOUS_ALIASES:[&'static str; 4] = [
+pub const ENUM_NAMES_ANY_AMBIGUOUS_ALIASES:[&'static str; 4] = [
"NONE",
"M1",
"M2",
@@ -487,6 +573,10 @@ impl Test {
padding0__: 0,
}
}
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example.Test"
+ }
+
pub fn a<'a>(&'a self) -> i16 {
self.a_.from_little_endian()
}
@@ -562,6 +652,10 @@ impl Vec3 {
padding2__: 0,
}
}
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example.Vec3"
+ }
+
pub fn x<'a>(&'a self) -> f32 {
self.x_.from_little_endian()
}
@@ -635,6 +729,10 @@ impl Ability {
}
}
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example.Ability"
+ }
+
pub fn id<'a>(&'a self) -> u32 {
self.id_.from_little_endian()
}
@@ -671,6 +769,10 @@ impl<'a> flatbuffers::Follow<'a> for TestSimpleTableWithEnum<'a> {
}
impl<'a> TestSimpleTableWithEnum<'a> {
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example.TestSimpleTableWithEnum"
+ }
+
#[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
TestSimpleTableWithEnum {
@@ -747,6 +849,10 @@ impl<'a> flatbuffers::Follow<'a> for Stat<'a> {
}
impl<'a> Stat<'a> {
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example.Stat"
+ }
+
#[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
Stat {
@@ -847,6 +953,10 @@ impl<'a> flatbuffers::Follow<'a> for Referrable<'a> {
}
impl<'a> Referrable<'a> {
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example.Referrable"
+ }
+
#[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
Referrable {
@@ -918,7 +1028,7 @@ impl<'a: 'b, 'b> ReferrableBuilder<'a, 'b> {
pub enum MonsterOffset {}
#[derive(Copy, Clone, Debug, PartialEq)]
-/// an example documentation comment: monster object
+/// an example documentation comment: "monster object"
pub struct Monster<'a> {
pub _tab: flatbuffers::Table<'a>,
}
@@ -934,6 +1044,10 @@ impl<'a> flatbuffers::Follow<'a> for Monster<'a> {
}
impl<'a> Monster<'a> {
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example.Monster"
+ }
+
#[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
Monster {
@@ -987,6 +1101,7 @@ impl<'a> Monster<'a> {
if let Some(x) = args.pos { builder.add_pos(x); }
builder.add_hp(args.hp);
builder.add_mana(args.mana);
+ builder.add_signed_enum(args.signed_enum);
builder.add_any_ambiguous_type(args.any_ambiguous_type);
builder.add_any_unique_type(args.any_unique_type);
builder.add_testbool(args.testbool);
@@ -1042,6 +1157,7 @@ impl<'a> Monster<'a> {
pub const VT_ANY_AMBIGUOUS_TYPE: flatbuffers::VOffsetT = 94;
pub const VT_ANY_AMBIGUOUS: flatbuffers::VOffsetT = 96;
pub const VT_VECTOR_OF_ENUMS: flatbuffers::VOffsetT = 98;
+ pub const VT_SIGNED_ENUM: flatbuffers::VOffsetT = 100;
#[inline]
pub fn pos(&self) -> Option<&'a Vec3> {
@@ -1253,6 +1369,10 @@ impl<'a> Monster<'a> {
self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, Color>>>(Monster::VT_VECTOR_OF_ENUMS, None)
}
#[inline]
+ pub fn signed_enum(&self) -> Race {
+ self._tab.get::<Race>(Monster::VT_SIGNED_ENUM, Some(Race::None)).unwrap()
+ }
+ #[inline]
#[allow(non_snake_case)]
pub fn test_as_monster(&self) -> Option<Monster<'a>> {
if self.test_type() == Any::Monster {
@@ -1294,8 +1414,8 @@ impl<'a> Monster<'a> {
#[inline]
#[allow(non_snake_case)]
- pub fn any_unique_as_t(&self) -> Option<TestSimpleTableWithEnum<'a>> {
- if self.any_unique_type() == AnyUniqueAliases::T {
+ pub fn any_unique_as_ts(&self) -> Option<TestSimpleTableWithEnum<'a>> {
+ if self.any_unique_type() == AnyUniqueAliases::TS {
self.any_unique().map(|u| TestSimpleTableWithEnum::init_from_table(u))
} else {
None
@@ -1392,6 +1512,7 @@ pub struct MonsterArgs<'a> {
pub any_ambiguous_type: AnyAmbiguousAliases,
pub any_ambiguous: Option<flatbuffers::WIPOffset<flatbuffers::UnionWIPOffset>>,
pub vector_of_enums: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a , Color>>>,
+ pub signed_enum: Race,
}
impl<'a> Default for MonsterArgs<'a> {
#[inline]
@@ -1444,6 +1565,7 @@ impl<'a> Default for MonsterArgs<'a> {
any_ambiguous_type: AnyAmbiguousAliases::NONE,
any_ambiguous: None,
vector_of_enums: None,
+ signed_enum: Race::None,
}
}
}
@@ -1641,6 +1763,10 @@ impl<'a: 'b, 'b> MonsterBuilder<'a, 'b> {
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Monster::VT_VECTOR_OF_ENUMS, vector_of_enums);
}
#[inline]
+ pub fn add_signed_enum(&mut self, signed_enum: Race) {
+ self.fbb_.push_slot::<Race>(Monster::VT_SIGNED_ENUM, signed_enum, Race::None);
+ }
+ #[inline]
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> MonsterBuilder<'a, 'b> {
let start = _fbb.start_table();
MonsterBuilder {
@@ -1674,6 +1800,10 @@ impl<'a> flatbuffers::Follow<'a> for TypeAliases<'a> {
}
impl<'a> TypeAliases<'a> {
+ pub const fn get_fully_qualified_name() -> &'static str {
+ "MyGame.Example.TypeAliases"
+ }
+
#[inline]
pub fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
TypeAliases {
diff --git a/tests/monster_test_generated.ts b/tests/monster_test_generated.ts
index 3784a19a..414bedbb 100644
--- a/tests/monster_test_generated.ts
+++ b/tests/monster_test_generated.ts
@@ -1,12 +1,23 @@
// automatically generated by the FlatBuffers compiler, do not modify
/**
+ * Composite components of Monster color.
+ *
* @enum {number}
*/
export namespace MyGame.Example{
export enum Color{
Red= 1,
+
+ /**
+ * \brief color Green
+ * Green is bit_flag with value (1u << 1)
+ */
Green= 2,
+
+ /**
+ * \brief color Blue (1u << 3)
+ */
Blue= 8
}};
@@ -14,6 +25,17 @@ export enum Color{
* @enum {number}
*/
export namespace MyGame.Example{
+export enum Race{
+ None= -1,
+ Human= 0,
+ Dwarf= 1,
+ Elf= 2
+}};
+
+/**
+ * @enum {number}
+ */
+export namespace MyGame.Example{
export enum Any{
NONE= 0,
Monster= 1,
@@ -28,7 +50,7 @@ export namespace MyGame.Example{
export enum AnyUniqueAliases{
NONE= 0,
M= 1,
- T= 2,
+ TS= 2,
M2= 3
}};
@@ -68,7 +90,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):InParentNamespace {
* @returns InParentNamespace
*/
static getRootAsInParentNamespace(bb:flatbuffers.ByteBuffer, obj?:InParentNamespace):InParentNamespace {
- return (obj || new InParentNamespace).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new InParentNamespace()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param InParentNamespace= obj
+ * @returns InParentNamespace
+ */
+static getSizePrefixedRootAsInParentNamespace(bb:flatbuffers.ByteBuffer, obj?:InParentNamespace):InParentNamespace {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new InParentNamespace()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -118,7 +150,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):Monster {
* @returns Monster
*/
static getRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
- return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new Monster()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getSizePrefixedRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new Monster()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -247,7 +289,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):TestSimpleTableWithEnum {
* @returns TestSimpleTableWithEnum
*/
static getRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimpleTableWithEnum):TestSimpleTableWithEnum {
- return (obj || new TestSimpleTableWithEnum).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new TestSimpleTableWithEnum()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TestSimpleTableWithEnum= obj
+ * @returns TestSimpleTableWithEnum
+ */
+static getSizePrefixedRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimpleTableWithEnum):TestSimpleTableWithEnum {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new TestSimpleTableWithEnum()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -255,7 +307,7 @@ static getRootAsTestSimpleTableWithEnum(bb:flatbuffers.ByteBuffer, obj?:TestSimp
*/
color():MyGame.Example.Color {
var offset = this.bb!.__offset(this.bb_pos, 4);
- return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
+ return offset ? /** */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Green;
};
/**
@@ -269,7 +321,7 @@ mutate_color(value:MyGame.Example.Color):boolean {
return false;
}
- this.bb!.writeInt8(this.bb_pos + offset, value);
+ this.bb!.writeUint8(this.bb_pos + offset, value);
return true;
};
@@ -415,7 +467,7 @@ mutate_test1(value:number):boolean {
* @returns MyGame.Example.Color
*/
test2():MyGame.Example.Color {
- return /** */ (this.bb!.readInt8(this.bb_pos + 24));
+ return /** */ (this.bb!.readUint8(this.bb_pos + 24));
};
/**
@@ -429,7 +481,7 @@ mutate_test2(value:MyGame.Example.Color):boolean {
return false;
}
- this.bb!.writeInt8(this.bb_pos + offset, value);
+ this.bb!.writeUint8(this.bb_pos + offset, value);
return true;
};
@@ -438,7 +490,7 @@ mutate_test2(value:MyGame.Example.Color):boolean {
* @returns MyGame.Example.Test|null
*/
test3(obj?:MyGame.Example.Test):MyGame.Example.Test|null {
- return (obj || new MyGame.Example.Test).__init(this.bb_pos + 26, this.bb!);
+ return (obj || new MyGame.Example.Test()).__init(this.bb_pos + 26, this.bb!);
};
/**
@@ -574,7 +626,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):Stat {
* @returns Stat
*/
static getRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
- return (obj || new Stat).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new Stat()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Stat= obj
+ * @returns Stat
+ */
+static getSizePrefixedRootAsStat(bb:flatbuffers.ByteBuffer, obj?:Stat):Stat {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new Stat()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -708,7 +770,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):Referrable {
* @returns Referrable
*/
static getRootAsReferrable(bb:flatbuffers.ByteBuffer, obj?:Referrable):Referrable {
- return (obj || new Referrable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new Referrable()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Referrable= obj
+ * @returns Referrable
+ */
+static getSizePrefixedRootAsReferrable(bb:flatbuffers.ByteBuffer, obj?:Referrable):Referrable {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new Referrable()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -766,7 +838,7 @@ static createReferrable(builder:flatbuffers.Builder, id:flatbuffers.Long):flatbu
}
}
/**
- * an example documentation comment: monster object
+ * an example documentation comment: "monster object"
*
* @constructor
*/
@@ -792,7 +864,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):Monster {
* @returns Monster
*/
static getRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
- return (obj || new Monster).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new Monster()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Monster= obj
+ * @returns Monster
+ */
+static getSizePrefixedRootAsMonster(bb:flatbuffers.ByteBuffer, obj?:Monster):Monster {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new Monster()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -809,7 +891,7 @@ static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean {
*/
pos(obj?:MyGame.Example.Vec3):MyGame.Example.Vec3|null {
var offset = this.bb!.__offset(this.bb_pos, 4);
- return offset ? (obj || new MyGame.Example.Vec3).__init(this.bb_pos + offset, this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Vec3()).__init(this.bb_pos + offset, this.bb!) : null;
};
/**
@@ -899,7 +981,7 @@ inventoryArray():Uint8Array|null {
*/
color():MyGame.Example.Color {
var offset = this.bb!.__offset(this.bb_pos, 16);
- return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
+ return offset ? /** */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Color.Blue;
};
/**
@@ -913,7 +995,7 @@ mutate_color(value:MyGame.Example.Color):boolean {
return false;
}
- this.bb!.writeInt8(this.bb_pos + offset, value);
+ this.bb!.writeUint8(this.bb_pos + offset, value);
return true;
};
@@ -926,21 +1008,6 @@ testType():MyGame.Example.Any {
};
/**
- * @param MyGame.Example.Any value
- * @returns boolean
- */
-mutate_test_type(value:MyGame.Example.Any):boolean {
- var offset = this.bb!.__offset(this.bb_pos, 18);
-
- if (offset === 0) {
- return false;
- }
-
- this.bb!.writeUint8(this.bb_pos + offset, value);
- return true;
-};
-
-/**
* @param flatbuffers.Table obj
* @returns ?flatbuffers.Table
*/
@@ -956,7 +1023,7 @@ test<T extends flatbuffers.Table>(obj:T):T|null {
*/
test4(index: number, obj?:MyGame.Example.Test):MyGame.Example.Test|null {
var offset = this.bb!.__offset(this.bb_pos, 22);
- return offset ? (obj || new MyGame.Example.Test).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Test()).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
};
/**
@@ -997,7 +1064,7 @@ testarrayofstringLength():number {
*/
testarrayoftables(index: number, obj?:MyGame.Example.Monster):MyGame.Example.Monster|null {
var offset = this.bb!.__offset(this.bb_pos, 26);
- return offset ? (obj || new MyGame.Example.Monster).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Monster()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
};
/**
@@ -1014,7 +1081,7 @@ testarrayoftablesLength():number {
*/
enemy(obj?:MyGame.Example.Monster):MyGame.Example.Monster|null {
var offset = this.bb!.__offset(this.bb_pos, 28);
- return offset ? (obj || new MyGame.Example.Monster).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Monster()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};
/**
@@ -1048,7 +1115,7 @@ testnestedflatbufferArray():Uint8Array|null {
*/
testempty(obj?:MyGame.Example.Stat):MyGame.Example.Stat|null {
var offset = this.bb!.__offset(this.bb_pos, 32);
- return offset ? (obj || new MyGame.Example.Stat).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Stat()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};
/**
@@ -1379,7 +1446,7 @@ testarrayofstring2Length():number {
*/
testarrayofsortedstruct(index: number, obj?:MyGame.Example.Ability):MyGame.Example.Ability|null {
var offset = this.bb!.__offset(this.bb_pos, 62);
- return offset ? (obj || new MyGame.Example.Ability).__init(this.bb!.__vector(this.bb_pos + offset) + index * 8, this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Ability()).__init(this.bb!.__vector(this.bb_pos + offset) + index * 8, this.bb!) : null;
};
/**
@@ -1422,7 +1489,7 @@ flexArray():Uint8Array|null {
*/
test5(index: number, obj?:MyGame.Example.Test):MyGame.Example.Test|null {
var offset = this.bb!.__offset(this.bb_pos, 66);
- return offset ? (obj || new MyGame.Example.Test).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Test()).__init(this.bb!.__vector(this.bb_pos + offset) + index * 4, this.bb!) : null;
};
/**
@@ -1481,7 +1548,7 @@ vectorOfDoublesArray():Float64Array|null {
*/
parentNamespaceTest(obj?:MyGame.InParentNamespace):MyGame.InParentNamespace|null {
var offset = this.bb!.__offset(this.bb_pos, 72);
- return offset ? (obj || new MyGame.InParentNamespace).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+ return offset ? (obj || new MyGame.InParentNamespace()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};
/**
@@ -1491,7 +1558,7 @@ parentNamespaceTest(obj?:MyGame.InParentNamespace):MyGame.InParentNamespace|null
*/
vectorOfReferrables(index: number, obj?:MyGame.Example.Referrable):MyGame.Example.Referrable|null {
var offset = this.bb!.__offset(this.bb_pos, 74);
- return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Referrable()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
};
/**
@@ -1549,7 +1616,7 @@ vectorOfWeakReferencesLength():number {
*/
vectorOfStrongReferrables(index: number, obj?:MyGame.Example.Referrable):MyGame.Example.Referrable|null {
var offset = this.bb!.__offset(this.bb_pos, 80);
- return offset ? (obj || new MyGame.Example.Referrable).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
+ return offset ? (obj || new MyGame.Example.Referrable()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
};
/**
@@ -1649,21 +1716,6 @@ anyUniqueType():MyGame.Example.AnyUniqueAliases {
};
/**
- * @param MyGame.Example.AnyUniqueAliases value
- * @returns boolean
- */
-mutate_any_unique_type(value:MyGame.Example.AnyUniqueAliases):boolean {
- var offset = this.bb!.__offset(this.bb_pos, 90);
-
- if (offset === 0) {
- return false;
- }
-
- this.bb!.writeUint8(this.bb_pos + offset, value);
- return true;
-};
-
-/**
* @param flatbuffers.Table obj
* @returns ?flatbuffers.Table
*/
@@ -1681,21 +1733,6 @@ anyAmbiguousType():MyGame.Example.AnyAmbiguousAliases {
};
/**
- * @param MyGame.Example.AnyAmbiguousAliases value
- * @returns boolean
- */
-mutate_any_ambiguous_type(value:MyGame.Example.AnyAmbiguousAliases):boolean {
- var offset = this.bb!.__offset(this.bb_pos, 94);
-
- if (offset === 0) {
- return false;
- }
-
- this.bb!.writeUint8(this.bb_pos + offset, value);
- return true;
-};
-
-/**
* @param flatbuffers.Table obj
* @returns ?flatbuffers.Table
*/
@@ -1710,7 +1747,7 @@ anyAmbiguous<T extends flatbuffers.Table>(obj:T):T|null {
*/
vectorOfEnums(index: number):MyGame.Example.Color|null {
var offset = this.bb!.__offset(this.bb_pos, 98);
- return offset ? /** */ (this.bb!.readInt8(this.bb!.__vector(this.bb_pos + offset) + index)) : /** */ (0);
+ return offset ? /** */ (this.bb!.readUint8(this.bb!.__vector(this.bb_pos + offset) + index)) : /** */ (0);
};
/**
@@ -1722,18 +1759,41 @@ vectorOfEnumsLength():number {
};
/**
- * @returns Int8Array
+ * @returns Uint8Array
*/
-vectorOfEnumsArray():Int8Array|null {
+vectorOfEnumsArray():Uint8Array|null {
var offset = this.bb!.__offset(this.bb_pos, 98);
- return offset ? new Int8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+ return offset ? new Uint8Array(this.bb!.bytes().buffer, this.bb!.bytes().byteOffset + this.bb!.__vector(this.bb_pos + offset), this.bb!.__vector_len(this.bb_pos + offset)) : null;
+};
+
+/**
+ * @returns MyGame.Example.Race
+ */
+signedEnum():MyGame.Example.Race {
+ var offset = this.bb!.__offset(this.bb_pos, 100);
+ return offset ? /** */ (this.bb!.readInt8(this.bb_pos + offset)) : MyGame.Example.Race.None;
+};
+
+/**
+ * @param MyGame.Example.Race value
+ * @returns boolean
+ */
+mutate_signed_enum(value:MyGame.Example.Race):boolean {
+ var offset = this.bb!.__offset(this.bb_pos, 100);
+
+ if (offset === 0) {
+ return false;
+ }
+
+ this.bb!.writeInt8(this.bb_pos + offset, value);
+ return true;
};
/**
* @param flatbuffers.Builder builder
*/
static startMonster(builder:flatbuffers.Builder) {
- builder.startObject(48);
+ builder.startObject(49);
};
/**
@@ -2453,6 +2513,14 @@ static startVectorOfEnumsVector(builder:flatbuffers.Builder, numElems:number) {
/**
* @param flatbuffers.Builder builder
+ * @param MyGame.Example.Race signedEnum
+ */
+static addSignedEnum(builder:flatbuffers.Builder, signedEnum:MyGame.Example.Race) {
+ builder.addFieldInt8(48, signedEnum, MyGame.Example.Race.None);
+};
+
+/**
+ * @param flatbuffers.Builder builder
* @returns flatbuffers.Offset
*/
static endMonster(builder:flatbuffers.Builder):flatbuffers.Offset {
@@ -2469,7 +2537,15 @@ static finishMonsterBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offse
builder.finish(offset, 'MONS');
};
-static createMonster(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset, mana:number, hp:number, nameOffset:flatbuffers.Offset, inventoryOffset:flatbuffers.Offset, color:MyGame.Example.Color, testType:MyGame.Example.Any, testOffset:flatbuffers.Offset, test4Offset:flatbuffers.Offset, testarrayofstringOffset:flatbuffers.Offset, testarrayoftablesOffset:flatbuffers.Offset, enemyOffset:flatbuffers.Offset, testnestedflatbufferOffset:flatbuffers.Offset, testemptyOffset:flatbuffers.Offset, testbool:boolean, testhashs32Fnv1:number, testhashu32Fnv1:number, testhashs64Fnv1:flatbuffers.Long, testhashu64Fnv1:flatbuffers.Long, testhashs32Fnv1a:number, testhashu32Fnv1a:number, testhashs64Fnv1a:flatbuffers.Long, testhashu64Fnv1a:flatbuffers.Long, testarrayofboolsOffset:flatbuffers.Offset, testf:number, testf2:number, testf3:number, testarrayofstring2Offset:flatbuffers.Offset, testarrayofsortedstructOffset:flatbuffers.Offset, flexOffset:flatbuffers.Offset, test5Offset:flatbuffers.Offset, vectorOfLongsOffset:flatbuffers.Offset, vectorOfDoublesOffset:flatbuffers.Offset, parentNamespaceTestOffset:flatbuffers.Offset, vectorOfReferrablesOffset:flatbuffers.Offset, singleWeakReference:flatbuffers.Long, vectorOfWeakReferencesOffset:flatbuffers.Offset, vectorOfStrongReferrablesOffset:flatbuffers.Offset, coOwningReference:flatbuffers.Long, vectorOfCoOwningReferencesOffset:flatbuffers.Offset, nonOwningReference:flatbuffers.Long, vectorOfNonOwningReferencesOffset:flatbuffers.Offset, anyUniqueType:MyGame.Example.AnyUniqueAliases, anyUniqueOffset:flatbuffers.Offset, anyAmbiguousType:MyGame.Example.AnyAmbiguousAliases, anyAmbiguousOffset:flatbuffers.Offset, vectorOfEnumsOffset:flatbuffers.Offset):flatbuffers.Offset {
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishSizePrefixedMonsterBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+ builder.finish(offset, 'MONS', true);
+};
+
+static createMonster(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset, mana:number, hp:number, nameOffset:flatbuffers.Offset, inventoryOffset:flatbuffers.Offset, color:MyGame.Example.Color, testType:MyGame.Example.Any, testOffset:flatbuffers.Offset, test4Offset:flatbuffers.Offset, testarrayofstringOffset:flatbuffers.Offset, testarrayoftablesOffset:flatbuffers.Offset, enemyOffset:flatbuffers.Offset, testnestedflatbufferOffset:flatbuffers.Offset, testemptyOffset:flatbuffers.Offset, testbool:boolean, testhashs32Fnv1:number, testhashu32Fnv1:number, testhashs64Fnv1:flatbuffers.Long, testhashu64Fnv1:flatbuffers.Long, testhashs32Fnv1a:number, testhashu32Fnv1a:number, testhashs64Fnv1a:flatbuffers.Long, testhashu64Fnv1a:flatbuffers.Long, testarrayofboolsOffset:flatbuffers.Offset, testf:number, testf2:number, testf3:number, testarrayofstring2Offset:flatbuffers.Offset, testarrayofsortedstructOffset:flatbuffers.Offset, flexOffset:flatbuffers.Offset, test5Offset:flatbuffers.Offset, vectorOfLongsOffset:flatbuffers.Offset, vectorOfDoublesOffset:flatbuffers.Offset, parentNamespaceTestOffset:flatbuffers.Offset, vectorOfReferrablesOffset:flatbuffers.Offset, singleWeakReference:flatbuffers.Long, vectorOfWeakReferencesOffset:flatbuffers.Offset, vectorOfStrongReferrablesOffset:flatbuffers.Offset, coOwningReference:flatbuffers.Long, vectorOfCoOwningReferencesOffset:flatbuffers.Offset, nonOwningReference:flatbuffers.Long, vectorOfNonOwningReferencesOffset:flatbuffers.Offset, anyUniqueType:MyGame.Example.AnyUniqueAliases, anyUniqueOffset:flatbuffers.Offset, anyAmbiguousType:MyGame.Example.AnyAmbiguousAliases, anyAmbiguousOffset:flatbuffers.Offset, vectorOfEnumsOffset:flatbuffers.Offset, signedEnum:MyGame.Example.Race):flatbuffers.Offset {
Monster.startMonster(builder);
Monster.addPos(builder, posOffset);
Monster.addMana(builder, mana);
@@ -2518,6 +2594,7 @@ static createMonster(builder:flatbuffers.Builder, posOffset:flatbuffers.Offset,
Monster.addAnyAmbiguousType(builder, anyAmbiguousType);
Monster.addAnyAmbiguous(builder, anyAmbiguousOffset);
Monster.addVectorOfEnums(builder, vectorOfEnumsOffset);
+ Monster.addSignedEnum(builder, signedEnum);
return Monster.endMonster(builder);
}
}
@@ -2547,7 +2624,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):TypeAliases {
* @returns TypeAliases
*/
static getRootAsTypeAliases(bb:flatbuffers.ByteBuffer, obj?:TypeAliases):TypeAliases {
- return (obj || new TypeAliases).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new TypeAliases()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TypeAliases= obj
+ * @returns TypeAliases
+ */
+static getSizePrefixedRootAsTypeAliases(bb:flatbuffers.ByteBuffer, obj?:TypeAliases):TypeAliases {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new TypeAliases()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
diff --git a/tests/monster_test_my_game.example_generated.dart b/tests/monster_test_my_game.example_generated.dart
index d4acf876..2ad2c952 100644
--- a/tests/monster_test_my_game.example_generated.dart
+++ b/tests/monster_test_my_game.example_generated.dart
@@ -9,6 +9,7 @@ import 'package:flat_buffers/flat_buffers.dart' as fb;
import './monster_test_my_game_generated.dart' as my_game;
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
+/// Composite components of Monster color.
class Color {
final int value;
const Color._(this.value);
@@ -24,7 +25,12 @@ class Color {
static bool containsValue(int value) => values.containsKey(value);
static const Color Red = const Color._(1);
+
+ /// \brief color Green
+ /// Green is bit_flag with value (1u << 1)
static const Color Green = const Color._(2);
+
+ /// \brief color Blue (1u << 3)
static const Color Blue = const Color._(8);
static get values => {1: Red,2: Green,8: Blue,};
@@ -44,7 +50,48 @@ class _ColorReader extends fb.Reader<Color> {
@override
Color read(fb.BufferContext bc, int offset) =>
- new Color.fromValue(const fb.Int8Reader().read(bc, offset));
+ new Color.fromValue(const fb.Uint8Reader().read(bc, offset));
+}
+
+class Race {
+ final int value;
+ const Race._(this.value);
+
+ factory Race.fromValue(int value) {
+ if (value == null) value = 0;
+ if (!values.containsKey(value)) {
+ throw new StateError('Invalid value $value for bit flag enum Race');
+ }
+ return values[value];
+ }
+
+ static const int minValue = -1;
+ static const int maxValue = 2;
+ static bool containsValue(int value) => values.containsKey(value);
+
+ static const Race None = const Race._(-1);
+ static const Race Human = const Race._(0);
+ static const Race Dwarf = const Race._(1);
+ static const Race Elf = const Race._(2);
+ static get values => {-1: None,0: Human,1: Dwarf,2: Elf,};
+
+ static const fb.Reader<Race> reader = const _RaceReader();
+
+ @override
+ String toString() {
+ return 'Race{value: $value}';
+ }
+}
+
+class _RaceReader extends fb.Reader<Race> {
+ const _RaceReader();
+
+ @override
+ int get size => 1;
+
+ @override
+ Race read(fb.BufferContext bc, int offset) =>
+ new Race.fromValue(const fb.Int8Reader().read(bc, offset));
}
class AnyTypeId {
@@ -106,9 +153,9 @@ class AnyUniqueAliasesTypeId {
static const AnyUniqueAliasesTypeId NONE = const AnyUniqueAliasesTypeId._(0);
static const AnyUniqueAliasesTypeId M = const AnyUniqueAliasesTypeId._(1);
- static const AnyUniqueAliasesTypeId T = const AnyUniqueAliasesTypeId._(2);
+ static const AnyUniqueAliasesTypeId TS = const AnyUniqueAliasesTypeId._(2);
static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
- static get values => {0: NONE,1: M,2: T,3: M2,};
+ static get values => {0: NONE,1: M,2: TS,3: M2,};
static const fb.Reader<AnyUniqueAliasesTypeId> reader = const _AnyUniqueAliasesTypeIdReader();
@@ -257,7 +304,7 @@ class TestSimpleTableWithEnum {
final fb.BufferContext _bc;
final int _bcOffset;
- Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 2));
+ Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 4, 2));
@override
String toString() {
@@ -285,7 +332,7 @@ class TestSimpleTableWithEnumBuilder {
}
int addColor(Color color) {
- fbBuilder.addInt8(0, color?.value);
+ fbBuilder.addUint8(0, color?.value);
return fbBuilder.offset;
}
@@ -309,7 +356,7 @@ class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder {
assert(fbBuilder != null);
fbBuilder.startTable();
- fbBuilder.addInt8(0, _color?.value);
+ fbBuilder.addUint8(0, _color?.value);
return fbBuilder.endTable();
}
@@ -333,7 +380,7 @@ class Vec3 {
double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
- Color get test2 => new Color.fromValue(const fb.Int8Reader().read(_bc, _bcOffset + 24));
+ Color get test2 => new Color.fromValue(const fb.Uint8Reader().read(_bc, _bcOffset + 24));
Test get test3 => Test.reader.read(_bc, _bcOffset + 26);
@override
@@ -364,7 +411,7 @@ class Vec3Builder {
fbBuilder.pad(2);
test3();
fbBuilder.pad(1);
- fbBuilder.putInt8(test2?.value);
+ fbBuilder.putUint8(test2?.value);
fbBuilder.putFloat64(test1);
fbBuilder.pad(4);
fbBuilder.putFloat32(z);
@@ -407,7 +454,7 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder {
fbBuilder.pad(2);
_test3.finish(fbBuilder);
fbBuilder.pad(1);
- fbBuilder.putInt8(_test2?.value);
+ fbBuilder.putUint8(_test2?.value);
fbBuilder.putFloat64(_test1);
fbBuilder.pad(4);
fbBuilder.putFloat32(_z);
@@ -670,7 +717,7 @@ class ReferrableObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.finish(offset, fileIdentifier);
}
}
-/// an example documentation comment: monster object
+/// an example documentation comment: "monster object"
class Monster {
Monster._(this._bc, this._bcOffset);
factory Monster(List<int> bytes) {
@@ -688,7 +735,7 @@ class Monster {
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
- Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 8));
+ Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 16, 8));
AnyTypeId get testType => new AnyTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 18, 0));
dynamic get test {
switch (testType?.value) {
@@ -700,8 +747,8 @@ class Monster {
}
List<Test> get test4 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 22, null);
List<String> get testarrayofstring => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 24, null);
-/// an example documentation comment: this will end up in the generated code
-/// multiline too
+ /// an example documentation comment: this will end up in the generated code
+ /// multiline too
List<Monster> get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGet(_bc, _bcOffset, 26, null);
Monster get enemy => Monster.reader.vTableGet(_bc, _bcOffset, 28, null);
List<int> get testnestedflatbuffer => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 30, null);
@@ -738,7 +785,7 @@ class Monster {
dynamic get anyUnique {
switch (anyUniqueType?.value) {
case 1: return M.reader.vTableGet(_bc, _bcOffset, 92, null);
- case 2: return T.reader.vTableGet(_bc, _bcOffset, 92, null);
+ case 2: return TS.reader.vTableGet(_bc, _bcOffset, 92, null);
case 3: return M2.reader.vTableGet(_bc, _bcOffset, 92, null);
default: return null;
}
@@ -753,10 +800,11 @@ class Monster {
}
}
List<Color> get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGet(_bc, _bcOffset, 98, null);
+ Race get signedEnum => new Race.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 100, -1));
@override
String toString() {
- return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums}';
+ return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums, signedEnum: $signedEnum}';
}
}
@@ -800,7 +848,7 @@ class MonsterBuilder {
return fbBuilder.offset;
}
int addColor(Color color) {
- fbBuilder.addInt8(6, color?.value);
+ fbBuilder.addUint8(6, color?.value);
return fbBuilder.offset;
}
int addTestType(AnyTypeId testType) {
@@ -967,6 +1015,10 @@ class MonsterBuilder {
fbBuilder.addOffset(47, offset);
return fbBuilder.offset;
}
+ int addSignedEnum(Race signedEnum) {
+ fbBuilder.addInt8(48, signedEnum?.value);
+ return fbBuilder.offset;
+ }
int finish() {
return fbBuilder.endTable();
@@ -1021,6 +1073,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
final AnyAmbiguousAliasesTypeId _anyAmbiguousType;
final dynamic _anyAmbiguous;
final List<Color> _vectorOfEnums;
+ final Race _signedEnum;
MonsterObjectBuilder({
Vec3ObjectBuilder pos,
@@ -1070,6 +1123,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
AnyAmbiguousAliasesTypeId anyAmbiguousType,
dynamic anyAmbiguous,
List<Color> vectorOfEnums,
+ Race signedEnum,
})
: _pos = pos,
_mana = mana,
@@ -1117,7 +1171,8 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
_anyUnique = anyUnique,
_anyAmbiguousType = anyAmbiguousType,
_anyAmbiguous = anyAmbiguous,
- _vectorOfEnums = vectorOfEnums;
+ _vectorOfEnums = vectorOfEnums,
+ _signedEnum = signedEnum;
/// Finish building, and store into the [fbBuilder].
@override
@@ -1183,7 +1238,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
final int anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
final int anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
final int vectorOfEnumsOffset = _vectorOfEnums?.isNotEmpty == true
- ? fbBuilder.writeListInt8(_vectorOfEnums.map((f) => f.value))
+ ? fbBuilder.writeListUint8(_vectorOfEnums.map((f) => f.value))
: null;
fbBuilder.startTable();
@@ -1198,7 +1253,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
if (inventoryOffset != null) {
fbBuilder.addOffset(5, inventoryOffset);
}
- fbBuilder.addInt8(6, _color?.value);
+ fbBuilder.addUint8(6, _color?.value);
fbBuilder.addUint8(7, _testType?.value);
if (testOffset != null) {
fbBuilder.addOffset(8, testOffset);
@@ -1286,6 +1341,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
if (vectorOfEnumsOffset != null) {
fbBuilder.addOffset(47, vectorOfEnumsOffset);
}
+ fbBuilder.addInt8(48, _signedEnum?.value);
return fbBuilder.endTable();
}
diff --git a/tests/monsterdata_extra.json b/tests/monsterdata_extra.json
new file mode 100644
index 00000000..53045cdd
--- /dev/null
+++ b/tests/monsterdata_extra.json
@@ -0,0 +1,15 @@
+{
+ // Initialize with non-default values.
+ d0 : -nan, // match with default
+ d1 : +inf,
+ d2 : -inf,
+ d3: nan,
+ f0 : +nan, // match with default
+ f1 : -nan, // match with default
+ f2 : +inf, // match with default
+ f3 : -inf, // match with default
+ // Values should have exact binary representation
+ // to avoid rounding effects in tests.
+ dvec : [2.0, +inf, -inf, nan,],
+ fvec : [1.0, -inf, +inf, nan],
+}
diff --git a/tests/monsterdata_python_wire.mon b/tests/monsterdata_python_wire.mon
index e41384a6..2fb956d5 100644
--- a/tests/monsterdata_python_wire.mon
+++ b/tests/monsterdata_python_wire.mon
Binary files differ
diff --git a/tests/monsterdata_test.golden b/tests/monsterdata_test.golden
index ab401544..4bead974 100644
--- a/tests/monsterdata_test.golden
+++ b/tests/monsterdata_test.golden
@@ -56,6 +56,9 @@
name: "Wilma"
}
],
+ testnestedflatbuffer: {
+ name: "NestedMonster"
+ },
testbool: true,
testhashs32_fnv1: -579221183,
testhashu32_fnv1: 3715746113,
diff --git a/tests/monsterdata_test.json b/tests/monsterdata_test.json
index d3028b55..eb400801 100644
--- a/tests/monsterdata_test.json
+++ b/tests/monsterdata_test.json
@@ -4,7 +4,7 @@
y: "2",
z: 3,
test1: 3,
- test2: Green,
+ test2: "Green",
test3: {
a: 5,
b: 6
@@ -31,7 +31,7 @@
0,
1.7976931348623157e+308
],
- test_type: Monster,
+ test_type: "Monster",
test: {
name: "Fred",
pos: null
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs
index 1a75ed43..bb17d7b3 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.cs
@@ -5,11 +5,12 @@
namespace NamespaceA.NamespaceB
{
+[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum EnumInNestedNS : sbyte
{
- A = 0,
- B = 1,
- C = 2,
+ A = 0,
+ B = 1,
+ C = 2,
};
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go
index 797ea67f..6cec5ffc 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.go
@@ -2,7 +2,10 @@
package NamespaceB
-type EnumInNestedNS = int8
+import "strconv"
+
+type EnumInNestedNS int8
+
const (
EnumInNestedNSA EnumInNestedNS = 0
EnumInNestedNSB EnumInNestedNS = 1
@@ -10,8 +13,20 @@ const (
)
var EnumNamesEnumInNestedNS = map[EnumInNestedNS]string{
- EnumInNestedNSA:"A",
- EnumInNestedNSB:"B",
- EnumInNestedNSC:"C",
+ EnumInNestedNSA: "A",
+ EnumInNestedNSB: "B",
+ EnumInNestedNSC: "C",
}
+var EnumValuesEnumInNestedNS = map[string]EnumInNestedNS{
+ "A": EnumInNestedNSA,
+ "B": EnumInNestedNSB,
+ "C": EnumInNestedNSC,
+}
+
+func (v EnumInNestedNS) String() string {
+ if s, ok := EnumNamesEnumInNestedNS[v]; ok {
+ return s
+ }
+ return "EnumInNestedNS(" + strconv.FormatInt(int64(v), 10) + ")"
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt
new file mode 100644
index 00000000..0ede58ca
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/EnumInNestedNS.kt
@@ -0,0 +1,15 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class EnumInNestedNS private constructor() {
+ companion object {
+ const val A: Byte = 0
+ const val B: Byte = 1
+ const val C: Byte = 2
+ val names : Array<String> = arrayOf("A", "B", "C")
+ fun name(e: Int) : String = names[e]
+ }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs
index 397fb89f..6fa9dd3c 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.cs
@@ -6,13 +6,14 @@ namespace NamespaceA.NamespaceB
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct StructInNestedNS : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
public StructInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int A { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
@@ -20,13 +21,42 @@ public struct StructInNestedNS : IFlatbufferObject
public int B { get { return __p.bb.GetInt(__p.bb_pos + 4); } }
public void MutateB(int b) { __p.bb.PutInt(__p.bb_pos + 4, b); }
- public static Offset<StructInNestedNS> CreateStructInNestedNS(FlatBufferBuilder builder, int A, int B) {
+ public static Offset<NamespaceA.NamespaceB.StructInNestedNS> CreateStructInNestedNS(FlatBufferBuilder builder, int A, int B) {
builder.Prep(4, 8);
builder.PutInt(B);
builder.PutInt(A);
- return new Offset<StructInNestedNS>(builder.Offset);
+ return new Offset<NamespaceA.NamespaceB.StructInNestedNS>(builder.Offset);
+ }
+ public StructInNestedNST UnPack() {
+ var _o = new StructInNestedNST();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(StructInNestedNST _o) {
+ _o.A = this.A;
+ _o.B = this.B;
+ }
+ public static Offset<NamespaceA.NamespaceB.StructInNestedNS> Pack(FlatBufferBuilder builder, StructInNestedNST _o) {
+ if (_o == null) return default(Offset<NamespaceA.NamespaceB.StructInNestedNS>);
+ return CreateStructInNestedNS(
+ builder,
+ _o.A,
+ _o.B);
}
};
+public class StructInNestedNST
+{
+ [Newtonsoft.Json.JsonProperty("a")]
+ public int A { get; set; }
+ [Newtonsoft.Json.JsonProperty("b")]
+ public int B { get; set; }
+
+ public StructInNestedNST() {
+ this.A = 0;
+ this.B = 0;
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go
index e985fbf7..854403fc 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.go
@@ -6,6 +6,27 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type StructInNestedNST struct {
+ A int32
+ B int32
+}
+
+func (t *StructInNestedNST) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ return CreateStructInNestedNS(builder, t.A, t.B)
+}
+func (rcv *StructInNestedNS) UnPackTo(t *StructInNestedNST) {
+ t.A = rcv.A()
+ t.B = rcv.B()
+}
+
+func (rcv *StructInNestedNS) UnPack() *StructInNestedNST {
+ if rcv == nil { return nil }
+ t := &StructInNestedNST{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type StructInNestedNS struct {
_tab flatbuffers.Struct
}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java
index 42d47c13..65055610 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.java
@@ -9,7 +9,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class StructInNestedNS extends Struct {
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public StructInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int a() { return bb.getInt(bb_pos + 0); }
@@ -23,5 +23,12 @@ public final class StructInNestedNS extends Struct {
builder.putInt(a);
return builder.offset();
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public StructInNestedNS get(int j) { return get(new StructInNestedNS(), j); }
+ public StructInNestedNS get(StructInNestedNS obj, int j) { return obj.__assign(__element(j), bb); }
+ }
}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt
new file mode 100644
index 00000000..0273bb11
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.kt
@@ -0,0 +1,32 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class StructInNestedNS : Struct() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : StructInNestedNS {
+ __init(_i, _bb)
+ return this
+ }
+ val a : Int get() = bb.getInt(bb_pos + 0)
+ fun mutateA(a: Int) : ByteBuffer = bb.putInt(bb_pos + 0, a)
+ val b : Int get() = bb.getInt(bb_pos + 4)
+ fun mutateB(b: Int) : ByteBuffer = bb.putInt(bb_pos + 4, b)
+ companion object {
+ fun createStructInNestedNS(builder: FlatBufferBuilder, a: Int, b: Int) : Int {
+ builder.prep(4, 8)
+ builder.putInt(b)
+ builder.putInt(a)
+ return builder.offset()
+ }
+ }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
index 59cceaa6..9df52bde 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
+++ b/tests/namespace_test/NamespaceA/NamespaceB/StructInNestedNS.py
@@ -3,6 +3,8 @@
# namespace: NamespaceB
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class StructInNestedNS(object):
__slots__ = ['_tab']
@@ -21,3 +23,34 @@ def CreateStructInNestedNS(builder, a, b):
builder.PrependInt32(b)
builder.PrependInt32(a)
return builder.Offset()
+
+
+class StructInNestedNST(object):
+
+ # StructInNestedNST
+ def __init__(self):
+ self.a = 0 # type: int
+ self.b = 0 # type: int
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ structInNestedNS = StructInNestedNS()
+ structInNestedNS.Init(buf, pos)
+ return cls.InitFromObj(structInNestedNS)
+
+ @classmethod
+ def InitFromObj(cls, structInNestedNS):
+ x = StructInNestedNST()
+ x._UnPack(structInNestedNS)
+ return x
+
+ # StructInNestedNST
+ def _UnPack(self, structInNestedNS):
+ if structInNestedNS is None:
+ return
+ self.a = structInNestedNS.A()
+ self.b = structInNestedNS.B()
+
+ # StructInNestedNST
+ def Pack(self, builder):
+ return CreateStructInNestedNS(builder, self.a, self.b)
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
index 89217449..cdbf6f8f 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.cs
@@ -6,34 +6,60 @@ namespace NamespaceA.NamespaceB
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct TableInNestedNS : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb) { return GetRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public TableInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int Foo { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
public bool MutateFoo(int foo) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, foo); return true; } else { return false; } }
- public static Offset<TableInNestedNS> CreateTableInNestedNS(FlatBufferBuilder builder,
+ public static Offset<NamespaceA.NamespaceB.TableInNestedNS> CreateTableInNestedNS(FlatBufferBuilder builder,
int foo = 0) {
- builder.StartObject(1);
+ builder.StartTable(1);
TableInNestedNS.AddFoo(builder, foo);
return TableInNestedNS.EndTableInNestedNS(builder);
}
- public static void StartTableInNestedNS(FlatBufferBuilder builder) { builder.StartObject(1); }
+ public static void StartTableInNestedNS(FlatBufferBuilder builder) { builder.StartTable(1); }
public static void AddFoo(FlatBufferBuilder builder, int foo) { builder.AddInt(0, foo, 0); }
- public static Offset<TableInNestedNS> EndTableInNestedNS(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<TableInNestedNS>(o);
+ public static Offset<NamespaceA.NamespaceB.TableInNestedNS> EndTableInNestedNS(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<NamespaceA.NamespaceB.TableInNestedNS>(o);
+ }
+ public TableInNestedNST UnPack() {
+ var _o = new TableInNestedNST();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(TableInNestedNST _o) {
+ _o.Foo = this.Foo;
+ }
+ public static Offset<NamespaceA.NamespaceB.TableInNestedNS> Pack(FlatBufferBuilder builder, TableInNestedNST _o) {
+ if (_o == null) return default(Offset<NamespaceA.NamespaceB.TableInNestedNS>);
+ return CreateTableInNestedNS(
+ builder,
+ _o.Foo);
}
};
+public class TableInNestedNST
+{
+ [Newtonsoft.Json.JsonProperty("foo")]
+ public int Foo { get; set; }
+
+ public TableInNestedNST() {
+ this.Foo = 0;
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go
index 75f7a554..e719e90b 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.go
@@ -6,6 +6,28 @@ import (
flatbuffers "github.com/google/flatbuffers/go"
)
+type TableInNestedNST struct {
+ Foo int32
+}
+
+func (t *TableInNestedNST) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ TableInNestedNSStart(builder)
+ TableInNestedNSAddFoo(builder, t.Foo)
+ return TableInNestedNSEnd(builder)
+}
+
+func (rcv *TableInNestedNS) UnPackTo(t *TableInNestedNST) {
+ t.Foo = rcv.Foo()
+}
+
+func (rcv *TableInNestedNS) UnPack() *TableInNestedNST {
+ if rcv == nil { return nil }
+ t := &TableInNestedNST{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type TableInNestedNS struct {
_tab flatbuffers.Table
}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java
index f3216c1c..b0931b16 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.java
@@ -9,9 +9,10 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class TableInNestedNS extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb) { return getRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public TableInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int foo() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
@@ -19,16 +20,23 @@ public final class TableInNestedNS extends Table {
public static int createTableInNestedNS(FlatBufferBuilder builder,
int foo) {
- builder.startObject(1);
+ builder.startTable(1);
TableInNestedNS.addFoo(builder, foo);
return TableInNestedNS.endTableInNestedNS(builder);
}
- public static void startTableInNestedNS(FlatBufferBuilder builder) { builder.startObject(1); }
+ public static void startTableInNestedNS(FlatBufferBuilder builder) { builder.startTable(1); }
public static void addFoo(FlatBufferBuilder builder, int foo) { builder.addInt(0, foo, 0); }
public static int endTableInNestedNS(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public TableInNestedNS get(int j) { return get(new TableInNestedNS(), j); }
+ public TableInNestedNS get(TableInNestedNS obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt
new file mode 100644
index 00000000..0fb2e3cf
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.kt
@@ -0,0 +1,53 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA.NamespaceB
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInNestedNS : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : TableInNestedNS {
+ __init(_i, _bb)
+ return this
+ }
+ val foo : Int
+ get() {
+ val o = __offset(4)
+ return if(o != 0) bb.getInt(o + bb_pos) else 0
+ }
+ fun mutateFoo(foo: Int) : Boolean {
+ val o = __offset(4)
+ return if (o != 0) {
+ bb.putInt(o + bb_pos, foo)
+ true
+ } else {
+ false
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsTableInNestedNS(_bb: ByteBuffer): TableInNestedNS = getRootAsTableInNestedNS(_bb, TableInNestedNS())
+ fun getRootAsTableInNestedNS(_bb: ByteBuffer, obj: TableInNestedNS): TableInNestedNS {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createTableInNestedNS(builder: FlatBufferBuilder, foo: Int) : Int {
+ builder.startTable(1)
+ addFoo(builder, foo)
+ return endTableInNestedNS(builder)
+ }
+ fun startTableInNestedNS(builder: FlatBufferBuilder) = builder.startTable(1)
+ fun addFoo(builder: FlatBufferBuilder, foo: Int) = builder.addInt(0, foo, 0)
+ fun endTableInNestedNS(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py
index d6d16740..e86ba633 100644
--- a/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py
+++ b/tests/namespace_test/NamespaceA/NamespaceB/TableInNestedNS.py
@@ -3,6 +3,8 @@
# namespace: NamespaceB
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class TableInNestedNS(object):
__slots__ = ['_tab']
@@ -28,3 +30,35 @@ class TableInNestedNS(object):
def TableInNestedNSStart(builder): builder.StartObject(1)
def TableInNestedNSAddFoo(builder, foo): builder.PrependInt32Slot(0, foo, 0)
def TableInNestedNSEnd(builder): return builder.EndObject()
+
+
+class TableInNestedNST(object):
+
+ # TableInNestedNST
+ def __init__(self):
+ self.foo = 0 # type: int
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ tableInNestedNS = TableInNestedNS()
+ tableInNestedNS.Init(buf, pos)
+ return cls.InitFromObj(tableInNestedNS)
+
+ @classmethod
+ def InitFromObj(cls, tableInNestedNS):
+ x = TableInNestedNST()
+ x._UnPack(tableInNestedNS)
+ return x
+
+ # TableInNestedNST
+ def _UnPack(self, tableInNestedNS):
+ if tableInNestedNS is None:
+ return
+ self.foo = tableInNestedNS.Foo()
+
+ # TableInNestedNST
+ def Pack(self, builder):
+ TableInNestedNSStart(builder)
+ TableInNestedNSAddFoo(builder, self.foo)
+ tableInNestedNS = TableInNestedNSEnd(builder)
+ return tableInNestedNS
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.cs b/tests/namespace_test/NamespaceA/SecondTableInA.cs
index 99c82ccb..a949c616 100644
--- a/tests/namespace_test/NamespaceA/SecondTableInA.cs
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.cs
@@ -6,33 +6,60 @@ namespace NamespaceA
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct SecondTableInA : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb) { return GetRootAsSecondTableInA(_bb, new SecondTableInA()); }
public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public NamespaceC.TableInC? ReferToC { get { int o = __p.__offset(4); return o != 0 ? (NamespaceC.TableInC?)(new NamespaceC.TableInC()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
- public static Offset<SecondTableInA> CreateSecondTableInA(FlatBufferBuilder builder,
+ public static Offset<NamespaceA.SecondTableInA> CreateSecondTableInA(FlatBufferBuilder builder,
Offset<NamespaceC.TableInC> refer_to_cOffset = default(Offset<NamespaceC.TableInC>)) {
- builder.StartObject(1);
+ builder.StartTable(1);
SecondTableInA.AddReferToC(builder, refer_to_cOffset);
return SecondTableInA.EndSecondTableInA(builder);
}
- public static void StartSecondTableInA(FlatBufferBuilder builder) { builder.StartObject(1); }
+ public static void StartSecondTableInA(FlatBufferBuilder builder) { builder.StartTable(1); }
public static void AddReferToC(FlatBufferBuilder builder, Offset<NamespaceC.TableInC> referToCOffset) { builder.AddOffset(0, referToCOffset.Value, 0); }
- public static Offset<SecondTableInA> EndSecondTableInA(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<SecondTableInA>(o);
+ public static Offset<NamespaceA.SecondTableInA> EndSecondTableInA(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<NamespaceA.SecondTableInA>(o);
+ }
+ public SecondTableInAT UnPack() {
+ var _o = new SecondTableInAT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(SecondTableInAT _o) {
+ _o.ReferToC = this.ReferToC.HasValue ? this.ReferToC.Value.UnPack() : null;
+ }
+ public static Offset<NamespaceA.SecondTableInA> Pack(FlatBufferBuilder builder, SecondTableInAT _o) {
+ if (_o == null) return default(Offset<NamespaceA.SecondTableInA>);
+ var _refer_to_c = _o.ReferToC == null ? default(Offset<NamespaceC.TableInC>) : NamespaceC.TableInC.Pack(builder, _o.ReferToC);
+ return CreateSecondTableInA(
+ builder,
+ _refer_to_c);
}
};
+public class SecondTableInAT
+{
+ [Newtonsoft.Json.JsonProperty("refer_to_c")]
+ public NamespaceC.TableInCT ReferToC { get; set; }
+
+ public SecondTableInAT() {
+ this.ReferToC = null;
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.go b/tests/namespace_test/NamespaceA/SecondTableInA.go
index 6dd1eeff..b50c8b68 100644
--- a/tests/namespace_test/NamespaceA/SecondTableInA.go
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.go
@@ -8,6 +8,29 @@ import (
NamespaceC "NamespaceC"
)
+type SecondTableInAT struct {
+ ReferToC *NamespaceC.TableInCT
+}
+
+func (t *SecondTableInAT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ referToCOffset := t.ReferToC.Pack(builder)
+ SecondTableInAStart(builder)
+ SecondTableInAAddReferToC(builder, referToCOffset)
+ return SecondTableInAEnd(builder)
+}
+
+func (rcv *SecondTableInA) UnPackTo(t *SecondTableInAT) {
+ t.ReferToC = rcv.ReferToC(nil).UnPack()
+}
+
+func (rcv *SecondTableInA) UnPack() *SecondTableInAT {
+ if rcv == nil { return nil }
+ t := &SecondTableInAT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type SecondTableInA struct {
_tab flatbuffers.Table
}
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.java b/tests/namespace_test/NamespaceA/SecondTableInA.java
index 8386446a..ec6e5612 100644
--- a/tests/namespace_test/NamespaceA/SecondTableInA.java
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.java
@@ -9,9 +9,10 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class SecondTableInA extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb) { return getRootAsSecondTableInA(_bb, new SecondTableInA()); }
public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public NamespaceC.TableInC referToC() { return referToC(new NamespaceC.TableInC()); }
@@ -19,16 +20,23 @@ public final class SecondTableInA extends Table {
public static int createSecondTableInA(FlatBufferBuilder builder,
int refer_to_cOffset) {
- builder.startObject(1);
+ builder.startTable(1);
SecondTableInA.addReferToC(builder, refer_to_cOffset);
return SecondTableInA.endSecondTableInA(builder);
}
- public static void startSecondTableInA(FlatBufferBuilder builder) { builder.startObject(1); }
+ public static void startSecondTableInA(FlatBufferBuilder builder) { builder.startTable(1); }
public static void addReferToC(FlatBufferBuilder builder, int referToCOffset) { builder.addOffset(0, referToCOffset, 0); }
public static int endSecondTableInA(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public SecondTableInA get(int j) { return get(new SecondTableInA(), j); }
+ public SecondTableInA get(SecondTableInA obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.kt b/tests/namespace_test/NamespaceA/SecondTableInA.kt
new file mode 100644
index 00000000..5b41f730
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.kt
@@ -0,0 +1,48 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class SecondTableInA : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : SecondTableInA {
+ __init(_i, _bb)
+ return this
+ }
+ val referToC : NamespaceC.TableInC? get() = referToC(NamespaceC.TableInC())
+ fun referToC(obj: NamespaceC.TableInC) : NamespaceC.TableInC? {
+ val o = __offset(4)
+ return if (o != 0) {
+ obj.__assign(__indirect(o + bb_pos), bb)
+ } else {
+ null
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsSecondTableInA(_bb: ByteBuffer): SecondTableInA = getRootAsSecondTableInA(_bb, SecondTableInA())
+ fun getRootAsSecondTableInA(_bb: ByteBuffer, obj: SecondTableInA): SecondTableInA {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createSecondTableInA(builder: FlatBufferBuilder, referToCOffset: Int) : Int {
+ builder.startTable(1)
+ addReferToC(builder, referToCOffset)
+ return endSecondTableInA(builder)
+ }
+ fun startSecondTableInA(builder: FlatBufferBuilder) = builder.startTable(1)
+ fun addReferToC(builder: FlatBufferBuilder, referToC: Int) = builder.addOffset(0, referToC, 0)
+ fun endSecondTableInA(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/namespace_test/NamespaceA/SecondTableInA.py b/tests/namespace_test/NamespaceA/SecondTableInA.py
index 20dac3e2..5aaa8edc 100644
--- a/tests/namespace_test/NamespaceA/SecondTableInA.py
+++ b/tests/namespace_test/NamespaceA/SecondTableInA.py
@@ -3,6 +3,8 @@
# namespace: NamespaceA
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class SecondTableInA(object):
__slots__ = ['_tab']
@@ -23,7 +25,6 @@ class SecondTableInA(object):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
- from .TableInC import TableInC
obj = TableInC()
obj.Init(self._tab.Bytes, x)
return obj
@@ -32,3 +33,43 @@ class SecondTableInA(object):
def SecondTableInAStart(builder): builder.StartObject(1)
def SecondTableInAAddReferToC(builder, referToC): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(referToC), 0)
def SecondTableInAEnd(builder): return builder.EndObject()
+
+try:
+ from typing import Optional
+except:
+ pass
+
+class SecondTableInAT(object):
+
+ # SecondTableInAT
+ def __init__(self):
+ self.referToC = None # type: Optional[TableInCT]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ secondTableInA = SecondTableInA()
+ secondTableInA.Init(buf, pos)
+ return cls.InitFromObj(secondTableInA)
+
+ @classmethod
+ def InitFromObj(cls, secondTableInA):
+ x = SecondTableInAT()
+ x._UnPack(secondTableInA)
+ return x
+
+ # SecondTableInAT
+ def _UnPack(self, secondTableInA):
+ if secondTableInA is None:
+ return
+ if secondTableInA.ReferToC() is not None:
+ self.referToC = TableInCT.InitFromObj(secondTableInA.ReferToC())
+
+ # SecondTableInAT
+ def Pack(self, builder):
+ if self.referToC is not None:
+ referToC = self.referToC.Pack(builder)
+ SecondTableInAStart(builder)
+ if self.referToC is not None:
+ SecondTableInAAddReferToC(builder, referToC)
+ secondTableInA = SecondTableInAEnd(builder)
+ return secondTableInA
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.cs b/tests/namespace_test/NamespaceA/TableInFirstNS.cs
index 48b5b205..9c7be472 100644
--- a/tests/namespace_test/NamespaceA/TableInFirstNS.cs
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.cs
@@ -6,15 +6,17 @@ namespace NamespaceA
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct TableInFirstNS : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb) { return GetRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public NamespaceA.NamespaceB.TableInNestedNS? FooTable { get { int o = __p.__offset(4); return o != 0 ? (NamespaceA.NamespaceB.TableInNestedNS?)(new NamespaceA.NamespaceB.TableInNestedNS()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
@@ -22,15 +24,50 @@ public struct TableInFirstNS : IFlatbufferObject
public bool MutateFooEnum(NamespaceA.NamespaceB.EnumInNestedNS foo_enum) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)foo_enum); return true; } else { return false; } }
public NamespaceA.NamespaceB.StructInNestedNS? FooStruct { get { int o = __p.__offset(8); return o != 0 ? (NamespaceA.NamespaceB.StructInNestedNS?)(new NamespaceA.NamespaceB.StructInNestedNS()).__assign(o + __p.bb_pos, __p.bb) : null; } }
- public static void StartTableInFirstNS(FlatBufferBuilder builder) { builder.StartObject(3); }
+ public static void StartTableInFirstNS(FlatBufferBuilder builder) { builder.StartTable(3); }
public static void AddFooTable(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.TableInNestedNS> fooTableOffset) { builder.AddOffset(0, fooTableOffset.Value, 0); }
public static void AddFooEnum(FlatBufferBuilder builder, NamespaceA.NamespaceB.EnumInNestedNS fooEnum) { builder.AddSbyte(1, (sbyte)fooEnum, 0); }
public static void AddFooStruct(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.StructInNestedNS> fooStructOffset) { builder.AddStruct(2, fooStructOffset.Value, 0); }
- public static Offset<TableInFirstNS> EndTableInFirstNS(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<TableInFirstNS>(o);
+ public static Offset<NamespaceA.TableInFirstNS> EndTableInFirstNS(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<NamespaceA.TableInFirstNS>(o);
+ }
+ public TableInFirstNST UnPack() {
+ var _o = new TableInFirstNST();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(TableInFirstNST _o) {
+ _o.FooTable = this.FooTable.HasValue ? this.FooTable.Value.UnPack() : null;
+ _o.FooEnum = this.FooEnum;
+ _o.FooStruct = this.FooStruct.HasValue ? this.FooStruct.Value.UnPack() : null;
+ }
+ public static Offset<NamespaceA.TableInFirstNS> Pack(FlatBufferBuilder builder, TableInFirstNST _o) {
+ if (_o == null) return default(Offset<NamespaceA.TableInFirstNS>);
+ var _foo_table = _o.FooTable == null ? default(Offset<NamespaceA.NamespaceB.TableInNestedNS>) : NamespaceA.NamespaceB.TableInNestedNS.Pack(builder, _o.FooTable);
+ StartTableInFirstNS(builder);
+ AddFooTable(builder, _foo_table);
+ AddFooEnum(builder, _o.FooEnum);
+ AddFooStruct(builder, NamespaceA.NamespaceB.StructInNestedNS.Pack(builder, _o.FooStruct));
+ return EndTableInFirstNS(builder);
}
};
+public class TableInFirstNST
+{
+ [Newtonsoft.Json.JsonProperty("foo_table")]
+ public NamespaceA.NamespaceB.TableInNestedNST FooTable { get; set; }
+ [Newtonsoft.Json.JsonProperty("foo_enum")]
+ public NamespaceA.NamespaceB.EnumInNestedNS FooEnum { get; set; }
+ [Newtonsoft.Json.JsonProperty("foo_struct")]
+ public NamespaceA.NamespaceB.StructInNestedNST FooStruct { get; set; }
+
+ public TableInFirstNST() {
+ this.FooTable = null;
+ this.FooEnum = NamespaceA.NamespaceB.EnumInNestedNS.A;
+ this.FooStruct = new NamespaceA.NamespaceB.StructInNestedNST();
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.go b/tests/namespace_test/NamespaceA/TableInFirstNS.go
index 877e2d44..781198e5 100644
--- a/tests/namespace_test/NamespaceA/TableInFirstNS.go
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.go
@@ -8,6 +8,36 @@ import (
NamespaceA__NamespaceB "NamespaceA/NamespaceB"
)
+type TableInFirstNST struct {
+ FooTable *NamespaceA__NamespaceB.TableInNestedNST
+ FooEnum NamespaceA__NamespaceB.EnumInNestedNS
+ FooStruct *NamespaceA__NamespaceB.StructInNestedNST
+}
+
+func (t *TableInFirstNST) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ fooTableOffset := t.FooTable.Pack(builder)
+ TableInFirstNSStart(builder)
+ TableInFirstNSAddFooTable(builder, fooTableOffset)
+ TableInFirstNSAddFooEnum(builder, t.FooEnum)
+ fooStructOffset := t.FooStruct.Pack(builder)
+ TableInFirstNSAddFooStruct(builder, fooStructOffset)
+ return TableInFirstNSEnd(builder)
+}
+
+func (rcv *TableInFirstNS) UnPackTo(t *TableInFirstNST) {
+ t.FooTable = rcv.FooTable(nil).UnPack()
+ t.FooEnum = rcv.FooEnum()
+ t.FooStruct = rcv.FooStruct(nil).UnPack()
+}
+
+func (rcv *TableInFirstNS) UnPack() *TableInFirstNST {
+ if rcv == nil { return nil }
+ t := &TableInFirstNST{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type TableInFirstNS struct {
_tab flatbuffers.Table
}
@@ -41,16 +71,16 @@ func (rcv *TableInFirstNS) FooTable(obj *NamespaceA__NamespaceB.TableInNestedNS)
return nil
}
-func (rcv *TableInFirstNS) FooEnum() EnumInNestedNS {
+func (rcv *TableInFirstNS) FooEnum() NamespaceA__NamespaceB.EnumInNestedNS {
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
if o != 0 {
- return rcv._tab.GetInt8(o + rcv._tab.Pos)
+ return NamespaceA__NamespaceB.EnumInNestedNS(rcv._tab.GetInt8(o + rcv._tab.Pos))
}
return 0
}
-func (rcv *TableInFirstNS) MutateFooEnum(n EnumInNestedNS) bool {
- return rcv._tab.MutateInt8Slot(6, n)
+func (rcv *TableInFirstNS) MutateFooEnum(n NamespaceA__NamespaceB.EnumInNestedNS) bool {
+ return rcv._tab.MutateInt8Slot(6, int8(n))
}
func (rcv *TableInFirstNS) FooStruct(obj *NamespaceA__NamespaceB.StructInNestedNS) *NamespaceA__NamespaceB.StructInNestedNS {
@@ -72,8 +102,8 @@ func TableInFirstNSStart(builder *flatbuffers.Builder) {
func TableInFirstNSAddFooTable(builder *flatbuffers.Builder, fooTable flatbuffers.UOffsetT) {
builder.PrependUOffsetTSlot(0, flatbuffers.UOffsetT(fooTable), 0)
}
-func TableInFirstNSAddFooEnum(builder *flatbuffers.Builder, fooEnum int8) {
- builder.PrependInt8Slot(1, fooEnum, 0)
+func TableInFirstNSAddFooEnum(builder *flatbuffers.Builder, fooEnum NamespaceA__NamespaceB.EnumInNestedNS) {
+ builder.PrependInt8Slot(1, int8(fooEnum), 0)
}
func TableInFirstNSAddFooStruct(builder *flatbuffers.Builder, fooStruct flatbuffers.UOffsetT) {
builder.PrependStructSlot(2, flatbuffers.UOffsetT(fooStruct), 0)
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.java b/tests/namespace_test/NamespaceA/TableInFirstNS.java
index 396d0b47..f04d9e91 100644
--- a/tests/namespace_test/NamespaceA/TableInFirstNS.java
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.java
@@ -9,9 +9,10 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class TableInFirstNS extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb) { return getRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public NamespaceA.NamespaceB.TableInNestedNS fooTable() { return fooTable(new NamespaceA.NamespaceB.TableInNestedNS()); }
@@ -21,13 +22,20 @@ public final class TableInFirstNS extends Table {
public NamespaceA.NamespaceB.StructInNestedNS fooStruct() { return fooStruct(new NamespaceA.NamespaceB.StructInNestedNS()); }
public NamespaceA.NamespaceB.StructInNestedNS fooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
- public static void startTableInFirstNS(FlatBufferBuilder builder) { builder.startObject(3); }
+ public static void startTableInFirstNS(FlatBufferBuilder builder) { builder.startTable(3); }
public static void addFooTable(FlatBufferBuilder builder, int fooTableOffset) { builder.addOffset(0, fooTableOffset, 0); }
public static void addFooEnum(FlatBufferBuilder builder, byte fooEnum) { builder.addByte(1, fooEnum, 0); }
public static void addFooStruct(FlatBufferBuilder builder, int fooStructOffset) { builder.addStruct(2, fooStructOffset, 0); }
public static int endTableInFirstNS(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public TableInFirstNS get(int j) { return get(new TableInFirstNS(), j); }
+ public TableInFirstNS get(TableInFirstNS obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.kt b/tests/namespace_test/NamespaceA/TableInFirstNS.kt
new file mode 100644
index 00000000..febe050c
--- /dev/null
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.kt
@@ -0,0 +1,68 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceA
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInFirstNS : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : TableInFirstNS {
+ __init(_i, _bb)
+ return this
+ }
+ val fooTable : NamespaceA.NamespaceB.TableInNestedNS? get() = fooTable(NamespaceA.NamespaceB.TableInNestedNS())
+ fun fooTable(obj: NamespaceA.NamespaceB.TableInNestedNS) : NamespaceA.NamespaceB.TableInNestedNS? {
+ val o = __offset(4)
+ return if (o != 0) {
+ obj.__assign(__indirect(o + bb_pos), bb)
+ } else {
+ null
+ }
+ }
+ val fooEnum : Byte
+ get() {
+ val o = __offset(6)
+ return if(o != 0) bb.get(o + bb_pos) else 0
+ }
+ fun mutateFooEnum(fooEnum: Byte) : Boolean {
+ val o = __offset(6)
+ return if (o != 0) {
+ bb.put(o + bb_pos, fooEnum)
+ true
+ } else {
+ false
+ }
+ }
+ val fooStruct : NamespaceA.NamespaceB.StructInNestedNS? get() = fooStruct(NamespaceA.NamespaceB.StructInNestedNS())
+ fun fooStruct(obj: NamespaceA.NamespaceB.StructInNestedNS) : NamespaceA.NamespaceB.StructInNestedNS? {
+ val o = __offset(8)
+ return if (o != 0) {
+ obj.__assign(o + bb_pos, bb)
+ } else {
+ null
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsTableInFirstNS(_bb: ByteBuffer): TableInFirstNS = getRootAsTableInFirstNS(_bb, TableInFirstNS())
+ fun getRootAsTableInFirstNS(_bb: ByteBuffer, obj: TableInFirstNS): TableInFirstNS {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun startTableInFirstNS(builder: FlatBufferBuilder) = builder.startTable(3)
+ fun addFooTable(builder: FlatBufferBuilder, fooTable: Int) = builder.addOffset(0, fooTable, 0)
+ fun addFooEnum(builder: FlatBufferBuilder, fooEnum: Byte) = builder.addByte(1, fooEnum, 0)
+ fun addFooStruct(builder: FlatBufferBuilder, fooStruct: Int) = builder.addStruct(2, fooStruct, 0)
+ fun endTableInFirstNS(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/namespace_test/NamespaceA/TableInFirstNS.py b/tests/namespace_test/NamespaceA/TableInFirstNS.py
index 40cbeba0..39598f5a 100644
--- a/tests/namespace_test/NamespaceA/TableInFirstNS.py
+++ b/tests/namespace_test/NamespaceA/TableInFirstNS.py
@@ -3,6 +3,8 @@
# namespace: NamespaceA
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class TableInFirstNS(object):
__slots__ = ['_tab']
@@ -23,7 +25,6 @@ class TableInFirstNS(object):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
- from .TableInNestedNS import TableInNestedNS
obj = TableInNestedNS()
obj.Init(self._tab.Bytes, x)
return obj
@@ -41,7 +42,6 @@ class TableInFirstNS(object):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(8))
if o != 0:
x = o + self._tab.Pos
- from .StructInNestedNS import StructInNestedNS
obj = StructInNestedNS()
obj.Init(self._tab.Bytes, x)
return obj
@@ -52,3 +52,52 @@ def TableInFirstNSAddFooTable(builder, fooTable): builder.PrependUOffsetTRelativ
def TableInFirstNSAddFooEnum(builder, fooEnum): builder.PrependInt8Slot(1, fooEnum, 0)
def TableInFirstNSAddFooStruct(builder, fooStruct): builder.PrependStructSlot(2, flatbuffers.number_types.UOffsetTFlags.py_type(fooStruct), 0)
def TableInFirstNSEnd(builder): return builder.EndObject()
+
+try:
+ from typing import Optional
+except:
+ pass
+
+class TableInFirstNST(object):
+
+ # TableInFirstNST
+ def __init__(self):
+ self.fooTable = None # type: Optional[TableInNestedNST]
+ self.fooEnum = 0 # type: int
+ self.fooStruct = None # type: Optional[StructInNestedNST]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ tableInFirstNS = TableInFirstNS()
+ tableInFirstNS.Init(buf, pos)
+ return cls.InitFromObj(tableInFirstNS)
+
+ @classmethod
+ def InitFromObj(cls, tableInFirstNS):
+ x = TableInFirstNST()
+ x._UnPack(tableInFirstNS)
+ return x
+
+ # TableInFirstNST
+ def _UnPack(self, tableInFirstNS):
+ if tableInFirstNS is None:
+ return
+ if tableInFirstNS.FooTable() is not None:
+ self.fooTable = TableInNestedNST.InitFromObj(tableInFirstNS.FooTable())
+ self.fooEnum = tableInFirstNS.FooEnum()
+ if tableInFirstNS.FooStruct() is not None:
+ self.fooStruct = StructInNestedNST.InitFromObj(tableInFirstNS.FooStruct())
+
+ # TableInFirstNST
+ def Pack(self, builder):
+ if self.fooTable is not None:
+ fooTable = self.fooTable.Pack(builder)
+ TableInFirstNSStart(builder)
+ if self.fooTable is not None:
+ TableInFirstNSAddFooTable(builder, fooTable)
+ TableInFirstNSAddFooEnum(builder, self.fooEnum)
+ if self.fooStruct is not None:
+ fooStruct = self.fooStruct.Pack(builder)
+ TableInFirstNSAddFooStruct(builder, fooStruct)
+ tableInFirstNS = TableInFirstNSEnd(builder)
+ return tableInFirstNS
diff --git a/tests/namespace_test/NamespaceC/TableInC.cs b/tests/namespace_test/NamespaceC/TableInC.cs
index 0c454acb..bfb9b76c 100644
--- a/tests/namespace_test/NamespaceC/TableInC.cs
+++ b/tests/namespace_test/NamespaceC/TableInC.cs
@@ -6,37 +6,70 @@ namespace NamespaceC
{
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct TableInC : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static TableInC GetRootAsTableInC(ByteBuffer _bb) { return GetRootAsTableInC(_bb, new TableInC()); }
public static TableInC GetRootAsTableInC(ByteBuffer _bb, TableInC obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public TableInC __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public NamespaceA.TableInFirstNS? ReferToA1 { get { int o = __p.__offset(4); return o != 0 ? (NamespaceA.TableInFirstNS?)(new NamespaceA.TableInFirstNS()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public NamespaceA.SecondTableInA? ReferToA2 { get { int o = __p.__offset(6); return o != 0 ? (NamespaceA.SecondTableInA?)(new NamespaceA.SecondTableInA()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
- public static Offset<TableInC> CreateTableInC(FlatBufferBuilder builder,
+ public static Offset<NamespaceC.TableInC> CreateTableInC(FlatBufferBuilder builder,
Offset<NamespaceA.TableInFirstNS> refer_to_a1Offset = default(Offset<NamespaceA.TableInFirstNS>),
Offset<NamespaceA.SecondTableInA> refer_to_a2Offset = default(Offset<NamespaceA.SecondTableInA>)) {
- builder.StartObject(2);
+ builder.StartTable(2);
TableInC.AddReferToA2(builder, refer_to_a2Offset);
TableInC.AddReferToA1(builder, refer_to_a1Offset);
return TableInC.EndTableInC(builder);
}
- public static void StartTableInC(FlatBufferBuilder builder) { builder.StartObject(2); }
+ public static void StartTableInC(FlatBufferBuilder builder) { builder.StartTable(2); }
public static void AddReferToA1(FlatBufferBuilder builder, Offset<NamespaceA.TableInFirstNS> referToA1Offset) { builder.AddOffset(0, referToA1Offset.Value, 0); }
public static void AddReferToA2(FlatBufferBuilder builder, Offset<NamespaceA.SecondTableInA> referToA2Offset) { builder.AddOffset(1, referToA2Offset.Value, 0); }
- public static Offset<TableInC> EndTableInC(FlatBufferBuilder builder) {
- int o = builder.EndObject();
- return new Offset<TableInC>(o);
+ public static Offset<NamespaceC.TableInC> EndTableInC(FlatBufferBuilder builder) {
+ int o = builder.EndTable();
+ return new Offset<NamespaceC.TableInC>(o);
+ }
+ public TableInCT UnPack() {
+ var _o = new TableInCT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(TableInCT _o) {
+ _o.ReferToA1 = this.ReferToA1.HasValue ? this.ReferToA1.Value.UnPack() : null;
+ _o.ReferToA2 = this.ReferToA2.HasValue ? this.ReferToA2.Value.UnPack() : null;
+ }
+ public static Offset<NamespaceC.TableInC> Pack(FlatBufferBuilder builder, TableInCT _o) {
+ if (_o == null) return default(Offset<NamespaceC.TableInC>);
+ var _refer_to_a1 = _o.ReferToA1 == null ? default(Offset<NamespaceA.TableInFirstNS>) : NamespaceA.TableInFirstNS.Pack(builder, _o.ReferToA1);
+ var _refer_to_a2 = _o.ReferToA2 == null ? default(Offset<NamespaceA.SecondTableInA>) : NamespaceA.SecondTableInA.Pack(builder, _o.ReferToA2);
+ return CreateTableInC(
+ builder,
+ _refer_to_a1,
+ _refer_to_a2);
}
};
+public class TableInCT
+{
+ [Newtonsoft.Json.JsonProperty("refer_to_a1")]
+ public NamespaceA.TableInFirstNST ReferToA1 { get; set; }
+ [Newtonsoft.Json.JsonProperty("refer_to_a2")]
+ public NamespaceA.SecondTableInAT ReferToA2 { get; set; }
+
+ public TableInCT() {
+ this.ReferToA1 = null;
+ this.ReferToA2 = null;
+ }
+}
+
}
diff --git a/tests/namespace_test/NamespaceC/TableInC.go b/tests/namespace_test/NamespaceC/TableInC.go
index 59b3e484..88444a32 100644
--- a/tests/namespace_test/NamespaceC/TableInC.go
+++ b/tests/namespace_test/NamespaceC/TableInC.go
@@ -8,6 +8,33 @@ import (
NamespaceA "NamespaceA"
)
+type TableInCT struct {
+ ReferToA1 *NamespaceA.TableInFirstNST
+ ReferToA2 *NamespaceA.SecondTableInAT
+}
+
+func (t *TableInCT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+ if t == nil { return 0 }
+ referToA1Offset := t.ReferToA1.Pack(builder)
+ referToA2Offset := t.ReferToA2.Pack(builder)
+ TableInCStart(builder)
+ TableInCAddReferToA1(builder, referToA1Offset)
+ TableInCAddReferToA2(builder, referToA2Offset)
+ return TableInCEnd(builder)
+}
+
+func (rcv *TableInC) UnPackTo(t *TableInCT) {
+ t.ReferToA1 = rcv.ReferToA1(nil).UnPack()
+ t.ReferToA2 = rcv.ReferToA2(nil).UnPack()
+}
+
+func (rcv *TableInC) UnPack() *TableInCT {
+ if rcv == nil { return nil }
+ t := &TableInCT{}
+ rcv.UnPackTo(t)
+ return t
+}
+
type TableInC struct {
_tab flatbuffers.Table
}
diff --git a/tests/namespace_test/NamespaceC/TableInC.java b/tests/namespace_test/NamespaceC/TableInC.java
index 80d6a123..503f2379 100644
--- a/tests/namespace_test/NamespaceC/TableInC.java
+++ b/tests/namespace_test/NamespaceC/TableInC.java
@@ -9,9 +9,10 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class TableInC extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static TableInC getRootAsTableInC(ByteBuffer _bb) { return getRootAsTableInC(_bb, new TableInC()); }
public static TableInC getRootAsTableInC(ByteBuffer _bb, TableInC obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public TableInC __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public NamespaceA.TableInFirstNS referToA1() { return referToA1(new NamespaceA.TableInFirstNS()); }
@@ -22,18 +23,25 @@ public final class TableInC extends Table {
public static int createTableInC(FlatBufferBuilder builder,
int refer_to_a1Offset,
int refer_to_a2Offset) {
- builder.startObject(2);
+ builder.startTable(2);
TableInC.addReferToA2(builder, refer_to_a2Offset);
TableInC.addReferToA1(builder, refer_to_a1Offset);
return TableInC.endTableInC(builder);
}
- public static void startTableInC(FlatBufferBuilder builder) { builder.startObject(2); }
+ public static void startTableInC(FlatBufferBuilder builder) { builder.startTable(2); }
public static void addReferToA1(FlatBufferBuilder builder, int referToA1Offset) { builder.addOffset(0, referToA1Offset, 0); }
public static void addReferToA2(FlatBufferBuilder builder, int referToA2Offset) { builder.addOffset(1, referToA2Offset, 0); }
public static int endTableInC(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public TableInC get(int j) { return get(new TableInC(), j); }
+ public TableInC get(TableInC obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/namespace_test/NamespaceC/TableInC.kt b/tests/namespace_test/NamespaceC/TableInC.kt
new file mode 100644
index 00000000..a5222f19
--- /dev/null
+++ b/tests/namespace_test/NamespaceC/TableInC.kt
@@ -0,0 +1,59 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+package NamespaceC
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class TableInC : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : TableInC {
+ __init(_i, _bb)
+ return this
+ }
+ val referToA1 : NamespaceA.TableInFirstNS? get() = referToA1(NamespaceA.TableInFirstNS())
+ fun referToA1(obj: NamespaceA.TableInFirstNS) : NamespaceA.TableInFirstNS? {
+ val o = __offset(4)
+ return if (o != 0) {
+ obj.__assign(__indirect(o + bb_pos), bb)
+ } else {
+ null
+ }
+ }
+ val referToA2 : NamespaceA.SecondTableInA? get() = referToA2(NamespaceA.SecondTableInA())
+ fun referToA2(obj: NamespaceA.SecondTableInA) : NamespaceA.SecondTableInA? {
+ val o = __offset(6)
+ return if (o != 0) {
+ obj.__assign(__indirect(o + bb_pos), bb)
+ } else {
+ null
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsTableInC(_bb: ByteBuffer): TableInC = getRootAsTableInC(_bb, TableInC())
+ fun getRootAsTableInC(_bb: ByteBuffer, obj: TableInC): TableInC {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createTableInC(builder: FlatBufferBuilder, referToA1Offset: Int, referToA2Offset: Int) : Int {
+ builder.startTable(2)
+ addReferToA2(builder, referToA2Offset)
+ addReferToA1(builder, referToA1Offset)
+ return endTableInC(builder)
+ }
+ fun startTableInC(builder: FlatBufferBuilder) = builder.startTable(2)
+ fun addReferToA1(builder: FlatBufferBuilder, referToA1: Int) = builder.addOffset(0, referToA1, 0)
+ fun addReferToA2(builder: FlatBufferBuilder, referToA2: Int) = builder.addOffset(1, referToA2, 0)
+ fun endTableInC(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/namespace_test/NamespaceC/TableInC.py b/tests/namespace_test/NamespaceC/TableInC.py
index 90b8736c..8f04b52b 100644
--- a/tests/namespace_test/NamespaceC/TableInC.py
+++ b/tests/namespace_test/NamespaceC/TableInC.py
@@ -3,6 +3,8 @@
# namespace: NamespaceC
import flatbuffers
+from flatbuffers.compat import import_numpy
+np = import_numpy()
class TableInC(object):
__slots__ = ['_tab']
@@ -23,7 +25,6 @@ class TableInC(object):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
- from .TableInFirstNS import TableInFirstNS
obj = TableInFirstNS()
obj.Init(self._tab.Bytes, x)
return obj
@@ -34,7 +35,6 @@ class TableInC(object):
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
if o != 0:
x = self._tab.Indirect(o + self._tab.Pos)
- from .SecondTableInA import SecondTableInA
obj = SecondTableInA()
obj.Init(self._tab.Bytes, x)
return obj
@@ -44,3 +44,50 @@ def TableInCStart(builder): builder.StartObject(2)
def TableInCAddReferToA1(builder, referToA1): builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(referToA1), 0)
def TableInCAddReferToA2(builder, referToA2): builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(referToA2), 0)
def TableInCEnd(builder): return builder.EndObject()
+
+try:
+ from typing import Optional
+except:
+ pass
+
+class TableInCT(object):
+
+ # TableInCT
+ def __init__(self):
+ self.referToA1 = None # type: Optional[TableInFirstNST]
+ self.referToA2 = None # type: Optional[SecondTableInAT]
+
+ @classmethod
+ def InitFromBuf(cls, buf, pos):
+ tableInC = TableInC()
+ tableInC.Init(buf, pos)
+ return cls.InitFromObj(tableInC)
+
+ @classmethod
+ def InitFromObj(cls, tableInC):
+ x = TableInCT()
+ x._UnPack(tableInC)
+ return x
+
+ # TableInCT
+ def _UnPack(self, tableInC):
+ if tableInC is None:
+ return
+ if tableInC.ReferToA1() is not None:
+ self.referToA1 = TableInFirstNST.InitFromObj(tableInC.ReferToA1())
+ if tableInC.ReferToA2() is not None:
+ self.referToA2 = SecondTableInAT.InitFromObj(tableInC.ReferToA2())
+
+ # TableInCT
+ def Pack(self, builder):
+ if self.referToA1 is not None:
+ referToA1 = self.referToA1.Pack(builder)
+ if self.referToA2 is not None:
+ referToA2 = self.referToA2.Pack(builder)
+ TableInCStart(builder)
+ if self.referToA1 is not None:
+ TableInCAddReferToA1(builder, referToA1)
+ if self.referToA2 is not None:
+ TableInCAddReferToA2(builder, referToA2)
+ tableInC = TableInCEnd(builder)
+ return tableInC
diff --git a/tests/namespace_test/namespace_test1_generated.h b/tests/namespace_test/namespace_test1_generated.h
index 239e6e4b..feae671a 100644
--- a/tests/namespace_test/namespace_test1_generated.h
+++ b/tests/namespace_test/namespace_test1_generated.h
@@ -10,9 +10,16 @@ namespace NamespaceA {
namespace NamespaceB {
struct TableInNestedNS;
+struct TableInNestedNSBuilder;
+struct TableInNestedNST;
struct StructInNestedNS;
+bool operator==(const TableInNestedNST &lhs, const TableInNestedNST &rhs);
+bool operator!=(const TableInNestedNST &lhs, const TableInNestedNST &rhs);
+bool operator==(const StructInNestedNS &lhs, const StructInNestedNS &rhs);
+bool operator!=(const StructInNestedNS &lhs, const StructInNestedNS &rhs);
+
inline const flatbuffers::TypeTable *TableInNestedNSTypeTable();
inline const flatbuffers::TypeTable *StructInNestedNSTypeTable();
@@ -35,7 +42,7 @@ inline const EnumInNestedNS (&EnumValuesEnumInNestedNS())[3] {
}
inline const char * const *EnumNamesEnumInNestedNS() {
- static const char * const names[] = {
+ static const char * const names[4] = {
"A",
"B",
"C",
@@ -45,7 +52,7 @@ inline const char * const *EnumNamesEnumInNestedNS() {
}
inline const char *EnumNameEnumInNestedNS(EnumInNestedNS e) {
- if (e < EnumInNestedNS_A || e > EnumInNestedNS_C) return "";
+ if (flatbuffers::IsOutRange(e, EnumInNestedNS_A, EnumInNestedNS_C)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesEnumInNestedNS()[index];
}
@@ -81,7 +88,38 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) StructInNestedNS FLATBUFFERS_FINAL_CLASS
};
FLATBUFFERS_STRUCT_END(StructInNestedNS, 8);
+inline bool operator==(const StructInNestedNS &lhs, const StructInNestedNS &rhs) {
+ return
+ (lhs.a() == rhs.a()) &&
+ (lhs.b() == rhs.b());
+}
+
+inline bool operator!=(const StructInNestedNS &lhs, const StructInNestedNS &rhs) {
+ return !(lhs == rhs);
+}
+
+
+struct TableInNestedNST : public flatbuffers::NativeTable {
+ typedef TableInNestedNS TableType;
+ int32_t foo;
+ TableInNestedNST()
+ : foo(0) {
+ }
+};
+
+inline bool operator==(const TableInNestedNST &lhs, const TableInNestedNST &rhs) {
+ return
+ (lhs.foo == rhs.foo);
+}
+
+inline bool operator!=(const TableInNestedNST &lhs, const TableInNestedNST &rhs) {
+ return !(lhs == rhs);
+}
+
+
struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef TableInNestedNST NativeTableType;
+ typedef TableInNestedNSBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TableInNestedNSTypeTable();
}
@@ -99,9 +137,13 @@ struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<int32_t>(verifier, VT_FOO) &&
verifier.EndTable();
}
+ TableInNestedNST *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(TableInNestedNST *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<TableInNestedNS> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TableInNestedNST* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct TableInNestedNSBuilder {
+ typedef TableInNestedNS Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_foo(int32_t foo) {
@@ -127,6 +169,34 @@ inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(
return builder_.Finish();
}
+flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(flatbuffers::FlatBufferBuilder &_fbb, const TableInNestedNST *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline TableInNestedNST *TableInNestedNS::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ flatbuffers::unique_ptr<NamespaceA::NamespaceB::TableInNestedNST> _o = flatbuffers::unique_ptr<NamespaceA::NamespaceB::TableInNestedNST>(new TableInNestedNST());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void TableInNestedNS::UnPackTo(TableInNestedNST *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = foo(); _o->foo = _e; }
+}
+
+inline flatbuffers::Offset<TableInNestedNS> TableInNestedNS::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TableInNestedNST* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateTableInNestedNS(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(flatbuffers::FlatBufferBuilder &_fbb, const TableInNestedNST *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TableInNestedNST* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _foo = _o->foo;
+ return NamespaceA::NamespaceB::CreateTableInNestedNS(
+ _fbb,
+ _foo);
+}
+
inline const flatbuffers::TypeTable *EnumInNestedNSTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
{ flatbuffers::ET_CHAR, 0, 0 },
@@ -134,7 +204,7 @@ inline const flatbuffers::TypeTable *EnumInNestedNSTypeTable() {
{ flatbuffers::ET_CHAR, 0, 0 }
};
static const flatbuffers::TypeFunction type_refs[] = {
- EnumInNestedNSTypeTable
+ NamespaceA::NamespaceB::EnumInNestedNSTypeTable
};
static const char * const names[] = {
"A",
diff --git a/tests/namespace_test/namespace_test1_generated.js b/tests/namespace_test/namespace_test1_generated.js
index 3eaaacec..256dce7d 100644
--- a/tests/namespace_test/namespace_test1_generated.js
+++ b/tests/namespace_test/namespace_test1_generated.js
@@ -25,9 +25,9 @@ NamespaceA.NamespaceB.EnumInNestedNS = {
* @enum {string}
*/
NamespaceA.NamespaceB.EnumInNestedNSName = {
- 0: 'A',
- 1: 'B',
- 2: 'C'
+ '0': 'A',
+ '1': 'B',
+ '2': 'C'
};
/**
@@ -66,6 +66,16 @@ NamespaceA.NamespaceB.TableInNestedNS.getRootAsTableInNestedNS = function(bb, ob
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
+ * @returns {NamespaceA.NamespaceB.TableInNestedNS}
+ */
+NamespaceA.NamespaceB.TableInNestedNS.getSizePrefixedRootAsTableInNestedNS = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new NamespaceA.NamespaceB.TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @returns {number}
*/
NamespaceA.NamespaceB.TableInNestedNS.prototype.foo = function() {
diff --git a/tests/namespace_test/namespace_test1_generated.lobster b/tests/namespace_test/namespace_test1_generated.lobster
index 7c1924f4..65030059 100644
--- a/tests/namespace_test/namespace_test1_generated.lobster
+++ b/tests/namespace_test/namespace_test1_generated.lobster
@@ -1,36 +1,39 @@
// automatically generated by the FlatBuffers compiler, do not modify
-
-include "flatbuffers.lobster"
+import flatbuffers
namespace NamespaceA_NamespaceB
-enum +
- EnumInNestedNS_A = 0,
- EnumInNestedNS_B = 1,
+enum EnumInNestedNS:
+ EnumInNestedNS_A = 0
+ EnumInNestedNS_B = 1
EnumInNestedNS_C = 2
-struct TableInNestedNS
+class TableInNestedNS
-struct StructInNestedNS
+class StructInNestedNS
-struct TableInNestedNS : flatbuffers_handle
+class TableInNestedNS : flatbuffers_handle
def foo():
- buf_.flatbuffers_field_int32(pos_, 4, 0)
-
-def GetRootAsTableInNestedNS(buf:string): TableInNestedNS { buf, buf.flatbuffers_indirect(0) }
-
-def TableInNestedNSStart(b_:flatbuffers_builder):
- b_.StartObject(1)
-def TableInNestedNSAddFoo(b_:flatbuffers_builder, foo:int):
- b_.PrependInt32Slot(0, foo, 0)
-def TableInNestedNSEnd(b_:flatbuffers_builder):
- b_.EndObject()
-
-struct StructInNestedNS : flatbuffers_handle
+ return buf_.flatbuffers_field_int32(pos_, 4, 0)
+
+def GetRootAsTableInNestedNS(buf:string): return TableInNestedNS { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInNestedNSBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(1)
+ return this
+ def add_foo(foo:int):
+ b_.PrependInt32Slot(0, foo, 0)
+ return this
+ def end():
+ return b_.EndObject()
+
+class StructInNestedNS : flatbuffers_handle
def a():
- buf_.read_int32_le(pos_ + 0)
+ return buf_.read_int32_le(pos_ + 0)
def b():
- buf_.read_int32_le(pos_ + 4)
+ return buf_.read_int32_le(pos_ + 4)
def CreateStructInNestedNS(b_:flatbuffers_builder, a:int, b:int):
b_.Prep(4, 8)
diff --git a/tests/namespace_test/namespace_test1_generated.rs b/tests/namespace_test/namespace_test1_generated.rs
index ab302991..b811e3a0 100644
--- a/tests/namespace_test/namespace_test1_generated.rs
+++ b/tests/namespace_test/namespace_test1_generated.rs
@@ -35,8 +35,8 @@ pub enum EnumInNestedNS {
}
-const ENUM_MIN_ENUM_IN_NESTED_NS: i8 = 0;
-const ENUM_MAX_ENUM_IN_NESTED_NS: i8 = 2;
+pub const ENUM_MIN_ENUM_IN_NESTED_NS: i8 = 0;
+pub const ENUM_MAX_ENUM_IN_NESTED_NS: i8 = 2;
impl<'a> flatbuffers::Follow<'a> for EnumInNestedNS {
type Inner = Self;
@@ -70,14 +70,14 @@ impl flatbuffers::Push for EnumInNestedNS {
}
#[allow(non_camel_case_types)]
-const ENUM_VALUES_ENUM_IN_NESTED_NS:[EnumInNestedNS; 3] = [
+pub const ENUM_VALUES_ENUM_IN_NESTED_NS:[EnumInNestedNS; 3] = [
EnumInNestedNS::A,
EnumInNestedNS::B,
EnumInNestedNS::C
];
#[allow(non_camel_case_types)]
-const ENUM_NAMES_ENUM_IN_NESTED_NS:[&'static str; 3] = [
+pub const ENUM_NAMES_ENUM_IN_NESTED_NS:[&'static str; 3] = [
"A",
"B",
"C"
diff --git a/tests/namespace_test/namespace_test1_generated.ts b/tests/namespace_test/namespace_test1_generated.ts
index 33dbb6da..400a29bf 100644
--- a/tests/namespace_test/namespace_test1_generated.ts
+++ b/tests/namespace_test/namespace_test1_generated.ts
@@ -35,7 +35,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):TableInNestedNS {
* @returns TableInNestedNS
*/
static getRootAsTableInNestedNS(bb:flatbuffers.ByteBuffer, obj?:TableInNestedNS):TableInNestedNS {
- return (obj || new TableInNestedNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new TableInNestedNS()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInNestedNS= obj
+ * @returns TableInNestedNS
+ */
+static getSizePrefixedRootAsTableInNestedNS(bb:flatbuffers.ByteBuffer, obj?:TableInNestedNS):TableInNestedNS {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new TableInNestedNS()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
diff --git a/tests/namespace_test/namespace_test2_generated.h b/tests/namespace_test/namespace_test2_generated.h
index 135100a4..bb6844b8 100644
--- a/tests/namespace_test/namespace_test2_generated.h
+++ b/tests/namespace_test/namespace_test2_generated.h
@@ -6,23 +6,42 @@
#include "flatbuffers/flatbuffers.h"
-#include "namespace_test1_generated.h"
-
namespace NamespaceA {
struct TableInFirstNS;
+struct TableInFirstNSBuilder;
+struct TableInFirstNST;
} // namespace NamespaceA
namespace NamespaceC {
struct TableInC;
+struct TableInCBuilder;
+struct TableInCT;
} // namespace NamespaceC
namespace NamespaceA {
struct SecondTableInA;
+struct SecondTableInABuilder;
+struct SecondTableInAT;
+
+bool operator==(const TableInFirstNST &lhs, const TableInFirstNST &rhs);
+bool operator!=(const TableInFirstNST &lhs, const TableInFirstNST &rhs);
+} // namespace NamespaceA
+
+namespace NamespaceC {
+
+bool operator==(const TableInCT &lhs, const TableInCT &rhs);
+bool operator!=(const TableInCT &lhs, const TableInCT &rhs);
+} // namespace NamespaceC
+
+namespace NamespaceA {
+
+bool operator==(const SecondTableInAT &lhs, const SecondTableInAT &rhs);
+bool operator!=(const SecondTableInAT &lhs, const SecondTableInAT &rhs);
inline const flatbuffers::TypeTable *TableInFirstNSTypeTable();
@@ -38,7 +57,31 @@ namespace NamespaceA {
inline const flatbuffers::TypeTable *SecondTableInATypeTable();
+struct TableInFirstNST : public flatbuffers::NativeTable {
+ typedef TableInFirstNS TableType;
+ flatbuffers::unique_ptr<NamespaceA::NamespaceB::TableInNestedNST> foo_table;
+ NamespaceA::NamespaceB::EnumInNestedNS foo_enum;
+ flatbuffers::unique_ptr<NamespaceA::NamespaceB::StructInNestedNS> foo_struct;
+ TableInFirstNST()
+ : foo_enum(NamespaceA::NamespaceB::EnumInNestedNS_A) {
+ }
+};
+
+inline bool operator==(const TableInFirstNST &lhs, const TableInFirstNST &rhs) {
+ return
+ (lhs.foo_table == rhs.foo_table) &&
+ (lhs.foo_enum == rhs.foo_enum) &&
+ (lhs.foo_struct == rhs.foo_struct);
+}
+
+inline bool operator!=(const TableInFirstNST &lhs, const TableInFirstNST &rhs) {
+ return !(lhs == rhs);
+}
+
+
struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef TableInFirstNST NativeTableType;
+ typedef TableInFirstNSBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TableInFirstNSTypeTable();
}
@@ -73,9 +116,13 @@ struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<NamespaceA::NamespaceB::StructInNestedNS>(verifier, VT_FOO_STRUCT) &&
verifier.EndTable();
}
+ TableInFirstNST *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(TableInFirstNST *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<TableInFirstNS> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TableInFirstNST* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct TableInFirstNSBuilder {
+ typedef TableInFirstNS Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_foo_table(flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table) {
@@ -111,11 +158,34 @@ inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(
return builder_.Finish();
}
+flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(flatbuffers::FlatBufferBuilder &_fbb, const TableInFirstNST *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
} // namespace NamespaceA
namespace NamespaceC {
+struct TableInCT : public flatbuffers::NativeTable {
+ typedef TableInC TableType;
+ flatbuffers::unique_ptr<NamespaceA::TableInFirstNST> refer_to_a1;
+ flatbuffers::unique_ptr<NamespaceA::SecondTableInAT> refer_to_a2;
+ TableInCT() {
+ }
+};
+
+inline bool operator==(const TableInCT &lhs, const TableInCT &rhs) {
+ return
+ (lhs.refer_to_a1 == rhs.refer_to_a1) &&
+ (lhs.refer_to_a2 == rhs.refer_to_a2);
+}
+
+inline bool operator!=(const TableInCT &lhs, const TableInCT &rhs) {
+ return !(lhs == rhs);
+}
+
+
struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef TableInCT NativeTableType;
+ typedef TableInCBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return TableInCTypeTable();
}
@@ -143,9 +213,13 @@ struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyTable(refer_to_a2()) &&
verifier.EndTable();
}
+ TableInCT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(TableInCT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<TableInC> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TableInCT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct TableInCBuilder {
+ typedef TableInC Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_refer_to_a1(flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1) {
@@ -176,11 +250,32 @@ inline flatbuffers::Offset<TableInC> CreateTableInC(
return builder_.Finish();
}
+flatbuffers::Offset<TableInC> CreateTableInC(flatbuffers::FlatBufferBuilder &_fbb, const TableInCT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
} // namespace NamespaceC
namespace NamespaceA {
+struct SecondTableInAT : public flatbuffers::NativeTable {
+ typedef SecondTableInA TableType;
+ flatbuffers::unique_ptr<NamespaceC::TableInCT> refer_to_c;
+ SecondTableInAT() {
+ }
+};
+
+inline bool operator==(const SecondTableInAT &lhs, const SecondTableInAT &rhs) {
+ return
+ (lhs.refer_to_c == rhs.refer_to_c);
+}
+
+inline bool operator!=(const SecondTableInAT &lhs, const SecondTableInAT &rhs) {
+ return !(lhs == rhs);
+}
+
+
struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef SecondTableInAT NativeTableType;
+ typedef SecondTableInABuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return SecondTableInATypeTable();
}
@@ -199,9 +294,13 @@ struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyTable(refer_to_c()) &&
verifier.EndTable();
}
+ SecondTableInAT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(SecondTableInAT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<SecondTableInA> Pack(flatbuffers::FlatBufferBuilder &_fbb, const SecondTableInAT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct SecondTableInABuilder {
+ typedef SecondTableInA Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_refer_to_c(flatbuffers::Offset<NamespaceC::TableInC> refer_to_c) {
@@ -227,14 +326,103 @@ inline flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(
return builder_.Finish();
}
+flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(flatbuffers::FlatBufferBuilder &_fbb, const SecondTableInAT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline TableInFirstNST *TableInFirstNS::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ flatbuffers::unique_ptr<NamespaceA::TableInFirstNST> _o = flatbuffers::unique_ptr<NamespaceA::TableInFirstNST>(new TableInFirstNST());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void TableInFirstNS::UnPackTo(TableInFirstNST *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = foo_table(); if (_e) _o->foo_table = flatbuffers::unique_ptr<NamespaceA::NamespaceB::TableInNestedNST>(_e->UnPack(_resolver)); }
+ { auto _e = foo_enum(); _o->foo_enum = _e; }
+ { auto _e = foo_struct(); if (_e) _o->foo_struct = flatbuffers::unique_ptr<NamespaceA::NamespaceB::StructInNestedNS>(new NamespaceA::NamespaceB::StructInNestedNS(*_e)); }
+}
+
+inline flatbuffers::Offset<TableInFirstNS> TableInFirstNS::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TableInFirstNST* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateTableInFirstNS(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(flatbuffers::FlatBufferBuilder &_fbb, const TableInFirstNST *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TableInFirstNST* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _foo_table = _o->foo_table ? CreateTableInNestedNS(_fbb, _o->foo_table.get(), _rehasher) : 0;
+ auto _foo_enum = _o->foo_enum;
+ auto _foo_struct = _o->foo_struct ? _o->foo_struct.get() : 0;
+ return NamespaceA::CreateTableInFirstNS(
+ _fbb,
+ _foo_table,
+ _foo_enum,
+ _foo_struct);
+}
+
} // namespace NamespaceA
namespace NamespaceC {
+inline TableInCT *TableInC::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ flatbuffers::unique_ptr<NamespaceC::TableInCT> _o = flatbuffers::unique_ptr<NamespaceC::TableInCT>(new TableInCT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void TableInC::UnPackTo(TableInCT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = refer_to_a1(); if (_e) _o->refer_to_a1 = flatbuffers::unique_ptr<NamespaceA::TableInFirstNST>(_e->UnPack(_resolver)); }
+ { auto _e = refer_to_a2(); if (_e) _o->refer_to_a2 = flatbuffers::unique_ptr<NamespaceA::SecondTableInAT>(_e->UnPack(_resolver)); }
+}
+
+inline flatbuffers::Offset<TableInC> TableInC::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TableInCT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateTableInC(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<TableInC> CreateTableInC(flatbuffers::FlatBufferBuilder &_fbb, const TableInCT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TableInCT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _refer_to_a1 = _o->refer_to_a1 ? CreateTableInFirstNS(_fbb, _o->refer_to_a1.get(), _rehasher) : 0;
+ auto _refer_to_a2 = _o->refer_to_a2 ? CreateSecondTableInA(_fbb, _o->refer_to_a2.get(), _rehasher) : 0;
+ return NamespaceC::CreateTableInC(
+ _fbb,
+ _refer_to_a1,
+ _refer_to_a2);
+}
+
} // namespace NamespaceC
namespace NamespaceA {
+inline SecondTableInAT *SecondTableInA::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ flatbuffers::unique_ptr<NamespaceA::SecondTableInAT> _o = flatbuffers::unique_ptr<NamespaceA::SecondTableInAT>(new SecondTableInAT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void SecondTableInA::UnPackTo(SecondTableInAT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = refer_to_c(); if (_e) _o->refer_to_c = flatbuffers::unique_ptr<NamespaceC::TableInCT>(_e->UnPack(_resolver)); }
+}
+
+inline flatbuffers::Offset<SecondTableInA> SecondTableInA::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SecondTableInAT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateSecondTableInA(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(flatbuffers::FlatBufferBuilder &_fbb, const SecondTableInAT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SecondTableInAT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _refer_to_c = _o->refer_to_c ? CreateTableInC(_fbb, _o->refer_to_c.get(), _rehasher) : 0;
+ return NamespaceA::CreateSecondTableInA(
+ _fbb,
+ _refer_to_c);
+}
+
inline const flatbuffers::TypeTable *TableInFirstNSTypeTable() {
static const flatbuffers::TypeCode type_codes[] = {
{ flatbuffers::ET_SEQUENCE, 0, 0 },
diff --git a/tests/namespace_test/namespace_test2_generated.js b/tests/namespace_test/namespace_test2_generated.js
index a06e05e3..f3be5786 100644
--- a/tests/namespace_test/namespace_test2_generated.js
+++ b/tests/namespace_test/namespace_test2_generated.js
@@ -54,6 +54,16 @@ NamespaceA.TableInFirstNS.getRootAsTableInFirstNS = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.TableInFirstNS=} obj
+ * @returns {NamespaceA.TableInFirstNS}
+ */
+NamespaceA.TableInFirstNS.getSizePrefixedRootAsTableInFirstNS = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new NamespaceA.TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @param {NamespaceA.NamespaceB.TableInNestedNS=} obj
* @returns {NamespaceA.NamespaceB.TableInNestedNS|null}
*/
@@ -185,6 +195,16 @@ NamespaceC.TableInC.getRootAsTableInC = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceC.TableInC=} obj
+ * @returns {NamespaceC.TableInC}
+ */
+NamespaceC.TableInC.getSizePrefixedRootAsTableInC = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new NamespaceC.TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @param {NamespaceA.TableInFirstNS=} obj
* @returns {NamespaceA.TableInFirstNS|null}
*/
@@ -283,6 +303,16 @@ NamespaceA.SecondTableInA.getRootAsSecondTableInA = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {NamespaceA.SecondTableInA=} obj
+ * @returns {NamespaceA.SecondTableInA}
+ */
+NamespaceA.SecondTableInA.getSizePrefixedRootAsSecondTableInA = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new NamespaceA.SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @param {NamespaceC.TableInC=} obj
* @returns {NamespaceC.TableInC|null}
*/
diff --git a/tests/namespace_test/namespace_test2_generated.lobster b/tests/namespace_test/namespace_test2_generated.lobster
index 8b9809bc..4383e685 100644
--- a/tests/namespace_test/namespace_test2_generated.lobster
+++ b/tests/namespace_test/namespace_test2_generated.lobster
@@ -1,76 +1,90 @@
// automatically generated by the FlatBuffers compiler, do not modify
-
-include "flatbuffers.lobster"
+import flatbuffers
namespace NamespaceA
-struct TableInFirstNS
+class TableInFirstNS
namespace NamespaceC
-struct TableInC
+class TableInC
namespace NamespaceA
-struct SecondTableInA
+class SecondTableInA
-struct TableInFirstNS : flatbuffers_handle
+class TableInFirstNS : flatbuffers_handle
def foo_table():
- o := buf_.flatbuffers_field_table(pos_, 4)
- if o: NamespaceA_NamespaceB_TableInNestedNS { buf_, o } else: nil
+ let o = buf_.flatbuffers_field_table(pos_, 4)
+ return if o: NamespaceA_NamespaceB_TableInNestedNS { buf_, o } else: nil
def foo_enum():
- buf_.flatbuffers_field_int8(pos_, 6, 0)
+ return EnumInNestedNS(buf_.flatbuffers_field_int8(pos_, 6, 0))
def foo_struct():
- o := buf_.flatbuffers_field_struct(pos_, 8)
- if o: NamespaceA_NamespaceB_StructInNestedNS { buf_, o } else: nil
-
-def GetRootAsTableInFirstNS(buf:string): TableInFirstNS { buf, buf.flatbuffers_indirect(0) }
-
-def TableInFirstNSStart(b_:flatbuffers_builder):
- b_.StartObject(3)
-def TableInFirstNSAddFooTable(b_:flatbuffers_builder, foo_table:int):
- b_.PrependUOffsetTRelativeSlot(0, foo_table, 0)
-def TableInFirstNSAddFooEnum(b_:flatbuffers_builder, foo_enum:int):
- b_.PrependInt8Slot(1, foo_enum, 0)
-def TableInFirstNSAddFooStruct(b_:flatbuffers_builder, foo_struct:int):
- b_.PrependStructSlot(2, foo_struct, 0)
-def TableInFirstNSEnd(b_:flatbuffers_builder):
- b_.EndObject()
+ let o = buf_.flatbuffers_field_struct(pos_, 8)
+ return if o: NamespaceA_NamespaceB_StructInNestedNS { buf_, o } else: nil
+
+def GetRootAsTableInFirstNS(buf:string): return TableInFirstNS { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInFirstNSBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(3)
+ return this
+ def add_foo_table(foo_table:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(0, foo_table)
+ return this
+ def add_foo_enum(foo_enum:EnumInNestedNS):
+ b_.PrependInt8Slot(1, foo_enum, 0)
+ return this
+ def add_foo_struct(foo_struct:flatbuffers_offset):
+ b_.PrependStructSlot(2, foo_struct)
+ return this
+ def end():
+ return b_.EndObject()
namespace NamespaceC
-struct TableInC : flatbuffers_handle
+class TableInC : flatbuffers_handle
def refer_to_a1():
- o := buf_.flatbuffers_field_table(pos_, 4)
- if o: NamespaceA_TableInFirstNS { buf_, o } else: nil
+ let o = buf_.flatbuffers_field_table(pos_, 4)
+ return if o: NamespaceA_TableInFirstNS { buf_, o } else: nil
def refer_to_a2():
- o := buf_.flatbuffers_field_table(pos_, 6)
- if o: NamespaceA_SecondTableInA { buf_, o } else: nil
-
-def GetRootAsTableInC(buf:string): TableInC { buf, buf.flatbuffers_indirect(0) }
-
-def TableInCStart(b_:flatbuffers_builder):
- b_.StartObject(2)
-def TableInCAddReferToA1(b_:flatbuffers_builder, refer_to_a1:int):
- b_.PrependUOffsetTRelativeSlot(0, refer_to_a1, 0)
-def TableInCAddReferToA2(b_:flatbuffers_builder, refer_to_a2:int):
- b_.PrependUOffsetTRelativeSlot(1, refer_to_a2, 0)
-def TableInCEnd(b_:flatbuffers_builder):
- b_.EndObject()
+ let o = buf_.flatbuffers_field_table(pos_, 6)
+ return if o: NamespaceA_SecondTableInA { buf_, o } else: nil
+
+def GetRootAsTableInC(buf:string): return TableInC { buf, buf.flatbuffers_indirect(0) }
+
+struct TableInCBuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(2)
+ return this
+ def add_refer_to_a1(refer_to_a1:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(0, refer_to_a1)
+ return this
+ def add_refer_to_a2(refer_to_a2:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(1, refer_to_a2)
+ return this
+ def end():
+ return b_.EndObject()
namespace NamespaceA
-struct SecondTableInA : flatbuffers_handle
+class SecondTableInA : flatbuffers_handle
def refer_to_c():
- o := buf_.flatbuffers_field_table(pos_, 4)
- if o: NamespaceC_TableInC { buf_, o } else: nil
-
-def GetRootAsSecondTableInA(buf:string): SecondTableInA { buf, buf.flatbuffers_indirect(0) }
-
-def SecondTableInAStart(b_:flatbuffers_builder):
- b_.StartObject(1)
-def SecondTableInAAddReferToC(b_:flatbuffers_builder, refer_to_c:int):
- b_.PrependUOffsetTRelativeSlot(0, refer_to_c, 0)
-def SecondTableInAEnd(b_:flatbuffers_builder):
- b_.EndObject()
+ let o = buf_.flatbuffers_field_table(pos_, 4)
+ return if o: NamespaceC_TableInC { buf_, o } else: nil
+
+def GetRootAsSecondTableInA(buf:string): return SecondTableInA { buf, buf.flatbuffers_indirect(0) }
+
+struct SecondTableInABuilder:
+ b_:flatbuffers_builder
+ def start():
+ b_.StartObject(1)
+ return this
+ def add_refer_to_c(refer_to_c:flatbuffers_offset):
+ b_.PrependUOffsetTRelativeSlot(0, refer_to_c)
+ return this
+ def end():
+ return b_.EndObject()
diff --git a/tests/namespace_test/namespace_test2_generated.rs b/tests/namespace_test/namespace_test2_generated.rs
index 3c04c0f0..cd0a75ae 100644
--- a/tests/namespace_test/namespace_test2_generated.rs
+++ b/tests/namespace_test/namespace_test2_generated.rs
@@ -2,6 +2,7 @@
+use crate::namespace_test1_generated::*;
use std::mem;
use std::cmp::Ordering;
@@ -11,6 +12,7 @@ use self::flatbuffers::EndianScalar;
#[allow(unused_imports, dead_code)]
pub mod namespace_a {
+ use crate::namespace_test1_generated::*;
use std::mem;
use std::cmp::Ordering;
@@ -198,6 +200,7 @@ impl<'a: 'b, 'b> SecondTableInABuilder<'a, 'b> {
#[allow(unused_imports, dead_code)]
pub mod namespace_c {
+ use crate::namespace_test1_generated::*;
use std::mem;
use std::cmp::Ordering;
diff --git a/tests/namespace_test/namespace_test2_generated.ts b/tests/namespace_test/namespace_test2_generated.ts
index 5a630e2a..5bfc0ddd 100644
--- a/tests/namespace_test/namespace_test2_generated.ts
+++ b/tests/namespace_test/namespace_test2_generated.ts
@@ -26,7 +26,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):TableInFirstNS {
* @returns TableInFirstNS
*/
static getRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):TableInFirstNS {
- return (obj || new TableInFirstNS).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new TableInFirstNS()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInFirstNS= obj
+ * @returns TableInFirstNS
+ */
+static getSizePrefixedRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):TableInFirstNS {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new TableInFirstNS()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -35,7 +45,7 @@ static getRootAsTableInFirstNS(bb:flatbuffers.ByteBuffer, obj?:TableInFirstNS):T
*/
fooTable(obj?:NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS):NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS|null {
var offset = this.bb!.__offset(this.bb_pos, 4);
- return offset ? (obj || new NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+ return offset ? (obj || new NS8755221360535654258.NamespaceA.NamespaceB.TableInNestedNS()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};
/**
@@ -67,7 +77,7 @@ mutate_foo_enum(value:NS8755221360535654258.NamespaceA.NamespaceB.EnumInNestedNS
*/
fooStruct(obj?:NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS):NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS|null {
var offset = this.bb!.__offset(this.bb_pos, 8);
- return offset ? (obj || new NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS).__init(this.bb_pos + offset, this.bb!) : null;
+ return offset ? (obj || new NS8755221360535654258.NamespaceA.NamespaceB.StructInNestedNS()).__init(this.bb_pos + offset, this.bb!) : null;
};
/**
@@ -144,7 +154,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):TableInC {
* @returns TableInC
*/
static getRootAsTableInC(bb:flatbuffers.ByteBuffer, obj?:TableInC):TableInC {
- return (obj || new TableInC).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new TableInC()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param TableInC= obj
+ * @returns TableInC
+ */
+static getSizePrefixedRootAsTableInC(bb:flatbuffers.ByteBuffer, obj?:TableInC):TableInC {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new TableInC()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -153,7 +173,7 @@ static getRootAsTableInC(bb:flatbuffers.ByteBuffer, obj?:TableInC):TableInC {
*/
referToA1(obj?:NamespaceA.TableInFirstNS):NamespaceA.TableInFirstNS|null {
var offset = this.bb!.__offset(this.bb_pos, 4);
- return offset ? (obj || new NamespaceA.TableInFirstNS).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+ return offset ? (obj || new NamespaceA.TableInFirstNS()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};
/**
@@ -162,7 +182,7 @@ referToA1(obj?:NamespaceA.TableInFirstNS):NamespaceA.TableInFirstNS|null {
*/
referToA2(obj?:NamespaceA.SecondTableInA):NamespaceA.SecondTableInA|null {
var offset = this.bb!.__offset(this.bb_pos, 6);
- return offset ? (obj || new NamespaceA.SecondTableInA).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+ return offset ? (obj || new NamespaceA.SecondTableInA()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};
/**
@@ -230,7 +250,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):SecondTableInA {
* @returns SecondTableInA
*/
static getRootAsSecondTableInA(bb:flatbuffers.ByteBuffer, obj?:SecondTableInA):SecondTableInA {
- return (obj || new SecondTableInA).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new SecondTableInA()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param SecondTableInA= obj
+ * @returns SecondTableInA
+ */
+static getSizePrefixedRootAsSecondTableInA(bb:flatbuffers.ByteBuffer, obj?:SecondTableInA):SecondTableInA {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new SecondTableInA()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -239,7 +269,7 @@ static getRootAsSecondTableInA(bb:flatbuffers.ByteBuffer, obj?:SecondTableInA):S
*/
referToC(obj?:NamespaceC.TableInC):NamespaceC.TableInC|null {
var offset = this.bb!.__offset(this.bb_pos, 4);
- return offset ? (obj || new NamespaceC.TableInC).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
+ return offset ? (obj || new NamespaceC.TableInC()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
};
/**
diff --git a/tests/namespace_test/namespace_test2_namespace_a_generated.dart b/tests/namespace_test/namespace_test2_namespace_a_generated.dart
index d5108eba..e10ad4b7 100644
--- a/tests/namespace_test/namespace_test2_namespace_a_generated.dart
+++ b/tests/namespace_test/namespace_test2_namespace_a_generated.dart
@@ -6,7 +6,6 @@ library namespace_a;
import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
-import 'namespace_test1_namespace_a_generated.dart';
import './namespace_test2_namespace_c_generated.dart' as namespace_c;
class TableInFirstNS {
diff --git a/tests/namespace_test/namespace_test2_namespace_c_generated.dart b/tests/namespace_test/namespace_test2_namespace_c_generated.dart
index 7214febc..edb6ffcb 100644
--- a/tests/namespace_test/namespace_test2_namespace_c_generated.dart
+++ b/tests/namespace_test/namespace_test2_namespace_c_generated.dart
@@ -6,7 +6,6 @@ library namespace_c;
import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
-import 'namespace_test1_namespace_c_generated.dart';
import './namespace_test2_namespace_a_generated.dart' as namespace_a;
class TableInC {
diff --git a/tests/native_type_test.fbs b/tests/native_type_test.fbs
new file mode 100644
index 00000000..de80bdf9
--- /dev/null
+++ b/tests/native_type_test.fbs
@@ -0,0 +1,15 @@
+native_include "native_type_test_impl.h";
+
+namespace Geometry;
+
+struct Vector3D (native_type:"Native::Vector3D") {
+ x:float;
+ y:float;
+ z:float;
+}
+
+table ApplicationData {
+ vectors:[Vector3D];
+}
+
+root_type ApplicationData;
diff --git a/tests/native_type_test_generated.h b/tests/native_type_test_generated.h
new file mode 100644
index 00000000..91114264
--- /dev/null
+++ b/tests/native_type_test_generated.h
@@ -0,0 +1,241 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+
+#ifndef FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
+#define FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
+
+#include "flatbuffers/flatbuffers.h"
+
+#include "native_type_test_impl.h"
+
+namespace Geometry {
+
+struct Vector3D;
+
+struct ApplicationData;
+struct ApplicationDataBuilder;
+struct ApplicationDataT;
+
+inline const flatbuffers::TypeTable *Vector3DTypeTable();
+
+inline const flatbuffers::TypeTable *ApplicationDataTypeTable();
+
+FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector3D FLATBUFFERS_FINAL_CLASS {
+ private:
+ float x_;
+ float y_;
+ float z_;
+
+ public:
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return Vector3DTypeTable();
+ }
+ Vector3D() {
+ memset(static_cast<void *>(this), 0, sizeof(Vector3D));
+ }
+ Vector3D(float _x, float _y, float _z)
+ : x_(flatbuffers::EndianScalar(_x)),
+ y_(flatbuffers::EndianScalar(_y)),
+ z_(flatbuffers::EndianScalar(_z)) {
+ }
+ float x() const {
+ return flatbuffers::EndianScalar(x_);
+ }
+ void mutate_x(float _x) {
+ flatbuffers::WriteScalar(&x_, _x);
+ }
+ float y() const {
+ return flatbuffers::EndianScalar(y_);
+ }
+ void mutate_y(float _y) {
+ flatbuffers::WriteScalar(&y_, _y);
+ }
+ float z() const {
+ return flatbuffers::EndianScalar(z_);
+ }
+ void mutate_z(float _z) {
+ flatbuffers::WriteScalar(&z_, _z);
+ }
+};
+FLATBUFFERS_STRUCT_END(Vector3D, 12);
+
+struct ApplicationDataT : public flatbuffers::NativeTable {
+ typedef ApplicationData TableType;
+ std::vector<Native::Vector3D> vectors;
+ ApplicationDataT() {
+ }
+};
+
+struct ApplicationData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
+ typedef ApplicationDataT NativeTableType;
+ typedef ApplicationDataBuilder Builder;
+ static const flatbuffers::TypeTable *MiniReflectTypeTable() {
+ return ApplicationDataTypeTable();
+ }
+ enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
+ VT_VECTORS = 4
+ };
+ const flatbuffers::Vector<const Geometry::Vector3D *> *vectors() const {
+ return GetPointer<const flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
+ }
+ flatbuffers::Vector<const Geometry::Vector3D *> *mutable_vectors() {
+ return GetPointer<flatbuffers::Vector<const Geometry::Vector3D *> *>(VT_VECTORS);
+ }
+ bool Verify(flatbuffers::Verifier &verifier) const {
+ return VerifyTableStart(verifier) &&
+ VerifyOffset(verifier, VT_VECTORS) &&
+ verifier.VerifyVector(vectors()) &&
+ verifier.EndTable();
+ }
+ ApplicationDataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ void UnPackTo(ApplicationDataT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
+ static flatbuffers::Offset<ApplicationData> Pack(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+};
+
+struct ApplicationDataBuilder {
+ typedef ApplicationData Table;
+ flatbuffers::FlatBufferBuilder &fbb_;
+ flatbuffers::uoffset_t start_;
+ void add_vectors(flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors) {
+ fbb_.AddOffset(ApplicationData::VT_VECTORS, vectors);
+ }
+ explicit ApplicationDataBuilder(flatbuffers::FlatBufferBuilder &_fbb)
+ : fbb_(_fbb) {
+ start_ = fbb_.StartTable();
+ }
+ ApplicationDataBuilder &operator=(const ApplicationDataBuilder &);
+ flatbuffers::Offset<ApplicationData> Finish() {
+ const auto end = fbb_.EndTable(start_);
+ auto o = flatbuffers::Offset<ApplicationData>(end);
+ return o;
+ }
+};
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationData(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ flatbuffers::Offset<flatbuffers::Vector<const Geometry::Vector3D *>> vectors = 0) {
+ ApplicationDataBuilder builder_(_fbb);
+ builder_.add_vectors(vectors);
+ return builder_.Finish();
+}
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationDataDirect(
+ flatbuffers::FlatBufferBuilder &_fbb,
+ const std::vector<Geometry::Vector3D> *vectors = nullptr) {
+ auto vectors__ = vectors ? _fbb.CreateVectorOfStructs<Geometry::Vector3D>(*vectors) : 0;
+ return Geometry::CreateApplicationData(
+ _fbb,
+ vectors__);
+}
+
+flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
+
+inline ApplicationDataT *ApplicationData::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
+ flatbuffers::unique_ptr<Geometry::ApplicationDataT> _o = flatbuffers::unique_ptr<Geometry::ApplicationDataT>(new ApplicationDataT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
+}
+
+inline void ApplicationData::UnPackTo(ApplicationDataT *_o, const flatbuffers::resolver_function_t *_resolver) const {
+ (void)_o;
+ (void)_resolver;
+ { auto _e = vectors(); if (_e) { _o->vectors.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->vectors[_i] = flatbuffers::UnPack(*_e->Get(_i)); } } }
+}
+
+inline flatbuffers::Offset<ApplicationData> ApplicationData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
+ return CreateApplicationData(_fbb, _o, _rehasher);
+}
+
+inline flatbuffers::Offset<ApplicationData> CreateApplicationData(flatbuffers::FlatBufferBuilder &_fbb, const ApplicationDataT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
+ (void)_rehasher;
+ (void)_o;
+ struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const ApplicationDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
+ auto _vectors = _o->vectors.size() ? _fbb.CreateVectorOfNativeStructs<Geometry::Vector3D>(_o->vectors) : 0;
+ return Geometry::CreateApplicationData(
+ _fbb,
+ _vectors);
+}
+
+inline const flatbuffers::TypeTable *Vector3DTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_FLOAT, 0, -1 },
+ { flatbuffers::ET_FLOAT, 0, -1 }
+ };
+ static const int64_t values[] = { 0, 4, 8, 12 };
+ static const char * const names[] = {
+ "x",
+ "y",
+ "z"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_STRUCT, 3, type_codes, nullptr, values, names
+ };
+ return &tt;
+}
+
+inline const flatbuffers::TypeTable *ApplicationDataTypeTable() {
+ static const flatbuffers::TypeCode type_codes[] = {
+ { flatbuffers::ET_SEQUENCE, 1, 0 }
+ };
+ static const flatbuffers::TypeFunction type_refs[] = {
+ Geometry::Vector3DTypeTable
+ };
+ static const char * const names[] = {
+ "vectors"
+ };
+ static const flatbuffers::TypeTable tt = {
+ flatbuffers::ST_TABLE, 1, type_codes, type_refs, nullptr, names
+ };
+ return &tt;
+}
+
+inline const Geometry::ApplicationData *GetApplicationData(const void *buf) {
+ return flatbuffers::GetRoot<Geometry::ApplicationData>(buf);
+}
+
+inline const Geometry::ApplicationData *GetSizePrefixedApplicationData(const void *buf) {
+ return flatbuffers::GetSizePrefixedRoot<Geometry::ApplicationData>(buf);
+}
+
+inline ApplicationData *GetMutableApplicationData(void *buf) {
+ return flatbuffers::GetMutableRoot<ApplicationData>(buf);
+}
+
+inline bool VerifyApplicationDataBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifyBuffer<Geometry::ApplicationData>(nullptr);
+}
+
+inline bool VerifySizePrefixedApplicationDataBuffer(
+ flatbuffers::Verifier &verifier) {
+ return verifier.VerifySizePrefixedBuffer<Geometry::ApplicationData>(nullptr);
+}
+
+inline void FinishApplicationDataBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<Geometry::ApplicationData> root) {
+ fbb.Finish(root);
+}
+
+inline void FinishSizePrefixedApplicationDataBuffer(
+ flatbuffers::FlatBufferBuilder &fbb,
+ flatbuffers::Offset<Geometry::ApplicationData> root) {
+ fbb.FinishSizePrefixed(root);
+}
+
+inline flatbuffers::unique_ptr<Geometry::ApplicationDataT> UnPackApplicationData(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<Geometry::ApplicationDataT>(GetApplicationData(buf)->UnPack(res));
+}
+
+inline flatbuffers::unique_ptr<Geometry::ApplicationDataT> UnPackSizePrefixedApplicationData(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<Geometry::ApplicationDataT>(GetSizePrefixedApplicationData(buf)->UnPack(res));
+}
+
+} // namespace Geometry
+
+#endif // FLATBUFFERS_GENERATED_NATIVETYPETEST_GEOMETRY_H_
diff --git a/tests/native_type_test_impl.cpp b/tests/native_type_test_impl.cpp
new file mode 100644
index 00000000..edf23ebf
--- /dev/null
+++ b/tests/native_type_test_impl.cpp
@@ -0,0 +1,13 @@
+#include "native_type_test_impl.h"
+
+#include "native_type_test_generated.h"
+
+namespace flatbuffers {
+Geometry::Vector3D Pack(const Native::Vector3D &obj) {
+ return Geometry::Vector3D(obj.x, obj.y, obj.z);
+}
+
+const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
+ return Native::Vector3D(obj.x(), obj.y(), obj.z());
+}
+} // namespace flatbuffers
diff --git a/tests/native_type_test_impl.h b/tests/native_type_test_impl.h
new file mode 100644
index 00000000..fb35e0fc
--- /dev/null
+++ b/tests/native_type_test_impl.h
@@ -0,0 +1,32 @@
+#ifndef NATIVE_TYPE_TEST_IMPL_H
+#define NATIVE_TYPE_TEST_IMPL_H
+
+namespace Native {
+struct Vector3D {
+ float x;
+ float y;
+ float z;
+
+ Vector3D() {
+ x = 0;
+ y = 0;
+ z = 0;
+ };
+ Vector3D(float _x, float _y, float _z) {
+ this->x = _x;
+ this->y = _y;
+ this->z = _z;
+ }
+};
+} // namespace Native
+
+namespace Geometry {
+struct Vector3D;
+}
+
+namespace flatbuffers {
+Geometry::Vector3D Pack(const Native::Vector3D &obj);
+const Native::Vector3D UnPack(const Geometry::Vector3D &obj);
+} // namespace flatbuffers
+
+#endif // VECTOR3D_PACK_H
diff --git a/tests/prototest/test_include.golden b/tests/prototest/test_include.golden
new file mode 100644
index 00000000..16b92ed8
--- /dev/null
+++ b/tests/prototest/test_include.golden
@@ -0,0 +1,57 @@
+// Generated from test.proto
+
+include "imported.fbs";
+
+namespace proto.test;
+
+/// Enum doc comment.
+enum ProtoEnum : int {
+ NUL = 0,
+ FOO = 1,
+ /// Enum 2nd value doc comment misaligned.
+ BAR = 5,
+}
+
+/// 2nd table doc comment with
+/// many lines.
+table ProtoMessage {
+ c:int = 16;
+ d:long;
+ p:uint;
+ e:ulong;
+ /// doc comment for f.
+ f:int = -1;
+ g:long;
+ h:uint;
+ q:ulong;
+ i:int;
+ j:long;
+ /// doc comment for k.
+ k:bool;
+ /// doc comment for l on 2
+ /// lines
+ l:string (required);
+ m:[ubyte];
+ n:proto.test.ProtoMessage_.OtherMessage;
+ o:[string];
+ z:proto.test.ImportedMessage;
+ /// doc comment for r.
+ r:proto.test.ProtoMessage_.Anonymous0;
+}
+
+namespace proto.test.ProtoMessage_;
+
+table OtherMessage {
+ a:double;
+ /// doc comment for b.
+ b:float = 3.14149;
+}
+
+table Anonymous0 {
+ /// doc comment for s.
+ s:proto.test.ImportedMessage;
+ /// doc comment for t on 2
+ /// lines.
+ t:proto.test.ProtoMessage_.OtherMessage;
+}
+
diff --git a/tests/prototest/test_suffix.golden b/tests/prototest/test_suffix.golden
new file mode 100644
index 00000000..94ffd267
--- /dev/null
+++ b/tests/prototest/test_suffix.golden
@@ -0,0 +1,59 @@
+// Generated from test.proto
+
+namespace proto.test.test_namespace_suffix;
+
+/// Enum doc comment.
+enum ProtoEnum : int {
+ NUL = 0,
+ FOO = 1,
+ /// Enum 2nd value doc comment misaligned.
+ BAR = 5,
+}
+
+table ImportedMessage {
+ a:int;
+}
+
+/// 2nd table doc comment with
+/// many lines.
+table ProtoMessage {
+ c:int = 16;
+ d:long;
+ p:uint;
+ e:ulong;
+ /// doc comment for f.
+ f:int = -1;
+ g:long;
+ h:uint;
+ q:ulong;
+ i:int;
+ j:long;
+ /// doc comment for k.
+ k:bool;
+ /// doc comment for l on 2
+ /// lines
+ l:string (required);
+ m:[ubyte];
+ n:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage;
+ o:[string];
+ z:proto.test.test_namespace_suffix.ImportedMessage;
+ /// doc comment for r.
+ r:proto.test.test_namespace_suffix.ProtoMessage_.Anonymous0;
+}
+
+namespace proto.test.test_namespace_suffix.ProtoMessage_;
+
+table OtherMessage {
+ a:double;
+ /// doc comment for b.
+ b:float = 3.14149;
+}
+
+table Anonymous0 {
+ /// doc comment for s.
+ s:proto.test.test_namespace_suffix.ImportedMessage;
+ /// doc comment for t on 2
+ /// lines.
+ t:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage;
+}
+
diff --git a/tests/prototest/test_union_include.golden b/tests/prototest/test_union_include.golden
new file mode 100644
index 00000000..1ce3ac30
--- /dev/null
+++ b/tests/prototest/test_union_include.golden
@@ -0,0 +1,61 @@
+// Generated from test.proto
+
+include "imported.fbs";
+
+namespace proto.test;
+
+/// Enum doc comment.
+enum ProtoEnum : int {
+ NUL = 0,
+ FOO = 1,
+ /// Enum 2nd value doc comment misaligned.
+ BAR = 5,
+}
+
+namespace proto.test.ProtoMessage_;
+
+union RUnion {
+ /// doc comment for s.
+ proto.test.ImportedMessage,
+ /// doc comment for t on 2
+ /// lines.
+ proto.test.ProtoMessage_.OtherMessage,
+}
+
+namespace proto.test;
+
+/// 2nd table doc comment with
+/// many lines.
+table ProtoMessage {
+ c:int = 16;
+ d:long;
+ p:uint;
+ e:ulong;
+ /// doc comment for f.
+ f:int = -1;
+ g:long;
+ h:uint;
+ q:ulong;
+ i:int;
+ j:long;
+ /// doc comment for k.
+ k:bool;
+ /// doc comment for l on 2
+ /// lines
+ l:string (required);
+ m:[ubyte];
+ n:proto.test.ProtoMessage_.OtherMessage;
+ o:[string];
+ z:proto.test.ImportedMessage;
+ /// doc comment for r.
+ r:proto.test.ProtoMessage_.RUnion;
+}
+
+namespace proto.test.ProtoMessage_;
+
+table OtherMessage {
+ a:double;
+ /// doc comment for b.
+ b:float = 3.14149;
+}
+
diff --git a/tests/prototest/test_union_suffix.golden b/tests/prototest/test_union_suffix.golden
new file mode 100644
index 00000000..0b0f9203
--- /dev/null
+++ b/tests/prototest/test_union_suffix.golden
@@ -0,0 +1,63 @@
+// Generated from test.proto
+
+namespace proto.test.test_namespace_suffix;
+
+/// Enum doc comment.
+enum ProtoEnum : int {
+ NUL = 0,
+ FOO = 1,
+ /// Enum 2nd value doc comment misaligned.
+ BAR = 5,
+}
+
+namespace proto.test.test_namespace_suffix.ProtoMessage_;
+
+union RUnion {
+ /// doc comment for s.
+ proto.test.test_namespace_suffix.ImportedMessage,
+ /// doc comment for t on 2
+ /// lines.
+ proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage,
+}
+
+namespace proto.test.test_namespace_suffix;
+
+table ImportedMessage {
+ a:int;
+}
+
+/// 2nd table doc comment with
+/// many lines.
+table ProtoMessage {
+ c:int = 16;
+ d:long;
+ p:uint;
+ e:ulong;
+ /// doc comment for f.
+ f:int = -1;
+ g:long;
+ h:uint;
+ q:ulong;
+ i:int;
+ j:long;
+ /// doc comment for k.
+ k:bool;
+ /// doc comment for l on 2
+ /// lines
+ l:string (required);
+ m:[ubyte];
+ n:proto.test.test_namespace_suffix.ProtoMessage_.OtherMessage;
+ o:[string];
+ z:proto.test.test_namespace_suffix.ImportedMessage;
+ /// doc comment for r.
+ r:proto.test.test_namespace_suffix.ProtoMessage_.RUnion;
+}
+
+namespace proto.test.test_namespace_suffix.ProtoMessage_;
+
+table OtherMessage {
+ a:double;
+ /// doc comment for b.
+ b:float = 3.14149;
+}
+
diff --git a/tests/py_test.py b/tests/py_test.py
index 76dabcbc..9b31f608 100644
--- a/tests/py_test.py
+++ b/tests/py_test.py
@@ -21,6 +21,7 @@ PY_VERSION = sys.version_info[:2]
import ctypes
from collections import defaultdict
import math
+import random
import timeit
import unittest
@@ -41,7 +42,11 @@ import MyGame.Example.Test # refers to generated code
import MyGame.Example.Stat # refers to generated code
import MyGame.Example.Vec3 # refers to generated code
import MyGame.MonsterExtra # refers to generated code
-
+import MyGame.InParentNamespace # refers to generated code
+import MyGame.Example.ArrayTable # refers to generated code
+import MyGame.Example.ArrayStruct # refers to generated code
+import MyGame.Example.NestedStruct # refers to generated code
+import MyGame.Example.TestEnum # refers to generated code
def assertRaises(test_case, fn, exception_class):
''' Backwards-compatible assertion for exceptions raised. '''
@@ -61,8 +66,9 @@ class TestWireFormat(unittest.TestCase):
# returning errors, and is interpreted correctly, for size prefixed
# representation and regular:
for sizePrefix in [True, False]:
- gen_buf, gen_off = make_monster_from_generated_code(sizePrefix = sizePrefix)
- CheckReadBuffer(gen_buf, gen_off, sizePrefix = sizePrefix)
+ for file_identifier in [None, b"MONS"]:
+ gen_buf, gen_off = make_monster_from_generated_code(sizePrefix=sizePrefix, file_identifier=file_identifier)
+ CheckReadBuffer(gen_buf, gen_off, sizePrefix=sizePrefix, file_identifier=file_identifier)
# Verify that the canonical flatbuffer file is readable by the
# generated Python code. Note that context managers are not part of
@@ -70,7 +76,7 @@ class TestWireFormat(unittest.TestCase):
f = open('monsterdata_test.mon', 'rb')
canonicalWireData = f.read()
f.close()
- CheckReadBuffer(bytearray(canonicalWireData), 0)
+ CheckReadBuffer(bytearray(canonicalWireData), 0, file_identifier=b'MONS')
# Write the generated buffer out to a file:
f = open('monsterdata_python_wire.mon', 'wb')
@@ -78,7 +84,450 @@ class TestWireFormat(unittest.TestCase):
f.close()
-def CheckReadBuffer(buf, offset, sizePrefix = False):
+class TestObjectBasedAPI(unittest.TestCase):
+ ''' Tests the generated object based API.'''
+
+ def test_consistenty_with_repeated_pack_and_unpack(self):
+ ''' Checks the serialization and deserialization between a buffer and
+ its python object. It tests in the same way as the C++ object API test,
+ ObjectFlatBuffersTest in test.cpp. '''
+
+ buf, off = make_monster_from_generated_code()
+
+ # Turns a buffer into Python object (T class).
+ monster1 = MyGame.Example.Monster.Monster.GetRootAsMonster(buf, off)
+ monsterT1 = MyGame.Example.Monster.MonsterT.InitFromObj(monster1)
+
+ for sizePrefix in [True, False]:
+ # Re-serialize the data into a buffer.
+ b1 = flatbuffers.Builder(0)
+ if sizePrefix:
+ b1.FinishSizePrefixed(monsterT1.Pack(b1))
+ else:
+ b1.Finish(monsterT1.Pack(b1))
+ CheckReadBuffer(b1.Bytes, b1.Head(), sizePrefix)
+
+ # Deserializes the buffer into Python object again.
+ monster2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b1.Bytes,
+ b1.Head())
+ # Re-serializes the data into a buffer for one more time.
+ monsterT2 = MyGame.Example.Monster.MonsterT.InitFromObj(monster2)
+ for sizePrefix in [True, False]:
+ # Re-serializes the data into a buffer
+ b2 = flatbuffers.Builder(0)
+ if sizePrefix:
+ b2.FinishSizePrefixed(monsterT2.Pack(b2))
+ else:
+ b2.Finish(monsterT2.Pack(b2))
+ CheckReadBuffer(b2.Bytes, b2.Head(), sizePrefix)
+
+ def test_default_values_with_pack_and_unpack(self):
+ ''' Serializes and deserializes between a buffer with default values (no
+ specific values are filled when the buffer is created) and its python
+ object. '''
+ # Creates a flatbuffer with default values.
+ b1 = flatbuffers.Builder(0)
+ MyGame.Example.Monster.MonsterStart(b1)
+ gen_mon = MyGame.Example.Monster.MonsterEnd(b1)
+ b1.Finish(gen_mon)
+
+ # Converts the flatbuffer into the object class.
+ monster1 = MyGame.Example.Monster.Monster.GetRootAsMonster(b1.Bytes,
+ b1.Head())
+ monsterT1 = MyGame.Example.Monster.MonsterT.InitFromObj(monster1)
+
+ # Packs the object class into another flatbuffer.
+ b2 = flatbuffers.Builder(0)
+ b2.Finish(monsterT1.Pack(b2))
+ monster2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b2.Bytes,
+ b2.Head())
+ # Checks the default values.
+ self.assertTrue(monster2.Pos() is None)
+ self.assertEqual(monster2.Mana(),150)
+ self.assertEqual(monster2.Hp(), 100)
+ self.assertTrue(monster2.Name() is None)
+ self.assertEqual(monster2.Inventory(0), 0)
+ self.assertEqual(monster2.InventoryAsNumpy(), 0)
+ self.assertEqual(monster2.InventoryLength(), 0)
+ self.assertTrue(monster2.InventoryIsNone())
+ self.assertTrue(monster2.Color() is 8)
+ self.assertEqual(monster2.TestType(), 0)
+ self.assertTrue(monster2.Test() is None)
+ self.assertTrue(monster2.Test4(0) is None)
+ self.assertEqual(monster2.Test4Length(), 0)
+ self.assertTrue(monster2.Test4IsNone())
+ self.assertTrue(monster2.Testarrayofstring(0) is "")
+ self.assertEqual(monster2.TestarrayofstringLength(), 0)
+ self.assertTrue(monster2.TestarrayofstringIsNone())
+ self.assertTrue(monster2.Testarrayoftables(0) is None)
+ self.assertEqual(monster2.TestarrayoftablesLength(), 0)
+ self.assertTrue(monster2.TestarrayoftablesIsNone())
+ self.assertTrue(monster2.Enemy() is None)
+ self.assertEqual(monster2.Testnestedflatbuffer(0), 0)
+ self.assertEqual(monster2.TestnestedflatbufferAsNumpy(), 0)
+ self.assertEqual(monster2.TestnestedflatbufferLength(), 0)
+ self.assertTrue(monster2.TestnestedflatbufferIsNone())
+ self.assertTrue(monster2.Testempty() is None)
+ self.assertTrue(monster2.Testbool() is False)
+ self.assertEqual(monster2.Testhashs32Fnv1(), 0)
+ self.assertEqual(monster2.Testhashu32Fnv1(), 0)
+ self.assertEqual(monster2.Testhashs64Fnv1(), 0)
+ self.assertEqual(monster2.Testhashu64Fnv1(), 0)
+ self.assertEqual(monster2.Testhashs32Fnv1a(), 0)
+ self.assertEqual(monster2.Testhashu32Fnv1a(), 0)
+ self.assertEqual(monster2.Testhashs64Fnv1a(), 0)
+ self.assertEqual(monster2.Testhashu64Fnv1a(), 0)
+ self.assertEqual(monster2.Testarrayofbools(0), 0)
+ self.assertEqual(monster2.TestarrayofboolsAsNumpy(), 0)
+ self.assertEqual(monster2.TestarrayofboolsLength(), 0)
+ self.assertTrue(monster2.TestarrayofboolsIsNone())
+ self.assertEqual(monster2.Testf(), 3.14159)
+ self.assertEqual(monster2.Testf2(), 3.0)
+ self.assertEqual(monster2.Testf3(), 0.0)
+ self.assertTrue(monster2.Testarrayofstring2(0) is "")
+ self.assertEqual(monster2.Testarrayofstring2Length(), 0)
+ self.assertTrue(monster2.Testarrayofstring2IsNone())
+ self.assertTrue(monster2.Testarrayofsortedstruct(0) is None)
+ self.assertEqual(monster2.TestarrayofsortedstructLength(), 0)
+ self.assertTrue(monster2.TestarrayofsortedstructIsNone())
+ self.assertEqual(monster2.Flex(0), 0)
+ self.assertEqual(monster2.FlexAsNumpy(), 0)
+ self.assertEqual(monster2.FlexLength(), 0)
+ self.assertTrue(monster2.FlexIsNone())
+ self.assertTrue(monster2.Test5(0) is None)
+ self.assertEqual(monster2.Test5Length(), 0)
+ self.assertTrue(monster2.Test5IsNone())
+ self.assertEqual(monster2.VectorOfLongs(0), 0)
+ self.assertEqual(monster2.VectorOfLongsAsNumpy(), 0)
+ self.assertEqual(monster2.VectorOfLongsLength(), 0)
+ self.assertTrue(monster2.VectorOfLongsIsNone())
+ self.assertEqual(monster2.VectorOfDoubles(0), 0)
+ self.assertEqual(monster2.VectorOfDoublesAsNumpy(), 0)
+ self.assertEqual(monster2.VectorOfDoublesLength(), 0)
+ self.assertTrue(monster2.VectorOfDoublesIsNone())
+ self.assertTrue(monster2.ParentNamespaceTest() is None)
+ self.assertTrue(monster2.VectorOfReferrables(0) is None)
+ self.assertEqual(monster2.VectorOfReferrablesLength(), 0)
+ self.assertTrue(monster2.VectorOfReferrablesIsNone())
+ self.assertEqual(monster2.SingleWeakReference(), 0)
+ self.assertEqual(monster2.VectorOfWeakReferences(0), 0)
+ self.assertEqual(monster2.VectorOfWeakReferencesAsNumpy(), 0)
+ self.assertEqual(monster2.VectorOfWeakReferencesLength(), 0)
+ self.assertTrue(monster2.VectorOfWeakReferencesIsNone())
+ self.assertTrue(monster2.VectorOfStrongReferrables(0) is None)
+ self.assertEqual(monster2.VectorOfStrongReferrablesLength(), 0)
+ self.assertTrue(monster2.VectorOfStrongReferrablesIsNone())
+ self.assertEqual(monster2.CoOwningReference(), 0)
+ self.assertEqual(monster2.VectorOfCoOwningReferences(0), 0)
+ self.assertEqual(monster2.VectorOfCoOwningReferencesAsNumpy(), 0)
+ self.assertEqual(monster2.VectorOfCoOwningReferencesLength(), 0)
+ self.assertTrue(monster2.VectorOfCoOwningReferencesIsNone())
+ self.assertEqual(monster2.NonOwningReference(), 0)
+ self.assertEqual(monster2.VectorOfNonOwningReferences(0), 0)
+ self.assertEqual(monster2.VectorOfNonOwningReferencesAsNumpy(), 0)
+ self.assertEqual(monster2.VectorOfNonOwningReferencesLength(), 0)
+ self.assertTrue(monster2.VectorOfNonOwningReferencesIsNone())
+ self.assertEqual(monster2.AnyUniqueType(), 0)
+ self.assertTrue(monster2.AnyUnique() is None)
+ self.assertEqual(monster2.AnyAmbiguousType(), 0)
+ self.assertTrue(monster2.AnyAmbiguous() is None)
+ self.assertEqual(monster2.VectorOfEnums(0), 0)
+ self.assertEqual(monster2.VectorOfEnumsAsNumpy(), 0)
+ self.assertEqual(monster2.VectorOfEnumsLength(), 0)
+ self.assertTrue(monster2.VectorOfEnumsIsNone())
+
+
+class TestAllMutableCodePathsOfExampleSchema(unittest.TestCase):
+ ''' Tests the object API generated for monster_test.fbs for mutation
+ purposes. In each test, the default values will be changed through the
+ object API. We'll then pack the object class into the buf class and read
+ the updated values out from it to validate if the values are mutated as
+ expected.'''
+
+ def setUp(self, *args, **kwargs):
+ super(TestAllMutableCodePathsOfExampleSchema, self).setUp(*args,
+ **kwargs)
+ # Creates an empty monster flatbuffer, and loads it into the object
+ # class for future tests.
+ b = flatbuffers.Builder(0)
+ MyGame.Example.Monster.MonsterStart(b)
+ self.monsterT = self._create_and_load_object_class(b)
+
+ def _pack_and_load_buf_class(self, monsterT):
+ ''' Packs the object class into a flatbuffer and loads it into a buf
+ class.'''
+ b = flatbuffers.Builder(0)
+ b.Finish(monsterT.Pack(b))
+ monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ return monster
+
+ def _create_and_load_object_class(self, b):
+ ''' Finishs the creation of a monster flatbuffer and loads it into an
+ object class.'''
+ gen_mon = MyGame.Example.Monster.MonsterEnd(b)
+ b.Finish(gen_mon)
+ monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ monsterT = MyGame.Example.Monster.MonsterT()
+ monsterT.InitFromObj(monster)
+ return monsterT
+
+ def test_mutate_pos(self):
+ posT = MyGame.Example.Vec3.Vec3T()
+ posT.x = 4.0
+ posT.y = 5.0
+ posT.z = 6.0
+ posT.test1 = 6.0
+ posT.test2 = 7
+ test3T = MyGame.Example.Test.TestT()
+ test3T.a = 8
+ test3T.b = 9
+ posT.test3 = test3T
+ self.monsterT.pos = posT
+
+ # Packs the updated values.
+ monster = self._pack_and_load_buf_class(self.monsterT)
+
+ # Checks if values are loaded correctly into the object class.
+ pos = monster.Pos()
+
+ # Verifies the properties of the Vec3.
+ self.assertEqual(pos.X(), 4.0)
+ self.assertEqual(pos.Y(), 5.0)
+ self.assertEqual(pos.Z(), 6.0)
+ self.assertEqual(pos.Test1(), 6.0)
+ self.assertEqual(pos.Test2(), 7)
+ t3 = MyGame.Example.Test.Test()
+ t3 = pos.Test3(t3)
+ self.assertEqual(t3.A(), 8)
+ self.assertEqual(t3.B(), 9)
+
+ def test_mutate_mana(self):
+ self.monsterT.mana = 200
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Mana(), 200)
+
+ def test_mutate_hp(self):
+ self.monsterT.hp = 200
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Hp(), 200)
+
+ def test_mutate_name(self):
+ self.monsterT.name = "MyMonster"
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Name(), b"MyMonster")
+
+ def test_mutate_inventory(self):
+ self.monsterT.inventory = [1, 7, 8]
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Inventory(0), 1)
+ self.assertEqual(monster.Inventory(1), 7)
+ self.assertEqual(monster.Inventory(2), 8)
+
+ def test_empty_inventory(self):
+ self.monsterT.inventory = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.InventoryIsNone())
+
+ def test_mutate_color(self):
+ self.monsterT.color = MyGame.Example.Color.Color.Red
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Color(), MyGame.Example.Color.Color.Red)
+
+ def test_mutate_testtype(self):
+ self.monsterT.testType = MyGame.Example.Any.Any.Monster
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.TestType(), MyGame.Example.Any.Any.Monster)
+
+ def test_mutate_test(self):
+ testT = MyGame.Example.Monster.MonsterT()
+ testT.hp = 200
+ self.monsterT.test = testT
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ # Initializes a Table from a union field Test(...).
+ table = monster.Test()
+
+ # Initializes a Monster from the Table from the union.
+ test_monster = MyGame.Example.Monster.Monster()
+ test_monster.Init(table.Bytes, table.Pos)
+ self.assertEqual(test_monster.Hp(), 200)
+
+ def test_mutate_test4(self):
+ test0T = MyGame.Example.Test.TestT()
+ test0T.a = 10
+ test0T.b = 20
+ test1T = MyGame.Example.Test.TestT()
+ test1T.a = 30
+ test1T.b = 40
+ self.monsterT.test4 = [test0T, test1T]
+
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ test0 = monster.Test4(0)
+ self.assertEqual(test0.A(), 10)
+ self.assertEqual(test0.B(), 20)
+ test1 = monster.Test4(1)
+ self.assertEqual(test1.A(), 30)
+ self.assertEqual(test1.B(), 40)
+
+ def test_empty_test4(self):
+ self.monsterT.test4 = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.Test4IsNone())
+
+ def test_mutate_testarrayofstring(self):
+ self.monsterT.testarrayofstring = []
+ self.monsterT.testarrayofstring.append("test1")
+ self.monsterT.testarrayofstring.append("test2")
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Testarrayofstring(0), b"test1")
+ self.assertEqual(monster.Testarrayofstring(1), b"test2")
+
+ def test_empty_testarrayofstring(self):
+ self.monsterT.testarrayofstring = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.TestarrayofstringIsNone())
+
+ def test_mutate_testarrayoftables(self):
+ monsterT0 = MyGame.Example.Monster.MonsterT()
+ monsterT0.hp = 200
+ monsterT1 = MyGame.Example.Monster.MonsterT()
+ monsterT1.hp = 400
+ self.monsterT.testarrayoftables = []
+ self.monsterT.testarrayoftables.append(monsterT0)
+ self.monsterT.testarrayoftables.append(monsterT1)
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Testarrayoftables(0).Hp(), 200)
+ self.assertEqual(monster.Testarrayoftables(1).Hp(), 400)
+
+ def test_empty_testarrayoftables(self):
+ self.monsterT.testarrayoftables = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.TestarrayoftablesIsNone())
+
+ def test_mutate_enemy(self):
+ monsterT = MyGame.Example.Monster.MonsterT()
+ monsterT.hp = 200
+ self.monsterT.enemy = monsterT
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Enemy().Hp(), 200)
+
+ def test_mutate_testnestedflatbuffer(self):
+ self.monsterT.testnestedflatbuffer = [8, 2, 4]
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Testnestedflatbuffer(0), 8)
+ self.assertEqual(monster.Testnestedflatbuffer(1), 2)
+ self.assertEqual(monster.Testnestedflatbuffer(2), 4)
+
+ def test_empty_testnestedflatbuffer(self):
+ self.monsterT.testnestedflatbuffer = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.TestnestedflatbufferIsNone())
+
+ def test_mutate_testbool(self):
+ self.monsterT.testbool = True
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertTrue(monster.Testbool())
+
+ def test_mutate_testhashes(self):
+ self.monsterT.testhashs32Fnv1 = 1
+ self.monsterT.testhashu32Fnv1 = 2
+ self.monsterT.testhashs64Fnv1 = 3
+ self.monsterT.testhashu64Fnv1 = 4
+ self.monsterT.testhashs32Fnv1a = 5
+ self.monsterT.testhashu32Fnv1a = 6
+ self.monsterT.testhashs64Fnv1a = 7
+ self.monsterT.testhashu64Fnv1a = 8
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Testhashs32Fnv1(), 1)
+ self.assertEqual(monster.Testhashu32Fnv1(), 2)
+ self.assertEqual(monster.Testhashs64Fnv1(), 3)
+ self.assertEqual(monster.Testhashu64Fnv1(), 4)
+ self.assertEqual(monster.Testhashs32Fnv1a(), 5)
+ self.assertEqual(monster.Testhashu32Fnv1a(), 6)
+ self.assertEqual(monster.Testhashs64Fnv1a(), 7)
+ self.assertEqual(monster.Testhashu64Fnv1a(), 8)
+
+ def test_mutate_testarrayofbools(self):
+ self.monsterT.testarrayofbools = []
+ self.monsterT.testarrayofbools.append(True)
+ self.monsterT.testarrayofbools.append(True)
+ self.monsterT.testarrayofbools.append(False)
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Testarrayofbools(0), True)
+ self.assertEqual(monster.Testarrayofbools(1), True)
+ self.assertEqual(monster.Testarrayofbools(2), False)
+
+ def test_empty_testarrayofbools(self):
+ self.monsterT.testarrayofbools = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.TestarrayofboolsIsNone())
+
+ def test_mutate_testf(self):
+ self.monsterT.testf = 2.0
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.Testf(), 2.0)
+
+ def test_mutate_vectoroflongs(self):
+ self.monsterT.vectorOfLongs = []
+ self.monsterT.vectorOfLongs.append(1)
+ self.monsterT.vectorOfLongs.append(100)
+ self.monsterT.vectorOfLongs.append(10000)
+ self.monsterT.vectorOfLongs.append(1000000)
+ self.monsterT.vectorOfLongs.append(100000000)
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.VectorOfLongs(0), 1)
+ self.assertEqual(monster.VectorOfLongs(1), 100)
+ self.assertEqual(monster.VectorOfLongs(2), 10000)
+ self.assertEqual(monster.VectorOfLongs(3), 1000000)
+ self.assertEqual(monster.VectorOfLongs(4), 100000000)
+
+ def test_empty_vectoroflongs(self):
+ self.monsterT.vectorOfLongs = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.VectorOfLongsIsNone())
+
+ def test_mutate_vectorofdoubles(self):
+ self.monsterT.vectorOfDoubles = []
+ self.monsterT.vectorOfDoubles.append(-1.7976931348623157e+308)
+ self.monsterT.vectorOfDoubles.append(0)
+ self.monsterT.vectorOfDoubles.append(1.7976931348623157e+308)
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.VectorOfDoubles(0), -1.7976931348623157e+308)
+ self.assertEqual(monster.VectorOfDoubles(1), 0)
+ self.assertEqual(monster.VectorOfDoubles(2), 1.7976931348623157e+308)
+
+ def test_empty_vectorofdoubles(self):
+ self.monsterT.vectorOfDoubles = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.VectorOfDoublesIsNone())
+
+ def test_mutate_parentnamespacetest(self):
+ self.monsterT.parentNamespaceTest = MyGame.InParentNamespace.InParentNamespaceT()
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertTrue(isinstance(monster.ParentNamespaceTest(),
+ MyGame.InParentNamespace.InParentNamespace))
+
+ def test_mutate_vectorofEnums(self):
+ self.monsterT.vectorOfEnums = []
+ self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Red)
+ self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Blue)
+ self.monsterT.vectorOfEnums.append(MyGame.Example.Color.Color.Red)
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertEqual(monster.VectorOfEnums(0),
+ MyGame.Example.Color.Color.Red)
+ self.assertEqual(monster.VectorOfEnums(1),
+ MyGame.Example.Color.Color.Blue)
+ self.assertEqual(monster.VectorOfEnums(2),
+ MyGame.Example.Color.Color.Red)
+
+ def test_empty_vectorofEnums(self):
+ self.monsterT.vectorOfEnums = []
+ monster = self._pack_and_load_buf_class(self.monsterT)
+ self.assertFalse(monster.VectorOfEnumsIsNone())
+
+
+def CheckReadBuffer(buf, offset, sizePrefix=False, file_identifier=None):
''' CheckReadBuffer checks that the given buffer is evaluated correctly
as the example Monster. '''
@@ -86,12 +535,19 @@ def CheckReadBuffer(buf, offset, sizePrefix = False):
''' An assertion helper that is separated from TestCase classes. '''
if not stmt:
raise AssertionError('CheckReadBuffer case failed')
-
+ if file_identifier:
+ # test prior to removal of size_prefix
+ asserter(util.GetBufferIdentifier(buf, offset, size_prefixed=sizePrefix) == file_identifier)
+ asserter(util.BufferHasIdentifier(buf, offset, file_identifier=file_identifier, size_prefixed=sizePrefix))
+ asserter(MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset, size_prefixed=sizePrefix))
if sizePrefix:
size = util.GetSizePrefix(buf, offset)
- # taken from the size of monsterdata_python_wire.mon, minus 4
- asserter(size == 340)
+ asserter(size == len(buf[offset:])-4)
buf, offset = util.RemoveSizePrefix(buf, offset)
+ if file_identifier:
+ asserter(MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
+ else:
+ asserter(not MyGame.Example.Monster.Monster.MonsterBufferHasIdentifier(buf, offset))
monster = MyGame.Example.Monster.Monster.GetRootAsMonster(buf, offset)
asserter(monster.Hp() == 80)
@@ -134,6 +590,7 @@ def CheckReadBuffer(buf, offset, sizePrefix = False):
# iterate through the first monster's inventory:
asserter(monster.InventoryLength() == 5)
+ asserter(not monster.InventoryIsNone())
invsum = 0
for i in compat_range(monster.InventoryLength()):
@@ -144,6 +601,7 @@ def CheckReadBuffer(buf, offset, sizePrefix = False):
for i in range(5):
asserter(monster.VectorOfLongs(i) == 10 ** (i * 2))
+ asserter(not monster.VectorOfDoublesIsNone())
asserter(([-1.7976931348623157e+308, 0, 1.7976931348623157e+308]
== [monster.VectorOfDoubles(i)
for i in range(monster.VectorOfDoublesLength())]))
@@ -176,6 +634,7 @@ def CheckReadBuffer(buf, offset, sizePrefix = False):
pass
asserter(monster.Test4Length() == 2)
+ asserter(not monster.Test4IsNone())
# create a 'Test' object and populate it:
test0 = monster.Test4(0)
@@ -194,11 +653,14 @@ def CheckReadBuffer(buf, offset, sizePrefix = False):
asserter(sumtest12 == 100)
+ asserter(not monster.TestarrayofstringIsNone())
asserter(monster.TestarrayofstringLength() == 2)
asserter(monster.Testarrayofstring(0) == b"test1")
asserter(monster.Testarrayofstring(1) == b"test2")
+ asserter(monster.TestarrayoftablesIsNone())
asserter(monster.TestarrayoftablesLength() == 0)
+ asserter(monster.TestnestedflatbufferIsNone())
asserter(monster.TestnestedflatbufferLength() == 0)
asserter(monster.Testempty() is None)
@@ -1079,7 +1541,7 @@ class TestByteLayout(unittest.TestCase):
])
-def make_monster_from_generated_code(sizePrefix = False):
+def make_monster_from_generated_code(sizePrefix = False, file_identifier=None):
''' Use generated code to build the example Monster. '''
b = flatbuffers.Builder(0)
@@ -1141,13 +1603,48 @@ def make_monster_from_generated_code(sizePrefix = False):
mon = MyGame.Example.Monster.MonsterEnd(b)
if sizePrefix:
- b.FinishSizePrefixed(mon)
+ b.FinishSizePrefixed(mon, file_identifier)
else:
- b.Finish(mon)
+ b.Finish(mon, file_identifier)
return b.Bytes, b.Head()
+class TestBuilderForceDefaults(unittest.TestCase):
+ """Verify that the builder adds default values when forced."""
+
+ test_flags = [N.BoolFlags(), N.Uint8Flags(), N.Uint16Flags(), \
+ N.Uint32Flags(), N.Uint64Flags(), N.Int8Flags(), \
+ N.Int16Flags(), N.Int32Flags(), N.Int64Flags(), \
+ N.Float32Flags(), N.Float64Flags(), N.UOffsetTFlags()]
+ def test_default_force_defaults(self):
+ for flag in self.test_flags:
+ b = flatbuffers.Builder(0)
+ b.StartObject(1)
+ stored_offset = b.Offset()
+ if flag != N.UOffsetTFlags():
+ b.PrependSlot(flag, 0, 0, 0)
+ else:
+ b.PrependUOffsetTRelativeSlot(0, 0, 0)
+ end_offset = b.Offset()
+ b.EndObject()
+ self.assertEqual(0, end_offset - stored_offset)
+
+ def test_force_defaults_true(self):
+ for flag in self.test_flags:
+ b = flatbuffers.Builder(0)
+ b.ForceDefaults(True)
+ b.StartObject(1)
+ stored_offset = b.Offset()
+ if flag != N.UOffsetTFlags():
+ b.PrependSlot(flag, 0, 0, 0)
+ else:
+ b.PrependUOffsetTRelativeSlot(0, 0, 0)
+ end_offset = b.Offset()
+ b.EndObject()
+ self.assertEqual(flag.bytewidth, end_offset - stored_offset)
+
+
class TestAllCodePathsOfExampleSchema(unittest.TestCase):
def setUp(self, *args, **kwargs):
super(TestAllCodePathsOfExampleSchema, self).setUp(*args, **kwargs)
@@ -1185,6 +1682,19 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
def test_default_monster_inventory_length(self):
self.assertEqual(0, self.mon.InventoryLength())
+ self.assertTrue(self.mon.InventoryIsNone())
+
+ def test_empty_monster_inventory_vector(self):
+ b = flatbuffers.Builder(0)
+ MyGame.Example.Monster.MonsterStartInventoryVector(b, 0)
+ inv = b.EndVector(0)
+ MyGame.Example.Monster.MonsterStart(b)
+ MyGame.Example.Monster.MonsterAddInventory(b, inv)
+ mon = MyGame.Example.Monster.MonsterEnd(b)
+ b.Finish(mon)
+ mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ self.assertFalse(mon2.InventoryIsNone())
def test_default_monster_color(self):
self.assertEqual(MyGame.Example.Color.Color.Blue, self.mon.Color())
@@ -1212,12 +1722,38 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
def test_default_monster_test4_length(self):
self.assertEqual(0, self.mon.Test4Length())
+ self.assertTrue(self.mon.Test4IsNone())
+
+ def test_empty_monster_test4_vector(self):
+ b = flatbuffers.Builder(0)
+ MyGame.Example.Monster.MonsterStartTest4Vector(b, 0)
+ test4 = b.EndVector(0)
+ MyGame.Example.Monster.MonsterStart(b)
+ MyGame.Example.Monster.MonsterAddTest4(b, test4)
+ mon = MyGame.Example.Monster.MonsterEnd(b)
+ b.Finish(mon)
+ mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ self.assertFalse(mon2.Test4IsNone())
def test_default_monster_testarrayofstring(self):
self.assertEqual("", self.mon.Testarrayofstring(0))
def test_default_monster_testarrayofstring_length(self):
self.assertEqual(0, self.mon.TestarrayofstringLength())
+ self.assertTrue(self.mon.TestarrayofstringIsNone())
+
+ def test_empty_monster_testarrayofstring_vector(self):
+ b = flatbuffers.Builder(0)
+ MyGame.Example.Monster.MonsterStartTestarrayofstringVector(b, 0)
+ testarrayofstring = b.EndVector(0)
+ MyGame.Example.Monster.MonsterStart(b)
+ MyGame.Example.Monster.MonsterAddTestarrayofstring(b, testarrayofstring)
+ mon = MyGame.Example.Monster.MonsterEnd(b)
+ b.Finish(mon)
+ mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ self.assertFalse(mon2.TestarrayofstringIsNone())
def test_default_monster_testarrayoftables(self):
self.assertEqual(None, self.mon.Testarrayoftables(0))
@@ -1245,6 +1781,23 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Output(), 0)
self.assertEqual(99, mon2.Testarrayoftables(0).Hp())
self.assertEqual(1, mon2.TestarrayoftablesLength())
+ self.assertFalse(mon2.TestarrayoftablesIsNone())
+
+ def test_default_monster_testarrayoftables_length(self):
+ self.assertEqual(0, self.mon.TestarrayoftablesLength())
+ self.assertTrue(self.mon.TestarrayoftablesIsNone())
+
+ def test_empty_monster_testarrayoftables_vector(self):
+ b = flatbuffers.Builder(0)
+ MyGame.Example.Monster.MonsterStartTestarrayoftablesVector(b, 0)
+ testarrayoftables = b.EndVector(0)
+ MyGame.Example.Monster.MonsterStart(b)
+ MyGame.Example.Monster.MonsterAddTestarrayoftables(b, testarrayoftables)
+ mon = MyGame.Example.Monster.MonsterEnd(b)
+ b.Finish(mon)
+ mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ self.assertFalse(mon2.TestarrayoftablesIsNone())
def test_default_monster_testarrayoftables_length(self):
self.assertEqual(0, self.mon.TestarrayoftablesLength())
@@ -1274,6 +1827,19 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
def test_default_monster_testnestedflatbuffer_length(self):
self.assertEqual(0, self.mon.TestnestedflatbufferLength())
+ self.assertTrue(self.mon.TestnestedflatbufferIsNone())
+
+ def test_empty_monster_testnestedflatbuffer_vector(self):
+ b = flatbuffers.Builder(0)
+ MyGame.Example.Monster.MonsterStartTestnestedflatbufferVector(b, 0)
+ testnestedflatbuffer = b.EndVector(0)
+ MyGame.Example.Monster.MonsterStart(b)
+ MyGame.Example.Monster.MonsterAddTestnestedflatbuffer(b, testnestedflatbuffer)
+ mon = MyGame.Example.Monster.MonsterEnd(b)
+ b.Finish(mon)
+ mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ self.assertFalse(mon2.TestnestedflatbufferIsNone())
def test_nondefault_monster_testnestedflatbuffer(self):
b = flatbuffers.Builder(0)
@@ -1294,6 +1860,7 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
mon2 = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
b.Head())
self.assertEqual(3, mon2.TestnestedflatbufferLength())
+ self.assertFalse(mon2.TestnestedflatbufferIsNone())
self.assertEqual(0, mon2.Testnestedflatbuffer(0))
self.assertEqual(2, mon2.Testnestedflatbuffer(1))
self.assertEqual(4, mon2.Testnestedflatbuffer(2))
@@ -1378,6 +1945,24 @@ class TestAllCodePathsOfExampleSchema(unittest.TestCase):
self.assertEqual(7, mon2.Testhashs64Fnv1a())
self.assertEqual(8, mon2.Testhashu64Fnv1a())
+ def test_default_monster_parent_namespace_test(self):
+ self.assertEqual(None, self.mon.ParentNamespaceTest())
+
+ def test_nondefault_monster_parent_namespace_test(self):
+ b = flatbuffers.Builder(0)
+ MyGame.InParentNamespace.InParentNamespaceStart(b)
+ parent = MyGame.InParentNamespace.InParentNamespaceEnd(b)
+ MyGame.Example.Monster.MonsterStart(b)
+ MyGame.Example.Monster.MonsterAddParentNamespaceTest(b, parent)
+ mon = MyGame.Example.Monster.MonsterEnd(b)
+ b.Finish(mon)
+
+ # Inspect the resulting data.
+ monster = MyGame.Example.Monster.Monster.GetRootAsMonster(b.Bytes,
+ b.Head())
+ self.assertTrue(isinstance(monster.ParentNamespaceTest(),
+ MyGame.InParentNamespace.InParentNamespace))
+
def test_getrootas_for_nonroot_table(self):
b = flatbuffers.Builder(0)
string = b.CreateString("MyStat")
@@ -1408,13 +1993,13 @@ class TestAllCodePathsOfMonsterExtraSchema(unittest.TestCase):
self.mon = MyGame.MonsterExtra.MonsterExtra.GetRootAsMonsterExtra(b.Bytes, b.Head())
def test_default_nan_inf(self):
- self.assertTrue(math.isnan(self.mon.TestfNan()))
- self.assertEqual(self.mon.TestfPinf(), float("inf"))
- self.assertEqual(self.mon.TestfNinf(), float("-inf"))
+ self.assertTrue(math.isnan(self.mon.F1()))
+ self.assertEqual(self.mon.F2(), float("inf"))
+ self.assertEqual(self.mon.F3(), float("-inf"))
- self.assertTrue(math.isnan(self.mon.TestdNan()))
- self.assertEqual(self.mon.TestdPinf(), float("inf"))
- self.assertEqual(self.mon.TestdNinf(), float("-inf"))
+ self.assertTrue(math.isnan(self.mon.D1()))
+ self.assertEqual(self.mon.D2(), float("inf"))
+ self.assertEqual(self.mon.D3(), float("-inf"))
class TestVtableDeduplication(unittest.TestCase):
@@ -1543,6 +2128,62 @@ class TestExceptions(unittest.TestCase):
flatbuffers.builder.BuilderNotFinishedError)
+class TestFixedLengthArrays(unittest.TestCase):
+ def test_fixed_length_array(self):
+ builder = flatbuffers.Builder(0)
+
+ a = 0.5
+ b = range(0, 15)
+ c = 1
+ d_a = [[1, 2], [3, 4]]
+ d_b = [MyGame.Example.TestEnum.TestEnum.B, \
+ MyGame.Example.TestEnum.TestEnum.C]
+ d_c = [[MyGame.Example.TestEnum.TestEnum.A, \
+ MyGame.Example.TestEnum.TestEnum.B], \
+ [MyGame.Example.TestEnum.TestEnum.C, \
+ MyGame.Example.TestEnum.TestEnum.B]]
+ d_d = [[-1, 1], [-2, 2]]
+ e = 2
+ f = [-1, 1]
+
+ arrayOffset = MyGame.Example.ArrayStruct.CreateArrayStruct(builder, \
+ a, b, c, d_a, d_b, d_c, d_d, e, f)
+
+ # Create a table with the ArrayStruct.
+ MyGame.Example.ArrayTable.ArrayTableStart(builder)
+ MyGame.Example.ArrayTable.ArrayTableAddA(builder, arrayOffset)
+ tableOffset = MyGame.Example.ArrayTable.ArrayTableEnd(builder)
+
+ builder.Finish(tableOffset)
+
+ buf = builder.Output()
+
+ table = MyGame.Example.ArrayTable.ArrayTable.GetRootAsArrayTable(buf, 0)
+
+ # Verify structure.
+ nested = MyGame.Example.NestedStruct.NestedStruct()
+ self.assertEqual(table.A().A(), 0.5)
+ self.assertEqual(table.A().B(), \
+ [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])
+ self.assertEqual(table.A().C(), 1)
+ self.assertEqual(table.A().D(nested, 0).A(), [1, 2])
+ self.assertEqual(table.A().D(nested, 1).A(), [3, 4])
+ self.assertEqual(table.A().D(nested, 0).B(), \
+ MyGame.Example.TestEnum.TestEnum.B)
+ self.assertEqual(table.A().D(nested, 1).B(), \
+ MyGame.Example.TestEnum.TestEnum.C)
+ self.assertEqual(table.A().D(nested, 0).C(), \
+ [MyGame.Example.TestEnum.TestEnum.A, \
+ MyGame.Example.TestEnum.TestEnum.B])
+ self.assertEqual(table.A().D(nested, 1).C(), \
+ [MyGame.Example.TestEnum.TestEnum.C, \
+ MyGame.Example.TestEnum.TestEnum.B])
+ self.assertEqual(table.A().D(nested, 0).D(), [-1, 1])
+ self.assertEqual(table.A().D(nested, 1).D(), [-2, 2])
+ self.assertEqual(table.A().E(), 2)
+ self.assertEqual(table.A().F(), [-1, 1])
+
+
def CheckAgainstGoldDataGo():
try:
gen_buf, gen_off = make_monster_from_generated_code()
@@ -1617,26 +2258,40 @@ def BenchmarkVtableDeduplication(count):
When count is large (as in long benchmarks), memory usage may be high.
'''
- prePop = 10
- builder = flatbuffers.Builder(0)
-
- # pre-populate some vtables:
- for i in compat_range(prePop):
- builder.StartObject(i)
- for j in compat_range(i):
- builder.PrependInt16Slot(j, j, 0)
- builder.EndObject()
-
- # benchmark deduplication of a new vtable:
- def f():
- builder.StartObject(prePop)
- for j in compat_range(prePop):
- builder.PrependInt16Slot(j, j, 0)
- builder.EndObject()
-
- duration = timeit.timeit(stmt=f, number=count)
- rate = float(count) / duration
- print(('vtable deduplication rate: %.2f/sec' % rate))
+ for prePop in (1, 10, 100, 1000):
+ builder = flatbuffers.Builder(0)
+ n = 1 + int(math.log(prePop, 1.5))
+
+ # generate some layouts:
+ layouts = set()
+ r = list(compat_range(n))
+ while len(layouts) < prePop:
+ layouts.add(tuple(sorted(random.sample(r, int(max(1, n / 2))))))
+
+ layouts = list(layouts)
+
+ # pre-populate vtables:
+ for layout in layouts:
+ builder.StartObject(n)
+ for j in layout:
+ builder.PrependInt16Slot(j, j, 0)
+ builder.EndObject()
+
+ # benchmark deduplication of a new vtable:
+ def f():
+ layout = random.choice(layouts)
+ builder.StartObject(n)
+ for j in layout:
+ builder.PrependInt16Slot(j, j, 0)
+ builder.EndObject()
+
+ duration = timeit.timeit(stmt=f, number=count)
+ rate = float(count) / duration
+ print(('vtable deduplication rate (n=%d, vtables=%d): %.2f sec' % (
+ prePop,
+ len(builder.vtables),
+ rate))
+ )
def BenchmarkCheckReadBuffer(count, buf, off):
@@ -1714,6 +2369,13 @@ def main():
kwargs = dict(argv=sys.argv[:-3])
+ # show whether numpy is present, as it changes the test logic:
+ try:
+ import numpy
+ print('numpy available')
+ except ImportError:
+ print('numpy not available')
+
# run tests, and run some language comparison checks if needed:
success = backward_compatible_run_tests(**kwargs)
if success and os.environ.get('COMPARE_GENERATED_TO_GO', 0) == "1":
diff --git a/tests/rust_usage_test/Cargo.toml b/tests/rust_usage_test/Cargo.toml
index 490d6d24..6178849d 100644
--- a/tests/rust_usage_test/Cargo.toml
+++ b/tests/rust_usage_test/Cargo.toml
@@ -19,6 +19,7 @@ path = "bin/alloc_check.rs"
quickcheck = "0.6"
# TODO(rw): look into moving to criterion.rs
bencher = "0.1.5"
+static_assertions = "1.0.0"
[[bench]]
# setup for bencher
diff --git a/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs b/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
index 2c6be1f3..d38b8b4b 100644
--- a/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
+++ b/tests/rust_usage_test/benches/flatbuffers_benchmarks.rs
@@ -21,6 +21,14 @@ use bencher::Bencher;
extern crate flatbuffers;
#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
+
+#[allow(dead_code, unused_imports)]
#[path = "../../monster_test_generated.rs"]
mod monster_test_generated;
pub use monster_test_generated::my_game;
diff --git a/tests/rust_usage_test/bin/alloc_check.rs b/tests/rust_usage_test/bin/alloc_check.rs
index ae1039cb..26f38e3a 100644
--- a/tests/rust_usage_test/bin/alloc_check.rs
+++ b/tests/rust_usage_test/bin/alloc_check.rs
@@ -29,6 +29,14 @@ static A: TrackingAllocator = TrackingAllocator;
// import the flatbuffers generated code:
extern crate flatbuffers;
#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
+
+#[allow(dead_code, unused_imports)]
#[path = "../../monster_test_generated.rs"]
mod monster_test_generated;
pub use monster_test_generated::my_game;
@@ -106,10 +114,13 @@ fn main() {
assert_eq!("MyMonster", m.name());
let pos = m.pos().unwrap();
- assert_eq!(pos.x(), 1.0f32);
- assert_eq!(pos.y(), 2.0f32);
- assert_eq!(pos.z(), 3.0f32);
- assert_eq!(pos.test1(), 3.0f64);
+ // We know the bits should be exactly equal here but compilers may
+ // optimize floats in subtle ways so we're playing it safe and using
+ // epsilon comparison
+ assert!((pos.x() - 1.0f32).abs() < std::f32::EPSILON);
+ assert!((pos.y() - 2.0f32).abs() < std::f32::EPSILON);
+ assert!((pos.z() - 3.0f32).abs() < std::f32::EPSILON);
+ assert!((pos.test1() - 3.0f64).abs() < std::f64::EPSILON);
assert_eq!(pos.test2(), my_game::example::Color::Green);
let pos_test3 = pos.test3();
assert_eq!(pos_test3.a(), 5i16);
@@ -126,8 +137,8 @@ fn main() {
let test4 = m.test4().unwrap();
assert_eq!(test4.len(), 2);
- assert_eq!(test4[0].a() as i32 + test4[0].b() as i32 +
- test4[1].a() as i32 + test4[1].b() as i32, 100);
+ assert_eq!(i32::from(test4[0].a()) + i32::from(test4[1].a()) +
+ i32::from(test4[0].b()) + i32::from(test4[1].b()), 100);
let testarrayofstring = m.testarrayofstring().unwrap();
assert_eq!(testarrayofstring.len(), 2);
diff --git a/tests/rust_usage_test/bin/monster_example.rs b/tests/rust_usage_test/bin/monster_example.rs
index 3c9a0a0e..fe172db1 100644
--- a/tests/rust_usage_test/bin/monster_example.rs
+++ b/tests/rust_usage_test/bin/monster_example.rs
@@ -1,10 +1,19 @@
extern crate flatbuffers;
#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
+
+#[allow(dead_code, unused_imports)]
#[path = "../../monster_test_generated.rs"]
mod monster_test_generated;
pub use monster_test_generated::my_game;
+
use std::io::Read;
fn main() {
diff --git a/tests/rust_usage_test/tests/integration_test.rs b/tests/rust_usage_test/tests/integration_test.rs
index 0dace96d..ae5c2343 100644
--- a/tests/rust_usage_test/tests/integration_test.rs
+++ b/tests/rust_usage_test/tests/integration_test.rs
@@ -20,6 +20,14 @@ extern crate quickcheck;
extern crate flatbuffers;
#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/include_test1_generated.rs"]
+pub mod include_test1_generated;
+
+#[allow(dead_code, unused_imports)]
+#[path = "../../include_test/sub/include_test2_generated.rs"]
+pub mod include_test2_generated;
+
+#[allow(dead_code, unused_imports)]
#[path = "../../monster_test_generated.rs"]
mod monster_test_generated;
pub use monster_test_generated::my_game;
@@ -184,6 +192,7 @@ fn serialized_example_is_accessible_and_correct(bytes: &[u8], identifier_require
let inv = m.inventory().unwrap();
check_eq!(inv.len(), 5)?;
check_eq!(inv.iter().sum::<u8>(), 10u8)?;
+ check_eq!(inv.iter().rev().sum::<u8>(), 10u8)?;
check_is_some!(m.test4())?;
let test4 = m.test4().unwrap();
@@ -234,6 +243,87 @@ mod generated_constants {
fn monster_file_extension() {
assert_eq!("mon", my_game::example::MONSTER_EXTENSION);
}
+
+ #[test]
+ fn enum_constants_are_public() {
+ assert_eq!(1, my_game::example::ENUM_MIN_COLOR);
+ assert_eq!(8, my_game::example::ENUM_MAX_COLOR);
+ assert_eq!(my_game::example::ENUM_VALUES_COLOR, [
+ my_game::example::Color::Red,
+ my_game::example::Color::Green,
+ my_game::example::Color::Blue,
+ ]);
+ assert_eq!(my_game::example::ENUM_NAMES_COLOR, [
+ "Red",
+ "Green",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Blue"
+ ]);
+
+ assert_eq!(-1, my_game::example::ENUM_MIN_RACE);
+ assert_eq!(2, my_game::example::ENUM_MAX_RACE);
+ assert_eq!(my_game::example::ENUM_VALUES_RACE, [
+ my_game::example::Race::None,
+ my_game::example::Race::Human,
+ my_game::example::Race::Dwarf,
+ my_game::example::Race::Elf,
+ ]);
+ assert_eq!(my_game::example::ENUM_NAMES_RACE, [
+ "None",
+ "Human",
+ "Dwarf",
+ "Elf"
+ ]);
+
+ assert_eq!(0, my_game::example::ENUM_MIN_ANY);
+ assert_eq!(3, my_game::example::ENUM_MAX_ANY);
+ assert_eq!(my_game::example::ENUM_VALUES_ANY, [
+ my_game::example::Any::NONE,
+ my_game::example::Any::Monster,
+ my_game::example::Any::TestSimpleTableWithEnum,
+ my_game::example::Any::MyGame_Example2_Monster,
+ ]);
+ assert_eq!(my_game::example::ENUM_NAMES_ANY, [
+ "NONE",
+ "Monster",
+ "TestSimpleTableWithEnum",
+ "MyGame_Example2_Monster"
+ ]);
+
+ assert_eq!(0, my_game::example::ENUM_MIN_ANY_UNIQUE_ALIASES);
+ assert_eq!(3, my_game::example::ENUM_MAX_ANY_UNIQUE_ALIASES);
+ assert_eq!(my_game::example::ENUM_VALUES_ANY_UNIQUE_ALIASES, [
+ my_game::example::AnyUniqueAliases::NONE,
+ my_game::example::AnyUniqueAliases::M,
+ my_game::example::AnyUniqueAliases::TS,
+ my_game::example::AnyUniqueAliases::M2,
+ ]);
+ assert_eq!(my_game::example::ENUM_NAMES_ANY_UNIQUE_ALIASES, [
+ "NONE",
+ "M",
+ "TS",
+ "M2"
+ ]);
+
+ assert_eq!(0, my_game::example::ENUM_MIN_ANY_AMBIGUOUS_ALIASES);
+ assert_eq!(3, my_game::example::ENUM_MAX_ANY_AMBIGUOUS_ALIASES);
+ assert_eq!(my_game::example::ENUM_VALUES_ANY_AMBIGUOUS_ALIASES, [
+ my_game::example::AnyAmbiguousAliases::NONE,
+ my_game::example::AnyAmbiguousAliases::M1,
+ my_game::example::AnyAmbiguousAliases::M2,
+ my_game::example::AnyAmbiguousAliases::M3,
+ ]);
+ assert_eq!(my_game::example::ENUM_NAMES_ANY_AMBIGUOUS_ALIASES, [
+ "NONE",
+ "M1",
+ "M2",
+ "M3"
+ ]);
+ }
}
#[cfg(test)]
@@ -509,6 +599,18 @@ mod roundtrip_generated_code {
assert_eq!(m.testarrayofstring().unwrap().len(), 2);
assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
+
+ let rust_vec_inst = m.testarrayofstring().unwrap();
+ let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_collect.len(), 2);
+ assert_eq!(rust_vec_iter_collect[0], "foobar");
+ assert_eq!(rust_vec_iter_collect[1], "baz");
+
+ let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_rev_collect.len(), 2);
+ assert_eq!(rust_vec_iter_rev_collect[1], "foobar");
+ assert_eq!(rust_vec_iter_rev_collect[0], "baz");
+
}
#[test]
fn vector_of_string_store_manual_build() {
@@ -523,6 +625,17 @@ mod roundtrip_generated_code {
assert_eq!(m.testarrayofstring().unwrap().len(), 2);
assert_eq!(m.testarrayofstring().unwrap().get(0), "foobar");
assert_eq!(m.testarrayofstring().unwrap().get(1), "baz");
+
+ let rust_vec_inst = m.testarrayofstring().unwrap();
+ let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_collect.len(), 2);
+ assert_eq!(rust_vec_iter_collect[0], "foobar");
+ assert_eq!(rust_vec_iter_collect[1], "baz");
+
+ let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_rev_collect.len(), 2);
+ assert_eq!(rust_vec_iter_rev_collect[0], "baz");
+ assert_eq!(rust_vec_iter_rev_collect[1], "foobar");
}
#[test]
fn vector_of_ubyte_store() {
@@ -543,6 +656,13 @@ mod roundtrip_generated_code {
name: Some(name),
testarrayofbools: Some(v), ..Default::default()});
assert_eq!(m.testarrayofbools().unwrap(), &[false, true, false, true][..]);
+
+ let rust_vec_inst = m.testarrayofbools().unwrap();
+ let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_collect, &[&false, &true, &false, &true][..]);
+
+ let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_rev_collect, &[&true, &false, &true, &false][..]);
}
#[test]
fn vector_of_f64_store() {
@@ -554,6 +674,15 @@ mod roundtrip_generated_code {
vector_of_doubles: Some(v), ..Default::default()});
assert_eq!(m.vector_of_doubles().unwrap().len(), 1);
assert_eq!(m.vector_of_doubles().unwrap().get(0), 3.14159265359f64);
+
+ let rust_vec_inst = m.vector_of_doubles().unwrap();
+ let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_collect.len(), 1);
+ assert_eq!(rust_vec_iter_collect[0], 3.14159265359f64);
+
+ let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_rev_collect.len(), 1);
+ assert_eq!(rust_vec_iter_rev_collect[0], 3.14159265359f64);
}
#[test]
fn vector_of_struct_store() {
@@ -564,6 +693,13 @@ mod roundtrip_generated_code {
name: Some(name),
test4: Some(v), ..Default::default()});
assert_eq!(m.test4().unwrap(), &[my_game::example::Test::new(127, -128), my_game::example::Test::new(3, 123)][..]);
+
+ let rust_vec_inst = m.test4().unwrap();
+ let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_collect, &[&my_game::example::Test::new(127, -128), &my_game::example::Test::new(3, 123)][..]);
+
+ let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_rev_collect, &[&my_game::example::Test::new(3, 123), &my_game::example::Test::new(127, -128)][..]);
}
#[test]
fn vector_of_struct_store_with_type_inference() {
@@ -613,6 +749,21 @@ mod roundtrip_generated_code {
assert_eq!(m.testarrayoftables().unwrap().get(0).name(), "foo");
assert_eq!(m.testarrayoftables().unwrap().get(1).hp(), 100);
assert_eq!(m.testarrayoftables().unwrap().get(1).name(), "bar");
+
+ let rust_vec_inst = m.testarrayoftables().unwrap();
+ let rust_vec_iter_collect = rust_vec_inst.iter().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_collect.len(), 2);
+ assert_eq!(rust_vec_iter_collect[0].hp(), 55);
+ assert_eq!(rust_vec_iter_collect[0].name(), "foo");
+ assert_eq!(rust_vec_iter_collect[1].hp(), 100);
+ assert_eq!(rust_vec_iter_collect[1].name(), "bar");
+
+ let rust_vec_iter_rev_collect = rust_vec_inst.iter().rev().collect::<Vec<_>>();
+ assert_eq!(rust_vec_iter_rev_collect.len(), 2);
+ assert_eq!(rust_vec_iter_rev_collect[0].hp(), 100);
+ assert_eq!(rust_vec_iter_rev_collect[0].name(), "bar");
+ assert_eq!(rust_vec_iter_rev_collect[1].hp(), 55);
+ assert_eq!(rust_vec_iter_rev_collect[1].name(), "foo");
}
}
@@ -721,6 +872,12 @@ mod generated_code_alignment_and_padding {
let aln = ::std::mem::align_of::<my_game::example::Ability>();
assert_eq!((a_ptr - start_ptr) % aln, 0);
}
+ for a in abilities.iter().rev() {
+ let a_ptr = a as *const my_game::example::Ability as usize;
+ assert!(a_ptr > start_ptr);
+ let aln = ::std::mem::align_of::<my_game::example::Ability>();
+ assert_eq!((a_ptr - start_ptr) % aln, 0);
+ }
}
}
@@ -765,10 +922,12 @@ mod roundtrip_byteswap {
assert_eq!(x, back_again);
}
- #[test]
- fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
- #[test]
- fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
+ // TODO(rw): Replace the implementations with the new stdlib endian-conversion functions.
+ // TODO(rw): Re-enable these tests (currently, rare CI failures occur that seem spurious).
+ // #[test]
+ // fn fuzz_f32() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f32 as fn(f32)); }
+ // #[test]
+ // fn fuzz_f64() { quickcheck::QuickCheck::new().max_tests(N).quickcheck(prop_f64 as fn(f64)); }
}
#[cfg(test)]
@@ -806,6 +965,13 @@ mod roundtrip_vectors {
result_vec.push(got.get(i));
}
assert_eq!(result_vec, xs);
+
+ let rust_vec_iter = got.iter().collect::<Vec<T>>();
+ assert_eq!(rust_vec_iter, xs);
+
+ let mut rust_vec_rev_iter = got.iter().rev().collect::<Vec<T>>();
+ rust_vec_rev_iter.reverse();
+ assert_eq!(rust_vec_rev_iter, xs);
}
#[test]
@@ -2694,6 +2860,33 @@ mod byte_layouts {
}
}
+#[cfg(test)]
+mod copy_clone_traits {
+ #[test]
+ fn follow_types_implement_copy_and_clone() {
+ static_assertions::assert_impl_all!(flatbuffers::WIPOffset<u32>: Copy, Clone);
+ static_assertions::assert_impl_all!(flatbuffers::WIPOffset<Vec<u32>>: Copy, Clone);
+
+ static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<u32>: Copy, Clone);
+ static_assertions::assert_impl_all!(flatbuffers::ForwardsUOffset<Vec<u32>>: Copy, Clone);
+
+ static_assertions::assert_impl_all!(flatbuffers::Vector<'static, u32>: Copy, Clone);
+ static_assertions::assert_impl_all!(flatbuffers::Vector<'static, Vec<u32>>: Copy, Clone);
+ }
+}
+
+#[cfg(test)]
+mod fully_qualified_name {
+ #[test]
+ fn fully_qualified_name_generated() {
+ assert!(check_eq!(::my_game::example::Monster::get_fully_qualified_name(), "MyGame.Example.Monster").is_ok());
+ assert!(check_eq!(::my_game::example_2::Monster::get_fully_qualified_name(), "MyGame.Example2.Monster").is_ok());
+
+ assert!(check_eq!(::my_game::example::Vec3::get_fully_qualified_name(), "MyGame.Example.Vec3").is_ok());
+ assert!(check_eq!(::my_game::example::Ability::get_fully_qualified_name(), "MyGame.Example.Ability").is_ok());
+ }
+}
+
// this is not technically a test, but we want to always keep this generated
// file up-to-date, and the simplest way to do that is to make sure that when
// tests are run, the file is generated.
diff --git a/tests/test.cpp b/tests/test.cpp
index e0232300..13bd66d5 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include <cmath>
+
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/minireflect.h"
@@ -34,9 +35,36 @@
#include "namespace_test/namespace_test2_generated.h"
#include "union_vector/union_vector_generated.h"
#include "monster_extra_generated.h"
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+# include "arrays_test_generated.h"
+# include "evolution_test/evolution_v1_generated.h"
+# include "evolution_test/evolution_v2_generated.h"
+#endif
+
+#include "native_type_test_generated.h"
#include "test_assert.h"
#include "flatbuffers/flexbuffers.h"
+#include "monster_test_bfbs_generated.h" // Generated using --bfbs-comments --bfbs-builtins --cpp --bfbs-gen-embed
+
+// clang-format off
+// Check that char* and uint8_t* are interoperable types.
+// The reinterpret_cast<> between the pointers are used to simplify data loading.
+static_assert(flatbuffers::is_same<uint8_t, char>::value ||
+ flatbuffers::is_same<uint8_t, unsigned char>::value,
+ "unexpected uint8_t type");
+
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+ // Ensure IEEE-754 support if tests of floats with NaN/Inf will run.
+ static_assert(std::numeric_limits<float>::is_iec559 &&
+ std::numeric_limits<double>::is_iec559,
+ "IEC-559 (IEEE-754) standard required");
+#endif
+// clang-format on
+
+// Shortcuts for the infinity.
+static const auto infinityf = std::numeric_limits<float>::infinity();
+static const auto infinityd = std::numeric_limits<double>::infinity();
using namespace MyGame::Example;
@@ -47,7 +75,8 @@ void FlatBufferBuilderTest();
// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
uint32_t lcg_seed = 48271;
uint32_t lcg_rand() {
- return lcg_seed = (static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL;
+ return lcg_seed =
+ (static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL;
}
void lcg_reset() { lcg_seed = 48271; }
@@ -172,17 +201,16 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
// We use this special creation function because we have an array of
// pre-C++11 (enum class) enums whose size likely is int, yet its declared
// type in the schema is byte.
- auto vecofcolors = builder.CreateVectorScalarCast<int8_t, Color>(colors, 2);
+ auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2);
// shortcut for creating monster with all fields set:
- auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue,
- Any_Monster, mlocs[1].Union(), // Store a union.
- testv, vecofstrings, vecoftables, 0,
- nested_flatbuffer_vector, 0, false, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2,
- vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, AnyUniqueAliases_NONE, 0,
- AnyAmbiguousAliases_NONE, 0, vecofcolors);
+ auto mloc = CreateMonster(
+ builder, &vec, 150, 80, name, inventory, Color_Blue, Any_Monster,
+ mlocs[1].Union(), // Store a union.
+ testv, vecofstrings, vecoftables, 0, nested_flatbuffer_vector, 0, false,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2,
+ vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ AnyUniqueAliases_NONE, 0, AnyAmbiguousAliases_NONE, 0, vecofcolors);
FinishMonsterBuffer(builder, mloc);
@@ -253,29 +281,37 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length,
unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Check compatibilty of iterators with STL.
std::vector<unsigned char> inv_vec(inventory->begin(), inventory->end());
- for (auto it = inventory->begin(); it != inventory->end(); ++it) {
+ int n = 0;
+ for (auto it = inventory->begin(); it != inventory->end(); ++it, ++n) {
auto indx = it - inventory->begin();
TEST_EQ(*it, inv_vec.at(indx)); // Use bounds-check.
TEST_EQ(*it, inv_data[indx]);
}
+ TEST_EQ(n, inv_vec.size());
- for (auto it = inventory->cbegin(); it != inventory->cend(); ++it) {
+ n = 0;
+ for (auto it = inventory->cbegin(); it != inventory->cend(); ++it, ++n) {
auto indx = it - inventory->cbegin();
TEST_EQ(*it, inv_vec.at(indx)); // Use bounds-check.
TEST_EQ(*it, inv_data[indx]);
}
+ TEST_EQ(n, inv_vec.size());
- for (auto it = inventory->rbegin(); it != inventory->rend(); ++it) {
- auto indx = inventory->rend() - it;
+ n = 0;
+ for (auto it = inventory->rbegin(); it != inventory->rend(); ++it, ++n) {
+ auto indx = inventory->rend() - it - 1;
TEST_EQ(*it, inv_vec.at(indx)); // Use bounds-check.
TEST_EQ(*it, inv_data[indx]);
}
+ TEST_EQ(n, inv_vec.size());
- for (auto it = inventory->crbegin(); it != inventory->crend(); ++it) {
- auto indx = inventory->crend() - it;
+ n = 0;
+ for (auto it = inventory->crbegin(); it != inventory->crend(); ++it, ++n) {
+ auto indx = inventory->crend() - it - 1;
TEST_EQ(*it, inv_vec.at(indx)); // Use bounds-check.
TEST_EQ(*it, inv_data[indx]);
}
+ TEST_EQ(n, inv_vec.size());
TEST_EQ(monster->color(), Color_Blue);
@@ -306,8 +342,9 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length,
// Example of accessing a vector of tables:
auto vecoftables = monster->testarrayoftables();
TEST_EQ(vecoftables->size(), 3U);
- for (auto it = vecoftables->begin(); it != vecoftables->end(); ++it)
+ for (auto it = vecoftables->begin(); it != vecoftables->end(); ++it) {
TEST_EQ(strlen(it->name()->c_str()) >= 4, true);
+ }
TEST_EQ_STR(vecoftables->Get(0)->name()->c_str(), "Barney");
TEST_EQ(vecoftables->Get(0)->hp(), 1000);
TEST_EQ_STR(vecoftables->Get(1)->name()->c_str(), "Fred");
@@ -533,8 +570,7 @@ void SizePrefixedTest() {
// Create size prefixed buffer.
flatbuffers::FlatBufferBuilder fbb;
FinishSizePrefixedMonsterBuffer(
- fbb,
- CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
+ fbb, CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
// Verify it.
flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
@@ -564,7 +600,8 @@ void JsonDefaultTest() {
// load FlatBuffer schema (.fbs) from disk
std::string schemafile;
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
- false, &schemafile), true);
+ false, &schemafile),
+ true);
// parse schema first, so we can use it to parse the data after
flatbuffers::Parser parser;
auto include_test_path =
@@ -590,6 +627,149 @@ void JsonDefaultTest() {
TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
}
+void JsonEnumsTest() {
+ // load FlatBuffer schema (.fbs) from disk
+ std::string schemafile;
+ TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
+ false, &schemafile),
+ true);
+ // parse schema first, so we can use it to parse the data after
+ flatbuffers::Parser parser;
+ auto include_test_path =
+ flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+ const char *include_directories[] = { test_data_path.c_str(),
+ include_test_path.c_str(), nullptr };
+ parser.opts.output_enum_identifiers = true;
+ TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+ flatbuffers::FlatBufferBuilder builder;
+ auto name = builder.CreateString("bitflag_enum");
+ MonsterBuilder color_monster(builder);
+ color_monster.add_name(name);
+ color_monster.add_color(Color(Color_Blue | Color_Red));
+ FinishMonsterBuffer(builder, color_monster.Finish());
+ std::string jsongen;
+ auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
+ TEST_EQ(result, true);
+ TEST_EQ(std::string::npos != jsongen.find("color: \"Red Blue\""), true);
+ // Test forward compatibility with 'output_enum_identifiers = true'.
+ // Current Color doesn't have '(1u << 2)' field, let's add it.
+ builder.Clear();
+ std::string future_json;
+ auto future_name = builder.CreateString("future bitflag_enum");
+ MonsterBuilder future_color(builder);
+ future_color.add_name(future_name);
+ future_color.add_color(
+ static_cast<Color>((1u << 2) | Color_Blue | Color_Red));
+ FinishMonsterBuffer(builder, future_color.Finish());
+ result = GenerateText(parser, builder.GetBufferPointer(), &future_json);
+ TEST_EQ(result, true);
+ TEST_EQ(std::string::npos != future_json.find("color: 13"), true);
+}
+
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+// The IEEE-754 quiet_NaN is not simple binary constant.
+// All binary NaN bit strings have all the bits of the biased exponent field E
+// set to 1. A quiet NaN bit string should be encoded with the first bit d[1]
+// of the trailing significand field T being 1 (d[0] is implicit bit).
+// It is assumed that endianness of floating-point is same as integer.
+template<typename T, typename U, U qnan_base> bool is_quiet_nan_impl(T v) {
+ static_assert(sizeof(T) == sizeof(U), "unexpected");
+ U b = 0;
+ std::memcpy(&b, &v, sizeof(T));
+ return ((b & qnan_base) == qnan_base);
+}
+static bool is_quiet_nan(float v) {
+ return is_quiet_nan_impl<float, uint32_t, 0x7FC00000u>(v);
+}
+static bool is_quiet_nan(double v) {
+ return is_quiet_nan_impl<double, uint64_t, 0x7FF8000000000000ul>(v);
+}
+
+void TestMonsterExtraFloats() {
+ TEST_EQ(is_quiet_nan(1.0), false);
+ TEST_EQ(is_quiet_nan(infinityd), false);
+ TEST_EQ(is_quiet_nan(-infinityf), false);
+ TEST_EQ(is_quiet_nan(std::numeric_limits<float>::quiet_NaN()), true);
+ TEST_EQ(is_quiet_nan(std::numeric_limits<double>::quiet_NaN()), true);
+
+ using namespace flatbuffers;
+ using namespace MyGame;
+ // Load FlatBuffer schema (.fbs) from disk.
+ std::string schemafile;
+ TEST_EQ(LoadFile((test_data_path + "monster_extra.fbs").c_str(), false,
+ &schemafile),
+ true);
+ // Parse schema first, so we can use it to parse the data after.
+ Parser parser;
+ auto include_test_path = ConCatPathFileName(test_data_path, "include_test");
+ const char *include_directories[] = { test_data_path.c_str(),
+ include_test_path.c_str(), nullptr };
+ TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+ // Create empty extra and store to json.
+ parser.opts.output_default_scalars_in_json = true;
+ parser.opts.output_enum_identifiers = true;
+ FlatBufferBuilder builder;
+ const auto def_root = MonsterExtraBuilder(builder).Finish();
+ FinishMonsterExtraBuffer(builder, def_root);
+ const auto def_obj = builder.GetBufferPointer();
+ const auto def_extra = GetMonsterExtra(def_obj);
+ TEST_NOTNULL(def_extra);
+ TEST_EQ(is_quiet_nan(def_extra->f0()), true);
+ TEST_EQ(is_quiet_nan(def_extra->f1()), true);
+ TEST_EQ(def_extra->f2(), +infinityf);
+ TEST_EQ(def_extra->f3(), -infinityf);
+ TEST_EQ(is_quiet_nan(def_extra->d0()), true);
+ TEST_EQ(is_quiet_nan(def_extra->d1()), true);
+ TEST_EQ(def_extra->d2(), +infinityd);
+ TEST_EQ(def_extra->d3(), -infinityd);
+ std::string jsongen;
+ auto result = GenerateText(parser, def_obj, &jsongen);
+ TEST_EQ(result, true);
+ // Check expected default values.
+ TEST_EQ(std::string::npos != jsongen.find("f0: nan"), true);
+ TEST_EQ(std::string::npos != jsongen.find("f1: nan"), true);
+ TEST_EQ(std::string::npos != jsongen.find("f2: inf"), true);
+ TEST_EQ(std::string::npos != jsongen.find("f3: -inf"), true);
+ TEST_EQ(std::string::npos != jsongen.find("d0: nan"), true);
+ TEST_EQ(std::string::npos != jsongen.find("d1: nan"), true);
+ TEST_EQ(std::string::npos != jsongen.find("d2: inf"), true);
+ TEST_EQ(std::string::npos != jsongen.find("d3: -inf"), true);
+ // Parse 'mosterdata_extra.json'.
+ const auto extra_base = test_data_path + "monsterdata_extra";
+ jsongen = "";
+ TEST_EQ(LoadFile((extra_base + ".json").c_str(), false, &jsongen), true);
+ TEST_EQ(parser.Parse(jsongen.c_str()), true);
+ const auto test_file = parser.builder_.GetBufferPointer();
+ const auto test_size = parser.builder_.GetSize();
+ Verifier verifier(test_file, test_size);
+ TEST_ASSERT(VerifyMonsterExtraBuffer(verifier));
+ const auto extra = GetMonsterExtra(test_file);
+ TEST_NOTNULL(extra);
+ TEST_EQ(is_quiet_nan(extra->f0()), true);
+ TEST_EQ(is_quiet_nan(extra->f1()), true);
+ TEST_EQ(extra->f2(), +infinityf);
+ TEST_EQ(extra->f3(), -infinityf);
+ TEST_EQ(is_quiet_nan(extra->d0()), true);
+ TEST_EQ(extra->d1(), +infinityd);
+ TEST_EQ(extra->d2(), -infinityd);
+ TEST_EQ(is_quiet_nan(extra->d3()), true);
+ TEST_NOTNULL(extra->fvec());
+ TEST_EQ(extra->fvec()->size(), 4);
+ TEST_EQ(extra->fvec()->Get(0), 1.0f);
+ TEST_EQ(extra->fvec()->Get(1), -infinityf);
+ TEST_EQ(extra->fvec()->Get(2), +infinityf);
+ TEST_EQ(is_quiet_nan(extra->fvec()->Get(3)), true);
+ TEST_NOTNULL(extra->dvec());
+ TEST_EQ(extra->dvec()->size(), 4);
+ TEST_EQ(extra->dvec()->Get(0), 2.0);
+ TEST_EQ(extra->dvec()->Get(1), +infinityd);
+ TEST_EQ(extra->dvec()->Get(2), -infinityd);
+ TEST_EQ(is_quiet_nan(extra->dvec()->Get(3)), true);
+}
+#else
+void TestMonsterExtraFloats() {}
+#endif
+
// example of parsing text straight into a buffer, and generating
// text back from it:
void ParseAndGenerateTextTest(bool binary) {
@@ -607,7 +787,7 @@ void ParseAndGenerateTextTest(bool binary) {
true);
auto include_test_path =
- flatbuffers::ConCatPathFileName(test_data_path, "include_test");
+ flatbuffers::ConCatPathFileName(test_data_path, "include_test");
const char *include_directories[] = { test_data_path.c_str(),
include_test_path.c_str(), nullptr };
@@ -618,8 +798,10 @@ void ParseAndGenerateTextTest(bool binary) {
reinterpret_cast<const uint8_t *>(schemafile.c_str()),
schemafile.size());
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
- //auto schema = reflection::GetSchema(schemafile.c_str());
- TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(), schemafile.size()), true);
+ // auto schema = reflection::GetSchema(schemafile.c_str());
+ TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(),
+ schemafile.size()),
+ true);
} else {
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
}
@@ -865,7 +1047,8 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
}
void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
- auto s = flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
+ auto s =
+ flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
TEST_EQ_STR(
s.c_str(),
"{ "
@@ -896,15 +1079,15 @@ void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
"}");
Test test(16, 32);
- Vec3 vec(1,2,3, 1.5, Color_Red, test);
+ Vec3 vec(1, 2, 3, 1.5, Color_Red, test);
flatbuffers::FlatBufferBuilder vec_builder;
vec_builder.Finish(vec_builder.CreateStruct(vec));
auto vec_buffer = vec_builder.Release();
auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(),
Vec3::MiniReflectTypeTable());
- TEST_EQ_STR(
- vec_str.c_str(),
- "{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: 16, b: 32 } }");
+ TEST_EQ_STR(vec_str.c_str(),
+ "{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: "
+ "16, b: 32 } }");
}
// Parse a .proto schema, output as .fbs
@@ -921,15 +1104,122 @@ void ParseProtoTest() {
flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(),
false, &goldenfile),
true);
+ TEST_EQ(flatbuffers::LoadFile(
+ (test_data_path + "prototest/test_union.golden").c_str(), false,
+ &goldenunionfile),
+ true);
+
+ flatbuffers::IDLOptions opts;
+ opts.include_dependence_headers = false;
+ opts.proto_mode = true;
+
+ // Parse proto.
+ flatbuffers::Parser parser(opts);
+ auto protopath = test_data_path + "prototest/";
+ const char *include_directories[] = { protopath.c_str(), nullptr };
+ TEST_EQ(parser.Parse(protofile.c_str(), include_directories), true);
+
+ // Generate fbs.
+ auto fbs = flatbuffers::GenerateFBS(parser, "test");
+
+ // Ensure generated file is parsable.
+ flatbuffers::Parser parser2;
+ TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
+ TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
+
+ // Parse proto with --oneof-union option.
+ opts.proto_oneof_union = true;
+ flatbuffers::Parser parser3(opts);
+ TEST_EQ(parser3.Parse(protofile.c_str(), include_directories), true);
+
+ // Generate fbs.
+ auto fbs_union = flatbuffers::GenerateFBS(parser3, "test");
+
+ // Ensure generated file is parsable.
+ flatbuffers::Parser parser4;
+ TEST_EQ(parser4.Parse(fbs_union.c_str(), nullptr), true);
+ TEST_EQ_STR(fbs_union.c_str(), goldenunionfile.c_str());
+}
+
+// Parse a .proto schema, output as .fbs
+void ParseProtoTestWithSuffix() {
+ // load the .proto and the golden file from disk
+ std::string protofile;
+ std::string goldenfile;
+ std::string goldenunionfile;
TEST_EQ(
- flatbuffers::LoadFile((test_data_path +
- "prototest/test_union.golden").c_str(),
- false, &goldenunionfile),
+ flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(),
+ false, &protofile),
true);
+ TEST_EQ(flatbuffers::LoadFile(
+ (test_data_path + "prototest/test_suffix.golden").c_str(), false,
+ &goldenfile),
+ true);
+ TEST_EQ(flatbuffers::LoadFile(
+ (test_data_path + "prototest/test_union_suffix.golden").c_str(),
+ false, &goldenunionfile),
+ true);
flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false;
opts.proto_mode = true;
+ opts.proto_namespace_suffix = "test_namespace_suffix";
+
+ // Parse proto.
+ flatbuffers::Parser parser(opts);
+ auto protopath = test_data_path + "prototest/";
+ const char *include_directories[] = { protopath.c_str(), nullptr };
+ TEST_EQ(parser.Parse(protofile.c_str(), include_directories), true);
+
+ // Generate fbs.
+ auto fbs = flatbuffers::GenerateFBS(parser, "test");
+
+ // Ensure generated file is parsable.
+ flatbuffers::Parser parser2;
+ TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
+ TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
+
+ // Parse proto with --oneof-union option.
+ opts.proto_oneof_union = true;
+ flatbuffers::Parser parser3(opts);
+ TEST_EQ(parser3.Parse(protofile.c_str(), include_directories), true);
+
+ // Generate fbs.
+ auto fbs_union = flatbuffers::GenerateFBS(parser3, "test");
+
+ // Ensure generated file is parsable.
+ flatbuffers::Parser parser4;
+ TEST_EQ(parser4.Parse(fbs_union.c_str(), nullptr), true);
+ TEST_EQ_STR(fbs_union.c_str(), goldenunionfile.c_str());
+}
+
+// Parse a .proto schema, output as .fbs
+void ParseProtoTestWithIncludes() {
+ // load the .proto and the golden file from disk
+ std::string protofile;
+ std::string goldenfile;
+ std::string goldenunionfile;
+ std::string importprotofile;
+ TEST_EQ(
+ flatbuffers::LoadFile((test_data_path + "prototest/test.proto").c_str(),
+ false, &protofile),
+ true);
+ TEST_EQ(flatbuffers::LoadFile(
+ (test_data_path + "prototest/imported.proto").c_str(), false,
+ &importprotofile),
+ true);
+ TEST_EQ(flatbuffers::LoadFile(
+ (test_data_path + "prototest/test_include.golden").c_str(), false,
+ &goldenfile),
+ true);
+ TEST_EQ(flatbuffers::LoadFile(
+ (test_data_path + "prototest/test_union_include.golden").c_str(),
+ false, &goldenunionfile),
+ true);
+
+ flatbuffers::IDLOptions opts;
+ opts.include_dependence_headers = true;
+ opts.proto_mode = true;
// Parse proto.
flatbuffers::Parser parser(opts);
@@ -940,8 +1230,17 @@ void ParseProtoTest() {
// Generate fbs.
auto fbs = flatbuffers::GenerateFBS(parser, "test");
+ // Generate fbs from import.proto
+ flatbuffers::Parser import_parser(opts);
+ TEST_EQ(import_parser.Parse(importprotofile.c_str(), include_directories),
+ true);
+ auto import_fbs = flatbuffers::GenerateFBS(import_parser, "test");
+
// Ensure generated file is parsable.
flatbuffers::Parser parser2;
+ TEST_EQ(
+ parser2.Parse(import_fbs.c_str(), include_directories, "imported.fbs"),
+ true);
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
TEST_EQ_STR(fbs.c_str(), goldenfile.c_str());
@@ -955,6 +1254,7 @@ void ParseProtoTest() {
// Ensure generated file is parsable.
flatbuffers::Parser parser4;
+ TEST_EQ(parser4.Parse(import_fbs.c_str(), nullptr, "imported.fbs"), true);
TEST_EQ(parser4.Parse(fbs_union.c_str(), nullptr), true);
TEST_EQ_STR(fbs_union.c_str(), goldenunionfile.c_str());
}
@@ -1160,6 +1460,15 @@ void FuzzTest2() {
AddToSchemaAndInstances(
"bool", deprecated ? "" : (lcg_rand() % 2 ? "true" : "false"));
break;
+ case flatbuffers::BASE_TYPE_ARRAY:
+ if (!is_struct) {
+ AddToSchemaAndInstances(
+ "ubyte",
+ deprecated ? "" : "255"); // No fixed-length arrays in tables.
+ } else {
+ AddToSchemaAndInstances("[int:3]", deprecated ? "" : "[\n,\n,\n]");
+ }
+ break;
default:
// All the scalar types.
schema += flatbuffers::kTypeNames[base_type];
@@ -1217,7 +1526,7 @@ void FuzzTest2() {
break;
}
}
- TEST_NOTNULL(NULL);
+ TEST_NOTNULL(nullptr); //-V501 (this comment supresses CWE-570 warning)
}
// clang-format off
@@ -1297,7 +1606,6 @@ void ErrorTest() {
TestError("enum X:float {}", "underlying");
TestError("enum X:byte { Y, Y }", "value already");
TestError("enum X:byte { Y=2, Z=1 }", "ascending");
- TestError("enum X:byte (bit_flags) { Y=8 }", "bit flag out");
TestError("table X { Y:int; } table X {", "datatype already");
TestError("struct X (force_align: 7) { Y:int; }", "force_align");
TestError("struct X {}", "size 0");
@@ -1354,9 +1662,9 @@ bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
// Additional parser testing not covered elsewhere.
void ValueTest() {
// Test scientific notation numbers.
- TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"),
- 3.14159f),
- true);
+ TEST_EQ(
+ FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), 3.14159f),
+ true);
// number in string
TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"),
3.14159f),
@@ -1394,7 +1702,6 @@ void ValueTest() {
// check comments before and after json object
TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1);
TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1);
-
}
void NestedListTest() {
@@ -1416,6 +1723,13 @@ void EnumStringsTest() {
"root_type T;"
"{ F:[ \"E.C\", \"E.A E.B E.C\" ] }"),
true);
+ // unsigned bit_flags
+ flatbuffers::Parser parser3;
+ TEST_EQ(
+ parser3.Parse("enum E:uint16 (bit_flags) { F0, F07=7, F08, F14=14, F15 }"
+ " table T { F: E = \"F15 F08\"; }"
+ "root_type T;"),
+ true);
}
void EnumNamesTest() {
@@ -1429,16 +1743,17 @@ void EnumNamesTest() {
// For details see C++17 standard or explanation on the SO:
// stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(0)));
- TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY-1)));
- TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY+1)));
+ TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY - 1)));
+ TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY + 1)));
}
void EnumOutOfRangeTest() {
TestError("enum X:byte { Y = 128 }", "enum value does not fit");
TestError("enum X:byte { Y = -129 }", "enum value does not fit");
- TestError("enum X:byte { Y = 127, Z }", "enum value does not fit");
+ TestError("enum X:byte { Y = 126, Z0, Z1 }", "enum value does not fit");
TestError("enum X:ubyte { Y = -1 }", "enum value does not fit");
TestError("enum X:ubyte { Y = 256 }", "enum value does not fit");
+ TestError("enum X:ubyte { Y = 255, Z }", "enum value does not fit");
// Unions begin with an implicit "NONE = 0".
TestError("table Y{} union X { Y = -1 }",
"enum values must be specified in ascending order");
@@ -1448,12 +1763,15 @@ void EnumOutOfRangeTest() {
TestError("enum X:int { Y = 2147483648 }", "enum value does not fit");
TestError("enum X:uint { Y = -1 }", "enum value does not fit");
TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit");
- TestError("enum X:long { Y = 9223372036854775808 }", "constant does not fit");
- TestError("enum X:long { Y = 9223372036854775807, Z }", "enum value overflows");
- TestError("enum X:ulong { Y = -1 }", "enum value does not fit");
- // TODO: these are perfectly valid constants that shouldn't fail
- TestError("enum X:ulong { Y = 13835058055282163712 }", "constant does not fit");
- TestError("enum X:ulong { Y = 18446744073709551615 }", "constant does not fit");
+ TestError("enum X:long { Y = 9223372036854775808 }", "does not fit");
+ TestError("enum X:long { Y = 9223372036854775807, Z }",
+ "enum value does not fit");
+ TestError("enum X:ulong { Y = -1 }", "does not fit");
+ TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out");
+ TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128
+ // bit_flgs out of range
+ TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }",
+ "out of range");
}
void EnumValueTest() {
@@ -1472,6 +1790,15 @@ void EnumValueTest() {
// Generate json with defaults and check.
TEST_EQ(TestValue<int>(nullptr, "E", "enum E:int { Z, V=5 }"), 0);
TEST_EQ(TestValue<int>(nullptr, "E=V", "enum E:int { Z, V=5 }"), 5);
+ // u84 test
+ TEST_EQ(TestValue<uint64_t>(nullptr, "E=V",
+ "enum E:ulong { V = 13835058055282163712 }"),
+ 13835058055282163712ULL);
+ TEST_EQ(TestValue<uint64_t>(nullptr, "E=V",
+ "enum E:ulong { V = 18446744073709551615 }"),
+ 18446744073709551615ULL);
+ // Assign non-enum value to enum field. Is it right?
+ TEST_EQ(TestValue<int>("{ Y:7 }", "E", "enum E:int { V = 0 }"), 7);
}
void IntegerOutOfRangeTest() {
@@ -1544,11 +1871,12 @@ void IntegerOutOfRangeTest() {
void IntegerBoundaryTest() {
// Check numerical compatibility with non-C++ languages.
- // By the C++ standard, std::numerical_limits<int64_t>::min() == -9223372036854775807 (-2^63+1) or less*
- // The Flatbuffers grammar and most of the languages (C#, Java, Rust) expect
- // that minimum values are: -128, -32768,.., -9223372036854775808.
- // Since C++20, static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement cast.
- // Therefore -9223372036854775808 should be valid negative value.
+ // By the C++ standard, std::numerical_limits<int64_t>::min() ==
+ // -9223372036854775807 (-2^63+1) or less* The Flatbuffers grammar and most of
+ // the languages (C#, Java, Rust) expect that minimum values are: -128,
+ // -32768,.., -9223372036854775808. Since C++20,
+ // static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement
+ // cast. Therefore -9223372036854775808 should be valid negative value.
TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128);
TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127);
TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768);
@@ -1591,8 +1919,6 @@ void IntegerBoundaryTest() {
}
void ValidFloatTest() {
- const auto infinityf = flatbuffers::numeric_limits<float>::infinity();
- const auto infinityd = flatbuffers::numeric_limits<double>::infinity();
// check rounding to infinity
TEST_EQ(TestValue<float>("{ Y:+3.4029e+38 }", "float"), +infinityf);
TEST_EQ(TestValue<float>("{ Y:-3.4029e+38 }", "float"), -infinityf);
@@ -1622,11 +1948,11 @@ void ValidFloatTest() {
TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f);
TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f);
- #if defined(FLATBUFFERS_HAS_NEW_STRTOD)
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Old MSVC versions may have problem with this check.
// https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"),
- 6929495644600920.0);
+ 6929495644600920.0);
// check nan's
TEST_EQ(std::isnan(TestValue<double>("{ Y:nan }", "double")), true);
TEST_EQ(std::isnan(TestValue<float>("{ Y:nan }", "float")), true);
@@ -1668,7 +1994,7 @@ void ValidFloatTest() {
#else // FLATBUFFERS_HAS_NEW_STRTOD
TEST_OUTPUT_LINE("FLATBUFFERS_HAS_NEW_STRTOD tests skipped");
-#endif // FLATBUFFERS_HAS_NEW_STRTOD
+#endif // !FLATBUFFERS_HAS_NEW_STRTOD
}
void InvalidFloatTest() {
@@ -1748,8 +2074,8 @@ void GenerateTableTextTest() {
TEST_EQ(ok, true);
auto include_test_path =
flatbuffers::ConCatPathFileName(test_data_path, "include_test");
- const char *include_directories[] = {test_data_path.c_str(),
- include_test_path.c_str(), nullptr};
+ const char *include_directories[] = { test_data_path.c_str(),
+ include_test_path.c_str(), nullptr };
flatbuffers::IDLOptions opt;
opt.indent_step = -1;
flatbuffers::Parser parser(opt);
@@ -2049,7 +2375,7 @@ void InvalidUTF8Test() {
// Check independence of identifier from locale.
std::string locale_ident;
locale_ident += "table T { F";
- locale_ident += static_cast<char>(-32); // unsigned 0xE0
+ locale_ident += static_cast<char>(-32); // unsigned 0xE0
locale_ident += " :string; }";
locale_ident += "root_type T;";
locale_ident += "{}";
@@ -2116,15 +2442,86 @@ void InvalidNestedFlatbufferTest() {
TEST_EQ(parser1.Parse("{ name: \"Bender\", testnestedflatbuffer: { name: "
"\"Leela\", color: \"nonexistent\"}}"),
false);
- // Check that Parser is destroyed correctly after parsing invalid json
+}
+
+void EvolutionTest() {
+ // VS10 does not support typed enums, exclude from tests
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+ const int NUM_VERSIONS = 2;
+ std::string schemas[NUM_VERSIONS];
+ std::string jsonfiles[NUM_VERSIONS];
+ std::vector<uint8_t> binaries[NUM_VERSIONS];
+
+ flatbuffers::IDLOptions idl_opts;
+ idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
+ flatbuffers::Parser parser(idl_opts);
+
+ // Load all the schema versions and their associated data.
+ for (int i = 0; i < NUM_VERSIONS; ++i) {
+ std::string schema = test_data_path + "evolution_test/evolution_v" +
+ flatbuffers::NumToString(i + 1) + ".fbs";
+ TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i]));
+ std::string json = test_data_path + "evolution_test/evolution_v" +
+ flatbuffers::NumToString(i + 1) + ".json";
+ TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i]));
+
+ TEST_ASSERT(parser.Parse(schemas[i].c_str()));
+ TEST_ASSERT(parser.Parse(jsonfiles[i].c_str()));
+
+ auto bufLen = parser.builder_.GetSize();
+ auto buf = parser.builder_.GetBufferPointer();
+ binaries[i].reserve(bufLen);
+ std::copy(buf, buf + bufLen, std::back_inserter(binaries[i]));
+ }
+
+ // Assert that all the verifiers for the different schema versions properly
+ // verify any version data.
+ for (int i = 0; i < NUM_VERSIONS; ++i) {
+ flatbuffers::Verifier verifier(&binaries[i].front(), binaries[i].size());
+ TEST_ASSERT(Evolution::V1::VerifyRootBuffer(verifier));
+ TEST_ASSERT(Evolution::V2::VerifyRootBuffer(verifier));
+ }
+
+ // Test backwards compatibility by reading old data with an evolved schema.
+ auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front());
+ // field 'j' is new in version 2, so it should be null.
+ TEST_ASSERT(nullptr == root_v1_viewed_from_v2->j());
+ // field 'k' is new in version 2 with a default of 56.
+ TEST_EQ(root_v1_viewed_from_v2->k(), 56);
+ // field 'c' of 'TableA' is new in version 2, so it should be null.
+ TEST_ASSERT(nullptr == root_v1_viewed_from_v2->e()->c());
+ // 'TableC' was added to field 'c' union in version 2, so it should be null.
+ TEST_ASSERT(nullptr == root_v1_viewed_from_v2->c_as_TableC());
+ // The field 'c' union should be of type 'TableB' regardless of schema version
+ TEST_ASSERT(root_v1_viewed_from_v2->c_type() == Evolution::V2::Union::TableB);
+ // The field 'f' was renamed to 'ff' in version 2, it should still be
+ // readable.
+ TEST_EQ(root_v1_viewed_from_v2->ff()->a(), 16);
+
+ // Test forwards compatibility by reading new data with an old schema.
+ auto root_v2_viewed_from_v1 = Evolution::V1::GetRoot(&binaries[1].front());
+ // The field 'c' union in version 2 is a new table (index = 3) and should
+ // still be accessible, but not interpretable.
+ TEST_EQ(static_cast<uint8_t>(root_v2_viewed_from_v1->c_type()), 3);
+ TEST_NOTNULL(root_v2_viewed_from_v1->c());
+ // The field 'd' enum in verison 2 has new members and should still be
+ // accessible, but not interpretable.
+ TEST_EQ(static_cast<int8_t>(root_v2_viewed_from_v1->d()), 3);
+ // The field 'a' in version 2 is deprecated and should return the default
+ // value (0) instead of the value stored in the in the buffer (42).
+ TEST_EQ(root_v2_viewed_from_v1->a(), 0);
+ // The field 'ff' was originally named 'f' in version 1, it should still be
+ // readable.
+ TEST_EQ(root_v2_viewed_from_v1->f()->a(), 35);
+#endif
}
void UnionVectorTest() {
// load FlatBuffer fbs schema and json.
std::string schemafile, jsonfile;
TEST_EQ(flatbuffers::LoadFile(
- (test_data_path + "union_vector/union_vector.fbs").c_str(),
- false, &schemafile),
+ (test_data_path + "union_vector/union_vector.fbs").c_str(), false,
+ &schemafile),
true);
TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "union_vector/union_vector.json").c_str(),
@@ -2161,12 +2558,11 @@ void UnionVectorTest() {
fbb.CreateStruct(Rapunzel(/*hair_length=*/6)).Union(),
fbb.CreateVector(types), fbb.CreateVector(characters));
FinishMovieBuffer(fbb, movie_offset);
- auto buf = fbb.GetBufferPointer();
- flatbuffers::Verifier verifier(buf, fbb.GetSize());
+ flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
TEST_EQ(VerifyMovieBuffer(verifier), true);
- auto flat_movie = GetMovie(buf);
+ auto flat_movie = GetMovie(fbb.GetBufferPointer());
auto TestMovie = [](const Movie *movie) {
TEST_EQ(movie->main_character_type() == Character_Rapunzel, true);
@@ -2223,6 +2619,7 @@ void UnionVectorTest() {
TestMovie(repacked_movie);
+ // Generate text using mini-reflection.
auto s =
flatbuffers::FlatBufferToString(fbb.GetBufferPointer(), MovieTypeTable());
TEST_EQ_STR(
@@ -2232,43 +2629,81 @@ void UnionVectorTest() {
"characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, "
"{ books_read: 2 }, \"Other\", \"Unused\" ] }");
-
flatbuffers::ToStringVisitor visitor("\n", true, " ");
IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor);
- TEST_EQ_STR(
- visitor.s.c_str(),
- "{\n"
- " \"main_character_type\": \"Rapunzel\",\n"
- " \"main_character\": {\n"
- " \"hair_length\": 6\n"
- " },\n"
- " \"characters_type\": [\n"
- " \"Belle\",\n"
- " \"MuLan\",\n"
- " \"BookFan\",\n"
- " \"Other\",\n"
- " \"Unused\"\n"
- " ],\n"
- " \"characters\": [\n"
- " {\n"
- " \"books_read\": 7\n"
- " },\n"
- " {\n"
- " \"sword_attack_damage\": 5\n"
- " },\n"
- " {\n"
- " \"books_read\": 2\n"
- " },\n"
- " \"Other\",\n"
- " \"Unused\"\n"
- " ]\n"
- "}");
+ TEST_EQ_STR(visitor.s.c_str(),
+ "{\n"
+ " \"main_character_type\": \"Rapunzel\",\n"
+ " \"main_character\": {\n"
+ " \"hair_length\": 6\n"
+ " },\n"
+ " \"characters_type\": [\n"
+ " \"Belle\",\n"
+ " \"MuLan\",\n"
+ " \"BookFan\",\n"
+ " \"Other\",\n"
+ " \"Unused\"\n"
+ " ],\n"
+ " \"characters\": [\n"
+ " {\n"
+ " \"books_read\": 7\n"
+ " },\n"
+ " {\n"
+ " \"sword_attack_damage\": 5\n"
+ " },\n"
+ " {\n"
+ " \"books_read\": 2\n"
+ " },\n"
+ " \"Other\",\n"
+ " \"Unused\"\n"
+ " ]\n"
+ "}");
+
+ // Generate text using parsed schema.
+ std::string jsongen;
+ auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen);
+ TEST_EQ(result, true);
+ TEST_EQ_STR(jsongen.c_str(),
+ "{\n"
+ " main_character_type: \"Rapunzel\",\n"
+ " main_character: {\n"
+ " hair_length: 6\n"
+ " },\n"
+ " characters_type: [\n"
+ " \"Belle\",\n"
+ " \"MuLan\",\n"
+ " \"BookFan\",\n"
+ " \"Other\",\n"
+ " \"Unused\"\n"
+ " ],\n"
+ " characters: [\n"
+ " {\n"
+ " books_read: 7\n"
+ " },\n"
+ " {\n"
+ " sword_attack_damage: 5\n"
+ " },\n"
+ " {\n"
+ " books_read: 2\n"
+ " },\n"
+ " \"Other\",\n"
+ " \"Unused\"\n"
+ " ]\n"
+ "}\n");
+
+ // Simple test with reflection.
+ parser.Serialize();
+ auto schema = reflection::GetSchema(parser.builder_.GetBufferPointer());
+ auto ok = flatbuffers::Verify(*schema, *schema->root_table(),
+ fbb.GetBufferPointer(), fbb.GetSize());
+ TEST_EQ(ok, true);
flatbuffers::Parser parser2(idl_opts);
TEST_EQ(parser2.Parse("struct Bool { b:bool; }"
"union Any { Bool }"
"table Root { a:Any; }"
- "root_type Root;"), true);
+ "root_type Root;"),
+ true);
TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true);
}
@@ -2327,9 +2762,11 @@ void FlexBuffersTest() {
slb += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
slb += "Fred";
slb.IndirectFloat(4.0f);
+ auto i_f = slb.LastValue();
uint8_t blob[] = { 77 };
slb.Blob(blob, 1);
slb += false;
+ slb.ReuseValue(i_f);
});
int ints[] = { 1, 2, 3 };
slb.Vector("bar", ints, 3);
@@ -2350,9 +2787,11 @@ void FlexBuffersTest() {
slb3 += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
slb3 += "Fred";
slb3.IndirectFloat(4.0f);
+ auto i_f = slb3.LastValue();
uint8_t blob[] = { 77 };
slb3.Blob(blob, 1);
slb3 += false;
+ slb3.ReuseValue(i_f);
}, slb2);
int ints[] = { 1, 2, 3 };
slb2.Vector("bar", ints, 3);
@@ -2376,7 +2815,7 @@ void FlexBuffersTest() {
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
TEST_EQ(map.size(), 7);
auto vec = map["vec"].AsVector();
- TEST_EQ(vec.size(), 5);
+ TEST_EQ(vec.size(), 6);
TEST_EQ(vec[0].AsInt64(), -100);
TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
TEST_EQ(vec[1].AsInt64(), 0); // Number parsing failed.
@@ -2384,13 +2823,11 @@ void FlexBuffersTest() {
TEST_EQ(vec[2].AsString().IsTheEmptyString(), true); // Wrong Type.
TEST_EQ_STR(vec[2].AsString().c_str(), ""); // This still works though.
TEST_EQ_STR(vec[2].ToString().c_str(), "4.0"); // Or have it converted.
-
// Few tests for templated version of As.
TEST_EQ(vec[0].As<int64_t>(), -100);
TEST_EQ_STR(vec[1].As<std::string>().c_str(), "Fred");
TEST_EQ(vec[1].As<int64_t>(), 0); // Number parsing failed.
TEST_EQ(vec[2].As<double>(), 4.0);
-
// Test that the blob can be accessed.
TEST_EQ(vec[3].IsBlob(), true);
auto blob = vec[3].AsBlob();
@@ -2398,6 +2835,7 @@ void FlexBuffersTest() {
TEST_EQ(blob.data()[0], 77);
TEST_EQ(vec[4].IsBool(), true); // Check if type is a bool
TEST_EQ(vec[4].AsBool(), false); // Check if value is false
+ TEST_EQ(vec[5].AsDouble(), 4.0); // This is shared with vec[2] !
auto tvec = map["bar"].AsTypedVector();
TEST_EQ(tvec.size(), 3);
TEST_EQ(tvec[2].AsInt8(), 3);
@@ -2446,6 +2884,68 @@ void FlexBuffersTest() {
TEST_EQ_STR(jsontest, jsonback.c_str());
}
+void FlexBuffersDeprecatedTest() {
+ // FlexBuffers as originally designed had a flaw involving the
+ // FBT_VECTOR_STRING datatype, and this test documents/tests the fix for it.
+ // Discussion: https://github.com/google/flatbuffers/issues/5627
+ flexbuffers::Builder slb;
+ // FBT_VECTOR_* are "typed vectors" where all elements are of the same type.
+ // Problem is, when storing FBT_STRING elements, it relies on that type to
+ // get the bit-width for the size field of the string, which in this case
+ // isn't present, and instead defaults to 8-bit. This means that any strings
+ // stored inside such a vector, when accessed thru the old API that returns
+ // a String reference, will appear to be truncated if the string stored is
+ // actually >=256 bytes.
+ std::string test_data(300, 'A');
+ auto start = slb.StartVector();
+ // This one will have a 16-bit size field.
+ slb.String(test_data);
+ // This one will have an 8-bit size field.
+ slb.String("hello");
+ // We're asking this to be serialized as a typed vector (true), but not
+ // fixed size (false). The type will be FBT_VECTOR_STRING with a bit-width
+ // of whatever the offsets in the vector need, the bit-widths of the strings
+ // are not stored(!) <- the actual design flaw.
+ // Note that even in the fixed code, we continue to serialize the elements of
+ // FBT_VECTOR_STRING as FBT_STRING, since there may be old code out there
+ // reading new data that we want to continue to function.
+ // Thus, FBT_VECTOR_STRING, while deprecated, will always be represented the
+ // same way, the fix lies on the reading side.
+ slb.EndVector(start, true, false);
+ slb.Finish();
+ // So now lets read this data back.
+ // For existing data, since we have no way of knowing what the actual
+ // bit-width of the size field of the string is, we are going to ignore this
+ // field, and instead treat these strings as FBT_KEY (null-terminated), so we
+ // can deal with strings of arbitrary length. This of course truncates strings
+ // with embedded nulls, but we think that that is preferrable over truncating
+ // strings >= 256 bytes.
+ auto vec = flexbuffers::GetRoot(slb.GetBuffer()).AsTypedVector();
+ // Even though this was serialized as FBT_VECTOR_STRING, it is read as
+ // FBT_VECTOR_KEY:
+ TEST_EQ(vec.ElementType(), flexbuffers::FBT_KEY);
+ // Access the long string. Previously, this would return a string of size 1,
+ // since it would read the high-byte of the 16-bit length.
+ // This should now correctly test the full 300 bytes, using AsKey():
+ TEST_EQ_STR(vec[0].AsKey(), test_data.c_str());
+ // Old code that called AsString will continue to work, as the String
+ // accessor objects now use a cached size that can come from a key as well.
+ TEST_EQ_STR(vec[0].AsString().c_str(), test_data.c_str());
+ // Short strings work as before:
+ TEST_EQ_STR(vec[1].AsKey(), "hello");
+ TEST_EQ_STR(vec[1].AsString().c_str(), "hello");
+ // So, while existing code and data mostly "just work" with the fixes applied
+ // to AsTypedVector and AsString, what do you do going forward?
+ // Code accessing existing data doesn't necessarily need to change, though
+ // you could consider using AsKey instead of AsString for a) documenting
+ // that you are accessing keys, or b) a speedup if you don't actually use
+ // the string size.
+ // For new data, or data that doesn't need to be backwards compatible,
+ // instead serialize as FBT_VECTOR (call EndVector with typed = false, then
+ // read elements with AsString), or, for maximum compactness, use
+ // FBT_VECTOR_KEY (call slb.Key above instead, read with AsKey or AsString).
+}
+
void TypeAliasesTest() {
flatbuffers::FlatBufferBuilder builder;
@@ -2472,7 +2972,7 @@ void TypeAliasesTest() {
TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max());
TEST_EQ(ta->f32(), 2.3f);
TEST_EQ(ta->f64(), 2.3);
- using namespace flatbuffers; // is_same
+ using namespace flatbuffers; // is_same
static_assert(is_same<decltype(ta->i8()), int8_t>::value, "invalid type");
static_assert(is_same<decltype(ta->i16()), int16_t>::value, "invalid type");
static_assert(is_same<decltype(ta->i32()), int32_t>::value, "invalid type");
@@ -2498,14 +2998,16 @@ void UninitializedVectorTest() {
flatbuffers::FlatBufferBuilder builder;
Test *buf = nullptr;
- auto vector_offset = builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
+ auto vector_offset =
+ builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
TEST_NOTNULL(buf);
buf[0] = Test(10, 20);
buf[1] = Test(30, 40);
auto required_name = builder.CreateString("myMonster");
auto monster_builder = MonsterBuilder(builder);
- monster_builder.add_name(required_name); // required field mandated for monster.
+ monster_builder.add_name(
+ required_name); // required field mandated for monster.
monster_builder.add_test4(vector_offset);
builder.Finish(monster_builder.Finish());
@@ -2550,11 +3052,11 @@ void EqualOperatorTest() {
// For testing any binaries, e.g. from fuzzing.
void LoadVerifyBinaryTest() {
std::string binary;
- if (flatbuffers::LoadFile((test_data_path +
- "fuzzer/your-filename-here").c_str(),
- true, &binary)) {
+ if (flatbuffers::LoadFile(
+ (test_data_path + "fuzzer/your-filename-here").c_str(), true,
+ &binary)) {
flatbuffers::Verifier verifier(
- reinterpret_cast<const uint8_t *>(binary.data()), binary.size());
+ reinterpret_cast<const uint8_t *>(binary.data()), binary.size());
TEST_EQ(VerifyMonsterBuffer(verifier), true);
}
}
@@ -2570,24 +3072,28 @@ void CreateSharedStringTest() {
TEST_EQ(onetwo.o != two.o, true);
// Support for embedded nulls
- const char chars_b[] = {'a', '\0', 'b'};
- const char chars_c[] = {'a', '\0', 'c'};
+ const char chars_b[] = { 'a', '\0', 'b' };
+ const char chars_c[] = { 'a', '\0', 'c' };
const auto null_b1 = builder.CreateSharedString(chars_b, sizeof(chars_b));
const auto null_c = builder.CreateSharedString(chars_c, sizeof(chars_c));
const auto null_b2 = builder.CreateSharedString(chars_b, sizeof(chars_b));
- TEST_EQ(null_b1.o != null_c.o, true); // Issue#5058 repro
+ TEST_EQ(null_b1.o != null_c.o, true); // Issue#5058 repro
TEST_EQ(null_b1.o, null_b2.o);
// Put the strings into an array for round trip verification.
- const flatbuffers::Offset<flatbuffers::String> array[7] = { one1, two, one2, onetwo, null_b1, null_c, null_b2 };
- const auto vector_offset = builder.CreateVector(array, flatbuffers::uoffset_t(7));
+ const flatbuffers::Offset<flatbuffers::String> array[7] = {
+ one1, two, one2, onetwo, null_b1, null_c, null_b2
+ };
+ const auto vector_offset =
+ builder.CreateVector(array, flatbuffers::uoffset_t(7));
MonsterBuilder monster_builder(builder);
monster_builder.add_name(two);
monster_builder.add_testarrayofstring(vector_offset);
builder.Finish(monster_builder.Finish());
// Read the Monster back.
- const auto *monster = flatbuffers::GetRoot<Monster>(builder.GetBufferPointer());
+ const auto *monster =
+ flatbuffers::GetRoot<Monster>(builder.GetBufferPointer());
TEST_EQ_STR(monster->name()->c_str(), "two");
const auto *testarrayofstring = monster->testarrayofstring();
TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7));
@@ -2600,7 +3106,8 @@ void CreateSharedStringTest() {
TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c))));
TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b))));
- // Make sure String::operator< works, too, since it is related to StringOffsetCompare.
+ // Make sure String::operator< works, too, since it is related to
+ // StringOffsetCompare.
TEST_EQ((*a[0]) < (*a[1]), true);
TEST_EQ((*a[1]) < (*a[0]), false);
TEST_EQ((*a[1]) < (*a[2]), false);
@@ -2611,6 +3118,232 @@ void CreateSharedStringTest() {
TEST_EQ((*a[6]) < (*a[5]), true);
}
+void FixedLengthArrayTest() {
+ // VS10 does not support typed enums, exclude from tests
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+ // Generate an ArrayTable containing one ArrayStruct.
+ flatbuffers::FlatBufferBuilder fbb;
+ MyGame::Example::NestedStruct nStruct0(MyGame::Example::TestEnum::B);
+ TEST_NOTNULL(nStruct0.mutable_a());
+ nStruct0.mutable_a()->Mutate(0, 1);
+ nStruct0.mutable_a()->Mutate(1, 2);
+ TEST_NOTNULL(nStruct0.mutable_c());
+ nStruct0.mutable_c()->Mutate(0, MyGame::Example::TestEnum::C);
+ nStruct0.mutable_c()->Mutate(1, MyGame::Example::TestEnum::A);
+ TEST_NOTNULL(nStruct0.mutable_d());
+ nStruct0.mutable_d()->Mutate(0, flatbuffers::numeric_limits<int64_t>::max());
+ nStruct0.mutable_d()->Mutate(1, flatbuffers::numeric_limits<int64_t>::min());
+ MyGame::Example::NestedStruct nStruct1(MyGame::Example::TestEnum::C);
+ TEST_NOTNULL(nStruct1.mutable_a());
+ nStruct1.mutable_a()->Mutate(0, 3);
+ nStruct1.mutable_a()->Mutate(1, 4);
+ TEST_NOTNULL(nStruct1.mutable_c());
+ nStruct1.mutable_c()->Mutate(0, MyGame::Example::TestEnum::C);
+ nStruct1.mutable_c()->Mutate(1, MyGame::Example::TestEnum::A);
+ TEST_NOTNULL(nStruct1.mutable_d());
+ nStruct1.mutable_d()->Mutate(0, flatbuffers::numeric_limits<int64_t>::min());
+ nStruct1.mutable_d()->Mutate(1, flatbuffers::numeric_limits<int64_t>::max());
+ MyGame::Example::ArrayStruct aStruct(2, 12, 1);
+ TEST_NOTNULL(aStruct.b());
+ TEST_NOTNULL(aStruct.mutable_b());
+ TEST_NOTNULL(aStruct.mutable_d());
+ TEST_NOTNULL(aStruct.mutable_f());
+ for (int i = 0; i < aStruct.b()->size(); i++)
+ aStruct.mutable_b()->Mutate(i, i + 1);
+ aStruct.mutable_d()->Mutate(0, nStruct0);
+ aStruct.mutable_d()->Mutate(1, nStruct1);
+ auto aTable = MyGame::Example::CreateArrayTable(fbb, &aStruct);
+ fbb.Finish(aTable);
+
+ // Verify correctness of the ArrayTable.
+ flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
+ MyGame::Example::VerifyArrayTableBuffer(verifier);
+ auto p = MyGame::Example::GetMutableArrayTable(fbb.GetBufferPointer());
+ auto mArStruct = p->mutable_a();
+ TEST_NOTNULL(mArStruct);
+ TEST_NOTNULL(mArStruct->b());
+ TEST_NOTNULL(mArStruct->d());
+ TEST_NOTNULL(mArStruct->f());
+ TEST_NOTNULL(mArStruct->mutable_b());
+ TEST_NOTNULL(mArStruct->mutable_d());
+ TEST_NOTNULL(mArStruct->mutable_f());
+ mArStruct->mutable_b()->Mutate(14, -14);
+ TEST_EQ(mArStruct->a(), 2);
+ TEST_EQ(mArStruct->b()->size(), 15);
+ TEST_EQ(mArStruct->b()->Get(aStruct.b()->size() - 1), -14);
+ TEST_EQ(mArStruct->c(), 12);
+ TEST_NOTNULL(mArStruct->d()->Get(0));
+ TEST_NOTNULL(mArStruct->d()->Get(0)->a());
+ TEST_EQ(mArStruct->d()->Get(0)->a()->Get(0), 1);
+ TEST_EQ(mArStruct->d()->Get(0)->a()->Get(1), 2);
+ TEST_NOTNULL(mArStruct->d()->Get(1));
+ TEST_NOTNULL(mArStruct->d()->Get(1)->a());
+ TEST_EQ(mArStruct->d()->Get(1)->a()->Get(0), 3);
+ TEST_EQ(mArStruct->d()->Get(1)->a()->Get(1), 4);
+ TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1));
+ TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a());
+ mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a()->Mutate(1, 5);
+ TEST_EQ(5, mArStruct->d()->Get(1)->a()->Get(1));
+ TEST_EQ(MyGame::Example::TestEnum::B, mArStruct->d()->Get(0)->b());
+ TEST_NOTNULL(mArStruct->d()->Get(0)->c());
+ TEST_EQ(MyGame::Example::TestEnum::C, mArStruct->d()->Get(0)->c()->Get(0));
+ TEST_EQ(MyGame::Example::TestEnum::A, mArStruct->d()->Get(0)->c()->Get(1));
+ TEST_EQ(flatbuffers::numeric_limits<int64_t>::max(),
+ mArStruct->d()->Get(0)->d()->Get(0));
+ TEST_EQ(flatbuffers::numeric_limits<int64_t>::min(),
+ mArStruct->d()->Get(0)->d()->Get(1));
+ TEST_EQ(MyGame::Example::TestEnum::C, mArStruct->d()->Get(1)->b());
+ TEST_NOTNULL(mArStruct->d()->Get(1)->c());
+ TEST_EQ(MyGame::Example::TestEnum::C, mArStruct->d()->Get(1)->c()->Get(0));
+ TEST_EQ(MyGame::Example::TestEnum::A, mArStruct->d()->Get(1)->c()->Get(1));
+ TEST_EQ(flatbuffers::numeric_limits<int64_t>::min(),
+ mArStruct->d()->Get(1)->d()->Get(0));
+ TEST_EQ(flatbuffers::numeric_limits<int64_t>::max(),
+ mArStruct->d()->Get(1)->d()->Get(1));
+ for (int i = 0; i < mArStruct->b()->size() - 1; i++)
+ TEST_EQ(mArStruct->b()->Get(i), i + 1);
+ // Check alignment
+ TEST_EQ(0, reinterpret_cast<uintptr_t>(mArStruct->d()) % 8);
+ TEST_EQ(0, reinterpret_cast<uintptr_t>(mArStruct->f()) % 8);
+#endif
+}
+
+void NativeTypeTest() {
+ const int N = 3;
+
+ Geometry::ApplicationDataT src_data;
+ src_data.vectors.reserve(N);
+
+ for (int i = 0; i < N; ++i) {
+ src_data.vectors.push_back(
+ Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f));
+ }
+
+ flatbuffers::FlatBufferBuilder fbb;
+ fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data));
+
+ auto dstDataT = Geometry::UnPackApplicationData(fbb.GetBufferPointer());
+
+ for (int i = 0; i < N; ++i) {
+ Native::Vector3D &v = dstDataT->vectors[i];
+ TEST_EQ(v.x, 10 * i + 0.1f);
+ TEST_EQ(v.y, 10 * i + 0.2f);
+ TEST_EQ(v.z, 10 * i + 0.3f);
+ }
+}
+
+void FixedLengthArrayJsonTest(bool binary) {
+ // VS10 does not support typed enums, exclude from tests
+#if !defined(_MSC_VER) || _MSC_VER >= 1700
+ // load FlatBuffer schema (.fbs) and JSON from disk
+ std::string schemafile;
+ std::string jsonfile;
+ TEST_EQ(
+ flatbuffers::LoadFile(
+ (test_data_path + "arrays_test." + (binary ? "bfbs" : "fbs")).c_str(),
+ binary, &schemafile),
+ true);
+ TEST_EQ(flatbuffers::LoadFile((test_data_path + "arrays_test.golden").c_str(),
+ false, &jsonfile),
+ true);
+
+ // parse schema first, so we can use it to parse the data after
+ flatbuffers::Parser parserOrg, parserGen;
+ if (binary) {
+ flatbuffers::Verifier verifier(
+ reinterpret_cast<const uint8_t *>(schemafile.c_str()),
+ schemafile.size());
+ TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
+ TEST_EQ(parserOrg.Deserialize((const uint8_t *)schemafile.c_str(),
+ schemafile.size()),
+ true);
+ TEST_EQ(parserGen.Deserialize((const uint8_t *)schemafile.c_str(),
+ schemafile.size()),
+ true);
+ } else {
+ TEST_EQ(parserOrg.Parse(schemafile.c_str()), true);
+ TEST_EQ(parserGen.Parse(schemafile.c_str()), true);
+ }
+ TEST_EQ(parserOrg.Parse(jsonfile.c_str()), true);
+
+ // First, verify it, just in case:
+ flatbuffers::Verifier verifierOrg(parserOrg.builder_.GetBufferPointer(),
+ parserOrg.builder_.GetSize());
+ TEST_EQ(VerifyArrayTableBuffer(verifierOrg), true);
+
+ // Export to JSON
+ std::string jsonGen;
+ TEST_EQ(
+ GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen),
+ true);
+
+ // Import from JSON
+ TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
+
+ // Verify buffer from generated JSON
+ flatbuffers::Verifier verifierGen(parserGen.builder_.GetBufferPointer(),
+ parserGen.builder_.GetSize());
+ TEST_EQ(VerifyArrayTableBuffer(verifierGen), true);
+
+ // Compare generated buffer to original
+ TEST_EQ(parserOrg.builder_.GetSize(), parserGen.builder_.GetSize());
+ TEST_EQ(std::memcmp(parserOrg.builder_.GetBufferPointer(),
+ parserGen.builder_.GetBufferPointer(),
+ parserOrg.builder_.GetSize()),
+ 0);
+#else
+ (void)binary;
+#endif
+}
+
+void TestEmbeddedBinarySchema() {
+ // load JSON from disk
+ std::string jsonfile;
+ TEST_EQ(flatbuffers::LoadFile(
+ (test_data_path + "monsterdata_test.golden").c_str(), false,
+ &jsonfile),
+ true);
+
+ // parse schema first, so we can use it to parse the data after
+ flatbuffers::Parser parserOrg, parserGen;
+ flatbuffers::Verifier verifier(MyGame::Example::MonsterBinarySchema::data(),
+ MyGame::Example::MonsterBinarySchema::size());
+ TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
+ TEST_EQ(parserOrg.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
+ MyGame::Example::MonsterBinarySchema::size()),
+ true);
+ TEST_EQ(parserGen.Deserialize(MyGame::Example::MonsterBinarySchema::data(),
+ MyGame::Example::MonsterBinarySchema::size()),
+ true);
+ TEST_EQ(parserOrg.Parse(jsonfile.c_str()), true);
+
+ // First, verify it, just in case:
+ flatbuffers::Verifier verifierOrg(parserOrg.builder_.GetBufferPointer(),
+ parserOrg.builder_.GetSize());
+ TEST_EQ(VerifyMonsterBuffer(verifierOrg), true);
+
+ // Export to JSON
+ std::string jsonGen;
+ TEST_EQ(
+ GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen),
+ true);
+
+ // Import from JSON
+ TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
+
+ // Verify buffer from generated JSON
+ flatbuffers::Verifier verifierGen(parserGen.builder_.GetBufferPointer(),
+ parserGen.builder_.GetSize());
+ TEST_EQ(VerifyMonsterBuffer(verifierGen), true);
+
+ // Compare generated buffer to original
+ TEST_EQ(parserOrg.builder_.GetSize(), parserGen.builder_.GetSize());
+ TEST_EQ(std::memcmp(parserOrg.builder_.GetBufferPointer(),
+ parserGen.builder_.GetBufferPointer(),
+ parserOrg.builder_.GetSize()),
+ 0);
+}
+
int FlatBufferTests() {
// clang-format off
@@ -2645,11 +3378,17 @@ int FlatBufferTests() {
#endif
ParseAndGenerateTextTest(false);
ParseAndGenerateTextTest(true);
+ FixedLengthArrayJsonTest(false);
+ FixedLengthArrayJsonTest(true);
ReflectionTest(flatbuf.data(), flatbuf.size());
ParseProtoTest();
+ ParseProtoTestWithSuffix();
+ ParseProtoTestWithIncludes();
+ EvolutionTest();
UnionVectorTest();
LoadVerifyBinaryTest();
GenerateTableTextTest();
+ TestEmbeddedBinarySchema();
#endif
// clang-format on
@@ -2679,22 +3418,27 @@ int FlatBufferTests() {
EndianSwapTest();
CreateSharedStringTest();
JsonDefaultTest();
+ JsonEnumsTest();
FlexBuffersTest();
+ FlexBuffersDeprecatedTest();
UninitializedVectorTest();
EqualOperatorTest();
NumericUtilsTest();
IsAsciiUtilsTest();
ValidFloatTest();
InvalidFloatTest();
+ TestMonsterExtraFloats();
+ FixedLengthArrayTest();
+ NativeTypeTest();
return 0;
}
-int main(int /*argc*/, const char * /*argv*/ []) {
+int main(int /*argc*/, const char * /*argv*/[]) {
InitTestEngine();
std::string req_locale;
if (flatbuffers::ReadEnvironmentVariable("FLATBUFFERS_TEST_LOCALE",
- &req_locale)) {
+ &req_locale)) {
TEST_OUTPUT_LINE("The environment variable FLATBUFFERS_TEST_LOCALE=%s",
req_locale.c_str());
req_locale = flatbuffers::RemoveStringQuotes(req_locale);
diff --git a/tests/test_assert.cpp b/tests/test_assert.cpp
index ccbce235..e2b43a76 100644
--- a/tests/test_assert.cpp
+++ b/tests/test_assert.cpp
@@ -12,8 +12,8 @@ static TestFailEventListener fail_listener_ = nullptr;
void TestFail(const char *expval, const char *val, const char *exp,
const char *file, int line, const char *func) {
- TEST_OUTPUT_LINE("VALUE: \"%s\"", expval);
- TEST_OUTPUT_LINE("EXPECTED: \"%s\"", val);
+ TEST_OUTPUT_LINE("EXPECTED: \"%s\"", expval);
+ TEST_OUTPUT_LINE("VALUE: \"%s\"", val);
TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s in %s", file, line, exp,
func ? func : "");
testing_fails++;
@@ -25,13 +25,15 @@ void TestFail(const char *expval, const char *val, const char *exp,
}
void TestEqStr(const char *expval, const char *val, const char *exp,
- const char *file, int line) {
- if (strcmp(expval, val) != 0) { TestFail(expval, val, exp, file, line); }
+ const char *file, int line, const char *func) {
+ if (strcmp(expval, val) != 0) {
+ TestFail(expval, val, exp, file, line, func);
+ }
}
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \
defined(_DEBUG)
-#define FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC
+# define FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC
#endif
void InitTestEngine(TestFailEventListener listener) {
@@ -41,24 +43,9 @@ void InitTestEngine(TestFailEventListener listener) {
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
- // clang-format off
+ flatbuffers::SetupDefaultCRTReportMode();
- #ifdef _MSC_VER
- // By default, send all reports to STDOUT to prevent CI hangs.
- // Enable assert report box [Abort|Retry|Ignore] if a debugger is present.
- const int dbg_mode = (_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG) |
- (IsDebuggerPresent() ? _CRTDBG_MODE_WNDW : 0);
- (void)dbg_mode; // release mode fix
- // CrtDebug reports to _CRT_WARN channel.
- _CrtSetReportMode(_CRT_WARN, dbg_mode);
- _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
- // The assert from <assert.h> reports to _CRT_ERROR channel
- _CrtSetReportMode(_CRT_ERROR, dbg_mode);
- _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
- // Internal CRT assert channel?
- _CrtSetReportMode(_CRT_ASSERT, dbg_mode);
- _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
- #endif
+ // clang-format off
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC)
// For more thorough checking:
@@ -73,12 +60,12 @@ void InitTestEngine(TestFailEventListener listener) {
int CloseTestEngine(bool force_report) {
if (!testing_fails || force_report) {
- #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC)
- auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
- flags &= ~_CRTDBG_DELAY_FREE_MEM_DF;
- flags |= _CRTDBG_LEAK_CHECK_DF;
- _CrtSetDbgFlag(flags);
- #endif
+#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC)
+ auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
+ flags &= ~_CRTDBG_DELAY_FREE_MEM_DF;
+ flags |= _CRTDBG_LEAK_CHECK_DF;
+ _CrtSetDbgFlag(flags);
+#endif
}
return (0 != testing_fails);
}
diff --git a/tests/test_assert.h b/tests/test_assert.h
index 883586b0..353e3cee 100644
--- a/tests/test_assert.h
+++ b/tests/test_assert.h
@@ -13,20 +13,20 @@
#define FLATBUFFERS_NO_FILE_TESTS
#else
#define TEST_OUTPUT_LINE(...) \
- { printf(__VA_ARGS__); printf("\n"); }
+ do { printf(__VA_ARGS__); printf("\n"); } while(!IsConstTrue(true))
#endif
-#define TEST_EQ(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__)
-#define TEST_ASSERT(exp) TestEq(exp, true, #exp, __FILE__, __LINE__)
-#define TEST_NOTNULL(exp) TestEq(exp == NULL, false, #exp, __FILE__, __LINE__)
-#define TEST_EQ_STR(exp, val) TestEqStr(exp, val, #exp, __FILE__, __LINE__)
+#define TEST_EQ(exp, val) TestEq(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, "")
+#define TEST_ASSERT(val) TestEq(true, !!(val), "'" "true" "' != '" #val "'", __FILE__, __LINE__, "")
+#define TEST_NOTNULL(val) TestEq(true, (val) != nullptr, "'" "nullptr" "' == '" #val "'", __FILE__, __LINE__, "")
+#define TEST_EQ_STR(exp, val) TestEqStr(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, "")
#ifdef _WIN32
- #define TEST_ASSERT_FUNC(exp) TestEq(exp, true, #exp, __FILE__, __LINE__, __FUNCTION__)
- #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__, __FUNCTION__)
+ #define TEST_ASSERT_FUNC(val) TestEq(true, !!(val), "'" "true" "' != '" #val "'", __FILE__, __LINE__, __FUNCTION__)
+ #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, __FUNCTION__)
#else
- #define TEST_ASSERT_FUNC(exp) TestEq(exp, true, #exp, __FILE__, __LINE__, __PRETTY_FUNCTION__)
- #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, #exp, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+ #define TEST_ASSERT_FUNC(val) TestEq(true, !!(val), "'" "true" "' != '" #val "'", __FILE__, __LINE__, __PRETTY_FUNCTION__)
+ #define TEST_EQ_FUNC(exp, val) TestEq(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, __PRETTY_FUNCTION__)
#endif
// clang-format on
@@ -54,14 +54,55 @@ void TestFail(const char *expval, const char *val, const char *exp,
const char *file, int line, const char *func = 0);
void TestEqStr(const char *expval, const char *val, const char *exp,
- const char *file, int line);
+ const char *file, int line, const char *func = 0);
+
+// Workaround for `enum class` printing.
+// There is an issue with the printing of enums with a fixed underlying type.
+// These enums are generated by `flatc` if `--scoped-enums` is active.
+// All modern compilers have problems with `std::stringstream&<<(T v)` if T is
+// an enum with fixed type. For details see DR1601:
+// http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1601
+// https://stackoverflow.com/questions/34336024/ambiguous-overload-when-writing-an-enum-with-an-enum-base-but-only-with-clang
+
+template<typename T, bool is_enum_type = flatbuffers::is_enum<T>::value>
+struct underlying_of_scalar {
+ static_assert(flatbuffers::is_scalar<T>::value, "invalid type T");
+ typedef T type;
+};
+
+template<typename T> struct underlying_of_scalar<T, true> {
+// clang-format off
+ // There are old compilers without full C++11 support (see stl_emulation.h).
+ #if defined(FLATBUFFERS_TEMPLATES_ALIASES) && !defined(FLATBUFFERS_CPP98_STL)
+ using type = typename std::underlying_type<T>::type;
+ #else
+ typedef int64_t type;
+ #endif
+ // clang-format on
+};
+
+template<typename T>
+typename underlying_of_scalar<T>::type scalar_as_underlying(T v) {
+ return static_cast<typename underlying_of_scalar<T>::type>(v);
+}
template<typename T, typename U>
void TestEq(T expval, U val, const char *exp, const char *file, int line,
- const char *func = 0) {
- if (U(expval) != val) {
- TestFail(flatbuffers::NumToString(expval).c_str(),
- flatbuffers::NumToString(val).c_str(), exp, file, line, func);
+ const char *func) {
+ if (static_cast<U>(expval) != val) {
+ TestFail(flatbuffers::NumToString(scalar_as_underlying(expval)).c_str(),
+ flatbuffers::NumToString(scalar_as_underlying(val)).c_str(), exp,
+ file, line, func);
+ }
+}
+
+template<>
+inline void TestEq<std::string, std::string>(std::string expval,
+ std::string val, const char *exp,
+ const char *file, int line,
+ const char *func) {
+ if (expval != val) {
+ TestFail(expval.c_str(), val.c_str(), exp, file, line, func);
}
}
diff --git a/tests/test_builder.cpp b/tests/test_builder.cpp
index 8c070c11..3a12d79d 100644
--- a/tests/test_builder.cpp
+++ b/tests/test_builder.cpp
@@ -1,19 +1,14 @@
-#include "flatbuffers/stl_emulation.h"
+#include "test_builder.h"
+#include "flatbuffers/stl_emulation.h"
#include "monster_test_generated.h"
-#include "test_builder.h"
using namespace MyGame::Example;
-const std::string m1_name = "Cyberdemon";
-const Color m1_color = Color_Red;
-const std::string m2_name = "Imp";
-const Color m2_color = Color_Green;
-
struct OwnedAllocator : public flatbuffers::DefaultAllocator {};
class TestHeapBuilder : public flatbuffers::FlatBufferBuilder {
-private:
+ private:
// clang-format off
#if !defined(FLATBUFFERS_CPP98_STL)
TestHeapBuilder(const TestHeapBuilder &);
@@ -21,15 +16,15 @@ private:
#endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
-public:
+ public:
TestHeapBuilder()
- : flatbuffers::FlatBufferBuilder(2048, new OwnedAllocator(), true) {}
+ : flatbuffers::FlatBufferBuilder(2048, new OwnedAllocator(), true) {}
// clang-format off
#if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
TestHeapBuilder(TestHeapBuilder &&other)
- : FlatBufferBuilder(std::move(other)) { }
+ : FlatBufferBuilder(std::move(other)) {}
TestHeapBuilder &operator=(TestHeapBuilder &&other) {
FlatBufferBuilder::operator=(std::move(other));
@@ -47,16 +42,16 @@ struct AllocatorMember {
struct GrpcLikeMessageBuilder : private AllocatorMember,
public flatbuffers::FlatBufferBuilder {
-private:
+ private:
GrpcLikeMessageBuilder(const GrpcLikeMessageBuilder &);
GrpcLikeMessageBuilder &operator=(const GrpcLikeMessageBuilder &);
-public:
+ public:
GrpcLikeMessageBuilder()
- : flatbuffers::FlatBufferBuilder(1024, &member_allocator_, false) {}
+ : flatbuffers::FlatBufferBuilder(1024, &member_allocator_, false) {}
GrpcLikeMessageBuilder(GrpcLikeMessageBuilder &&other)
- : FlatBufferBuilder(1024, &member_allocator_, false) {
+ : FlatBufferBuilder(1024, &member_allocator_, false) {
// Default construct and swap idiom.
Swap(other);
}
@@ -77,53 +72,63 @@ public:
void Swap(GrpcLikeMessageBuilder &other) {
// No need to swap member_allocator_ because it's stateless.
FlatBufferBuilder::Swap(other);
- // After swapping the FlatBufferBuilder, we swap back the allocator, which restores
- // the original allocator back in place. This is necessary because MessageBuilder's
- // allocator is its own member (SliceAllocatorMember). The allocator passed to
- // FlatBufferBuilder::vector_downward must point to this member.
+ // After swapping the FlatBufferBuilder, we swap back the allocator, which
+ // restores the original allocator back in place. This is necessary because
+ // MessageBuilder's allocator is its own member (SliceAllocatorMember). The
+ // allocator passed to FlatBufferBuilder::vector_downward must point to this
+ // member.
buf_.swap_allocator(other.buf_);
}
};
-flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder) {
- auto name_offset = builder.CreateString(m1_name);
- return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color);
+flatbuffers::Offset<Monster> populate1(
+ flatbuffers::FlatBufferBuilder &builder) {
+ auto name_offset = builder.CreateString(m1_name());
+ return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color());
}
-flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder) {
- auto name_offset = builder.CreateString(m2_name);
- return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color);
+flatbuffers::Offset<Monster> populate2(
+ flatbuffers::FlatBufferBuilder &builder) {
+ auto name_offset = builder.CreateString(m2_name());
+ return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color());
}
-uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset) {
+uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
+ size_t &offset) {
return fbb.ReleaseRaw(size, offset);
}
void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) {
- // release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument MessageBuilder.
- // It's semantically wrong as MessageBuilder has its own ReleaseRaw member function that
- // takes three arguments. In such cases though, ~MessageBuilder() invokes
- // ~SliceAllocator() that takes care of deleting memory as it calls grpc_slice_unref.
- // Obviously, this behavior is very surprising as the pointer returned by
- // FlatBufferBuilder::ReleaseRaw is not valid as soon as MessageBuilder goes out of scope.
- // This problem does not occur with FlatBufferBuilder.
+ // release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument
+ // MessageBuilder. It's semantically wrong as MessageBuilder has its own
+ // ReleaseRaw member function that takes three arguments. In such cases
+ // though, ~MessageBuilder() invokes ~SliceAllocator() that takes care of
+ // deleting memory as it calls grpc_slice_unref. Obviously, this behavior is
+ // very surprising as the pointer returned by FlatBufferBuilder::ReleaseRaw is
+ // not valid as soon as MessageBuilder goes out of scope. This problem does
+ // not occur with FlatBufferBuilder.
}
void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) {
flatbuffers::DefaultAllocator().deallocate(buf, 0);
}
-bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color) {
+bool verify(const flatbuffers::DetachedBuffer &buf,
+ const std::string &expected_name, Color color) {
const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data());
- return (monster->name()->str() == expected_name) && (monster->color() == color);
+ return (monster->name()->str() == expected_name) &&
+ (monster->color() == color);
}
-bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color) {
- const Monster *monster = flatbuffers::GetRoot<Monster>(buf+offset);
- return (monster->name()->str() == expected_name) && (monster->color() == color);
+bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
+ Color color) {
+ const Monster *monster = flatbuffers::GetRoot<Monster>(buf + offset);
+ return (monster->name()->str() == expected_name) &&
+ (monster->color() == color);
}
-bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color) {
+bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
+ const std::string &expected_name, Color color) {
flatbuffers::DetachedBuffer buf = fbb.Release();
return verify(buf, expected_name, color);
}
@@ -136,13 +141,18 @@ void FlatBufferBuilderTest() {
BuilderTests<GrpcLikeMessageBuilder>::all_tests();
BuilderReuseTestSelector tests[4] = {
- REUSABLE_AFTER_RELEASE,
- REUSABLE_AFTER_RELEASE_RAW,
+ REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE_RAW,
REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN,
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
};
- BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+4));
- BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(TestSelector(tests, tests+4));
- BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(TestSelector(tests, tests+4));
+ BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(
+ TestSelector(tests, tests + 4));
+ BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(
+ TestSelector(tests, tests + 4));
+ BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(
+ TestSelector(tests, tests + 4));
}
+
+// Link-time check using pointer type.
+void CheckTestGeneratedIsValid(const MyGame::Example::Color &) {} \ No newline at end of file
diff --git a/tests/test_builder.h b/tests/test_builder.h
index 1e2fa0ad..5555e907 100644
--- a/tests/test_builder.h
+++ b/tests/test_builder.h
@@ -3,8 +3,9 @@
#include <set>
#include <type_traits>
-#include "monster_test_generated.h"
+
#include "flatbuffers/flatbuffers.h"
+#include "monster_test_generated.h"
#include "test_assert.h"
using MyGame::Example::Color;
@@ -14,50 +15,59 @@ namespace flatbuffers {
namespace grpc {
class MessageBuilder;
}
-}
+} // namespace flatbuffers
-template <class T, class U>
-struct is_same {
- static const bool value = false;
-};
+template<class T, class U> struct is_same { static const bool value = false; };
-template <class T>
-struct is_same<T, T> {
- static const bool value = true;
-};
+template<class T> struct is_same<T, T> { static const bool value = true; };
-extern const std::string m1_name;
-extern const Color m1_color;
-extern const std::string m2_name;
-extern const Color m2_color;
+inline std::string m1_name() { return "Cyberdemon"; }
+inline std::string m2_name() { return "Imp"; }
+inline MyGame::Example::Color m1_color() {
+ return MyGame::Example::Color_Red;
+}
+inline MyGame::Example::Color m2_color() {
+ return MyGame::Example::Color_Green;
+}
+inline void m1_color_check() {
+ // Ensure that all compilation units see the same monster_test_generated.h.
+ extern void CheckTestGeneratedIsValid(const MyGame::Example::Color&);
+ CheckTestGeneratedIsValid(m1_color());
+}
flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder);
flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder);
-uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset);
+uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
+ size_t &offset);
void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf);
void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf);
-bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color);
-bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color);
+bool verify(const flatbuffers::DetachedBuffer &buf,
+ const std::string &expected_name, Color color);
+bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
+ Color color);
-bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color);
-bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color);
+bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
+ const std::string &expected_name, Color color);
+bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
+ const std::string &expected_name, Color color);
// clang-format off
#if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
// Invokes this function when testing the following Builder types
// FlatBufferBuilder, TestHeapBuilder, and GrpcLikeMessageBuilder
-template <class Builder>
+template<class Builder>
void builder_move_assign_after_releaseraw_test(Builder b1) {
auto root_offset1 = populate1(b1);
b1.Finish(root_offset1);
size_t size, offset;
- std::shared_ptr<uint8_t> raw(b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) {
- flatbuffers::DefaultAllocator::dealloc(ptr, size);
- });
+ std::shared_ptr<uint8_t> raw(
+ b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) {
+ flatbuffers::DefaultAllocator::dealloc(ptr, size);
+ });
Builder src;
auto root_offset2 = populate2(src);
src.Finish(root_offset2);
@@ -65,16 +75,17 @@ void builder_move_assign_after_releaseraw_test(Builder b1) {
// Move into a released builder.
b1 = std::move(src);
TEST_EQ_FUNC(b1.GetSize(), src_size);
- TEST_ASSERT_FUNC(release_n_verify(b1, m2_name, m2_color));
+ TEST_ASSERT_FUNC(release_n_verify(b1, m2_name(), m2_color()));
TEST_EQ_FUNC(src.GetSize(), 0);
}
// clang-format off
#endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
-void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder b1);
+void builder_move_assign_after_releaseraw_test(
+ flatbuffers::grpc::MessageBuilder b1);
-template <class DestBuilder, class SrcBuilder = DestBuilder>
+template<class DestBuilder, class SrcBuilder = DestBuilder>
struct BuilderTests {
// clang-format off
#if !defined(FLATBUFFERS_CPP98_STL)
@@ -102,7 +113,7 @@ struct BuilderTests {
auto root_offset1 = populate1(src);
DestBuilder dst(std::move(src));
dst.Finish(root_offset1);
- TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(dst, m1_name(), m1_color()));
TEST_EQ_FUNC(src.GetSize(), 0);
}
@@ -113,7 +124,7 @@ struct BuilderTests {
auto src_size = src.GetSize();
DestBuilder dst(std::move(src));
TEST_EQ_FUNC(dst.GetSize(), src_size);
- TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(dst, m1_name(), m1_color()));
TEST_EQ_FUNC(src.GetSize(), 0);
}
@@ -124,7 +135,7 @@ struct BuilderTests {
populate2(dst);
dst = std::move(src);
dst.Finish(root_offset1);
- TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(dst, m1_name(), m1_color()));
TEST_EQ_FUNC(src.GetSize(), 0);
}
@@ -138,7 +149,7 @@ struct BuilderTests {
dst.Finish(root_offset2);
dst = std::move(src);
TEST_EQ_FUNC(dst.GetSize(), src_size);
- TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(dst, m1_name(), m1_color()));
TEST_EQ_FUNC(src.GetSize(), 0);
}
@@ -157,16 +168,17 @@ struct BuilderTests {
// Move into a released builder.
dst = std::move(src);
TEST_EQ_FUNC(dst.GetSize(), src_size);
- TEST_ASSERT_FUNC(release_n_verify(dst, m2_name, m2_color));
+ TEST_ASSERT_FUNC(release_n_verify(dst, m2_name(), m2_color()));
TEST_EQ_FUNC(src.GetSize(), 0);
}
// clang-format off
#endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
- static void builder_swap_before_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) {
+ static void builder_swap_before_finish_test(
+ bool run = is_same<DestBuilder, SrcBuilder>::value) {
/// Swap is allowed only when lhs and rhs are the same concrete type.
- if(run) {
+ if (run) {
SrcBuilder src;
auto root_offset1 = populate1(src);
auto size1 = src.GetSize();
@@ -178,14 +190,15 @@ struct BuilderTests {
dst.Finish(root_offset1);
TEST_EQ_FUNC(src.GetSize() > size2, true);
TEST_EQ_FUNC(dst.GetSize() > size1, true);
- TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
- TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(src, m2_name(), m2_color()));
+ TEST_ASSERT_FUNC(release_n_verify(dst, m1_name(), m1_color()));
}
}
- static void builder_swap_after_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) {
+ static void builder_swap_after_finish_test(
+ bool run = is_same<DestBuilder, SrcBuilder>::value) {
/// Swap is allowed only when lhs and rhs are the same concrete type.
- if(run) {
+ if (run) {
SrcBuilder src;
auto root_offset1 = populate1(src);
src.Finish(root_offset1);
@@ -197,8 +210,8 @@ struct BuilderTests {
src.Swap(dst);
TEST_EQ_FUNC(src.GetSize(), size2);
TEST_EQ_FUNC(dst.GetSize(), size1);
- TEST_ASSERT_FUNC(release_n_verify(src, m2_name, m2_color));
- TEST_ASSERT_FUNC(release_n_verify(dst, m1_name, m1_color));
+ TEST_ASSERT_FUNC(release_n_verify(src, m2_name(), m2_color()));
+ TEST_ASSERT_FUNC(release_n_verify(dst, m1_name(), m1_color()));
}
}
@@ -233,12 +246,9 @@ enum BuilderReuseTestSelector {
typedef std::set<BuilderReuseTestSelector> TestSelector;
-template <class DestBuilder, class SrcBuilder>
-struct BuilderReuseTests {
+template<class DestBuilder, class SrcBuilder> struct BuilderReuseTests {
static void builder_reusable_after_release_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE)) {
- return;
- }
+ if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
DestBuilder fbb;
std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -246,14 +256,12 @@ struct BuilderReuseTests {
auto root_offset1 = populate1(fbb);
fbb.Finish(root_offset1);
buffers.push_back(fbb.Release());
- TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
}
}
static void builder_reusable_after_releaseraw_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
- return;
- }
+ if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
DestBuilder fbb;
for (int i = 0; i < 5; ++i) {
@@ -261,7 +269,7 @@ struct BuilderReuseTests {
fbb.Finish(root_offset1);
size_t size, offset;
uint8_t *buf = release_raw_base(fbb, size, offset);
- TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
free_raw(fbb, buf);
}
}
@@ -269,10 +277,9 @@ struct BuilderReuseTests {
// clang-format off
#if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
- static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
- return;
- }
+ static void builder_reusable_after_release_and_move_assign_test(
+ TestSelector selector) {
+ if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
DestBuilder dst;
std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -280,17 +287,16 @@ struct BuilderReuseTests {
auto root_offset1 = populate1(dst);
dst.Finish(root_offset1);
buffers.push_back(dst.Release());
- TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
SrcBuilder src;
dst = std::move(src);
TEST_EQ_FUNC(src.GetSize(), 0);
}
}
- static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
- if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
- return;
- }
+ static void builder_reusable_after_releaseraw_and_move_assign_test(
+ TestSelector selector) {
+ if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
DestBuilder dst;
for (int i = 0; i < 5; ++i) {
@@ -298,7 +304,7 @@ struct BuilderReuseTests {
dst.Finish(root_offset1);
size_t size, offset;
uint8_t *buf = release_raw_base(dst, size, offset);
- TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
+ TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
free_raw(dst, buf);
SrcBuilder src;
dst = std::move(src);
@@ -323,4 +329,4 @@ struct BuilderReuseTests {
}
};
-#endif // TEST_BUILDER_H
+#endif // TEST_BUILDER_H
diff --git a/tests/unicode_test.json b/tests/unicode_test.json
index 2894f0c8..7bd26712 100644
--- a/tests/unicode_test.json
+++ b/tests/unicode_test.json
@@ -13,7 +13,7 @@
"name": "Цлїςσδε"
},
{
- "name": "フムアムカモケモ"
+ "name": "☳☶☲"
},
{
"name": "フムヤムカモケモ"
@@ -22,7 +22,7 @@
"name": "㊀㊁㊂㊃㊄"
},
{
- "name": "☳☶☲"
+ "name": "フムアムカモケモ"
},
{
"name": "𡇙𝌆"
diff --git a/tests/union_vector/Attacker.cs b/tests/union_vector/Attacker.cs
index 7f20fff8..870643f2 100644
--- a/tests/union_vector/Attacker.cs
+++ b/tests/union_vector/Attacker.cs
@@ -3,15 +3,17 @@
// </auto-generated>
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Attacker : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static Attacker GetRootAsAttacker(ByteBuffer _bb) { return GetRootAsAttacker(_bb, new Attacker()); }
public static Attacker GetRootAsAttacker(ByteBuffer _bb, Attacker obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Attacker __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int SwordAttackDamage { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
@@ -19,16 +21,40 @@ public struct Attacker : IFlatbufferObject
public static Offset<Attacker> CreateAttacker(FlatBufferBuilder builder,
int sword_attack_damage = 0) {
- builder.StartObject(1);
+ builder.StartTable(1);
Attacker.AddSwordAttackDamage(builder, sword_attack_damage);
return Attacker.EndAttacker(builder);
}
- public static void StartAttacker(FlatBufferBuilder builder) { builder.StartObject(1); }
+ public static void StartAttacker(FlatBufferBuilder builder) { builder.StartTable(1); }
public static void AddSwordAttackDamage(FlatBufferBuilder builder, int swordAttackDamage) { builder.AddInt(0, swordAttackDamage, 0); }
public static Offset<Attacker> EndAttacker(FlatBufferBuilder builder) {
- int o = builder.EndObject();
+ int o = builder.EndTable();
return new Offset<Attacker>(o);
}
+ public AttackerT UnPack() {
+ var _o = new AttackerT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(AttackerT _o) {
+ _o.SwordAttackDamage = this.SwordAttackDamage;
+ }
+ public static Offset<Attacker> Pack(FlatBufferBuilder builder, AttackerT _o) {
+ if (_o == null) return default(Offset<Attacker>);
+ return CreateAttacker(
+ builder,
+ _o.SwordAttackDamage);
+ }
};
+public class AttackerT
+{
+ [Newtonsoft.Json.JsonProperty("sword_attack_damage")]
+ public int SwordAttackDamage { get; set; }
+
+ public AttackerT() {
+ this.SwordAttackDamage = 0;
+ }
+}
+
diff --git a/tests/union_vector/Attacker.java b/tests/union_vector/Attacker.java
index ae84a4a2..22219441 100644
--- a/tests/union_vector/Attacker.java
+++ b/tests/union_vector/Attacker.java
@@ -7,9 +7,10 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Attacker extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static Attacker getRootAsAttacker(ByteBuffer _bb) { return getRootAsAttacker(_bb, new Attacker()); }
public static Attacker getRootAsAttacker(ByteBuffer _bb, Attacker obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Attacker __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int swordAttackDamage() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
@@ -17,16 +18,23 @@ public final class Attacker extends Table {
public static int createAttacker(FlatBufferBuilder builder,
int sword_attack_damage) {
- builder.startObject(1);
+ builder.startTable(1);
Attacker.addSwordAttackDamage(builder, sword_attack_damage);
return Attacker.endAttacker(builder);
}
- public static void startAttacker(FlatBufferBuilder builder) { builder.startObject(1); }
+ public static void startAttacker(FlatBufferBuilder builder) { builder.startTable(1); }
public static void addSwordAttackDamage(FlatBufferBuilder builder, int swordAttackDamage) { builder.addInt(0, swordAttackDamage, 0); }
public static int endAttacker(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Attacker get(int j) { return get(new Attacker(), j); }
+ public Attacker get(Attacker obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/union_vector/Attacker.kt b/tests/union_vector/Attacker.kt
new file mode 100644
index 00000000..d398227a
--- /dev/null
+++ b/tests/union_vector/Attacker.kt
@@ -0,0 +1,51 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Attacker : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Attacker {
+ __init(_i, _bb)
+ return this
+ }
+ val swordAttackDamage : Int
+ get() {
+ val o = __offset(4)
+ return if(o != 0) bb.getInt(o + bb_pos) else 0
+ }
+ fun mutateSwordAttackDamage(swordAttackDamage: Int) : Boolean {
+ val o = __offset(4)
+ return if (o != 0) {
+ bb.putInt(o + bb_pos, swordAttackDamage)
+ true
+ } else {
+ false
+ }
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsAttacker(_bb: ByteBuffer): Attacker = getRootAsAttacker(_bb, Attacker())
+ fun getRootAsAttacker(_bb: ByteBuffer, obj: Attacker): Attacker {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun createAttacker(builder: FlatBufferBuilder, swordAttackDamage: Int) : Int {
+ builder.startTable(1)
+ addSwordAttackDamage(builder, swordAttackDamage)
+ return endAttacker(builder)
+ }
+ fun startAttacker(builder: FlatBufferBuilder) = builder.startTable(1)
+ fun addSwordAttackDamage(builder: FlatBufferBuilder, swordAttackDamage: Int) = builder.addInt(0, swordAttackDamage, 0)
+ fun endAttacker(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ }
+}
diff --git a/tests/union_vector/BookReader.cs b/tests/union_vector/BookReader.cs
index 2cd33bfc..3f80cdf5 100644
--- a/tests/union_vector/BookReader.cs
+++ b/tests/union_vector/BookReader.cs
@@ -3,13 +3,14 @@
// </auto-generated>
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct BookReader : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
public BookReader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int BooksRead { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
@@ -20,5 +21,29 @@ public struct BookReader : IFlatbufferObject
builder.PutInt(BooksRead);
return new Offset<BookReader>(builder.Offset);
}
+ public BookReaderT UnPack() {
+ var _o = new BookReaderT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(BookReaderT _o) {
+ _o.BooksRead = this.BooksRead;
+ }
+ public static Offset<BookReader> Pack(FlatBufferBuilder builder, BookReaderT _o) {
+ if (_o == null) return default(Offset<BookReader>);
+ return CreateBookReader(
+ builder,
+ _o.BooksRead);
+ }
};
+public class BookReaderT
+{
+ [Newtonsoft.Json.JsonProperty("books_read")]
+ public int BooksRead { get; set; }
+
+ public BookReaderT() {
+ this.BooksRead = 0;
+ }
+}
+
diff --git a/tests/union_vector/BookReader.java b/tests/union_vector/BookReader.java
index 1cb516e9..a6d1b437 100644
--- a/tests/union_vector/BookReader.java
+++ b/tests/union_vector/BookReader.java
@@ -7,7 +7,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class BookReader extends Struct {
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public BookReader __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int booksRead() { return bb.getInt(bb_pos + 0); }
@@ -18,5 +18,12 @@ public final class BookReader extends Struct {
builder.putInt(booksRead);
return builder.offset();
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public BookReader get(int j) { return get(new BookReader(), j); }
+ public BookReader get(BookReader obj, int j) { return obj.__assign(__element(j), bb); }
+ }
}
diff --git a/tests/union_vector/BookReader.kt b/tests/union_vector/BookReader.kt
new file mode 100644
index 00000000..fc41473b
--- /dev/null
+++ b/tests/union_vector/BookReader.kt
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class BookReader : Struct() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : BookReader {
+ __init(_i, _bb)
+ return this
+ }
+ val booksRead : Int get() = bb.getInt(bb_pos + 0)
+ fun mutateBooksRead(booksRead: Int) : ByteBuffer = bb.putInt(bb_pos + 0, booksRead)
+ companion object {
+ fun createBookReader(builder: FlatBufferBuilder, booksRead: Int) : Int {
+ builder.prep(4, 4)
+ builder.putInt(booksRead)
+ return builder.offset()
+ }
+ }
+}
diff --git a/tests/union_vector/Character.cs b/tests/union_vector/Character.cs
index b873b73d..d067e222 100644
--- a/tests/union_vector/Character.cs
+++ b/tests/union_vector/Character.cs
@@ -2,14 +2,91 @@
// automatically generated by the FlatBuffers compiler, do not modify
// </auto-generated>
+[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public enum Character : byte
{
- NONE = 0,
- MuLan = 1,
- Rapunzel = 2,
- Belle = 3,
- BookFan = 4,
- Other = 5,
- Unused = 6,
+ NONE = 0,
+ MuLan = 1,
+ Rapunzel = 2,
+ Belle = 3,
+ BookFan = 4,
+ Other = 5,
+ Unused = 6,
};
+public class CharacterUnion {
+ public Character Type { get; set; }
+ public object Value { get; set; }
+
+ public CharacterUnion() {
+ this.Type = Character.NONE;
+ this.Value = null;
+ }
+
+ public T As<T>() where T : class { return this.Value as T; }
+ public AttackerT AsMuLan() { return this.As<AttackerT>(); }
+ public RapunzelT AsRapunzel() { return this.As<RapunzelT>(); }
+ public BookReaderT AsBelle() { return this.As<BookReaderT>(); }
+ public BookReaderT AsBookFan() { return this.As<BookReaderT>(); }
+ public string AsOther() { return this.As<string>(); }
+ public string AsUnused() { return this.As<string>(); }
+
+ public static int Pack(FlatBuffers.FlatBufferBuilder builder, CharacterUnion _o) {
+ switch (_o.Type) {
+ default: return 0;
+ case Character.MuLan: return Attacker.Pack(builder, _o.AsMuLan()).Value;
+ case Character.Rapunzel: return Rapunzel.Pack(builder, _o.AsRapunzel()).Value;
+ case Character.Belle: return BookReader.Pack(builder, _o.AsBelle()).Value;
+ case Character.BookFan: return BookReader.Pack(builder, _o.AsBookFan()).Value;
+ case Character.Other: return builder.CreateString(_o.AsOther()).Value;
+ case Character.Unused: return builder.CreateString(_o.AsUnused()).Value;
+ }
+ }
+}
+
+public class CharacterUnion_JsonConverter : Newtonsoft.Json.JsonConverter {
+ public override bool CanConvert(System.Type objectType) {
+ return objectType == typeof(CharacterUnion) || objectType == typeof(System.Collections.Generic.List<CharacterUnion>);
+ }
+ public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) {
+ var _olist = value as System.Collections.Generic.List<CharacterUnion>;
+ if (_olist != null) {
+ writer.WriteStartArray();
+ foreach (var _o in _olist) { this.WriteJson(writer, _o, serializer); }
+ writer.WriteEndArray();
+ } else {
+ this.WriteJson(writer, value as CharacterUnion, serializer);
+ }
+ }
+ public void WriteJson(Newtonsoft.Json.JsonWriter writer, CharacterUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
+ if (_o == null) return;
+ serializer.Serialize(writer, _o.Value);
+ }
+ public override object ReadJson(Newtonsoft.Json.JsonReader reader, System.Type objectType, object existingValue, Newtonsoft.Json.JsonSerializer serializer) {
+ var _olist = existingValue as System.Collections.Generic.List<CharacterUnion>;
+ if (_olist != null) {
+ for (var _j = 0; _j < _olist.Count; ++_j) {
+ reader.Read();
+ _olist[_j] = this.ReadJson(reader, _olist[_j], serializer);
+ }
+ reader.Read();
+ return _olist;
+ } else {
+ return this.ReadJson(reader, existingValue as CharacterUnion, serializer);
+ }
+ }
+ public CharacterUnion ReadJson(Newtonsoft.Json.JsonReader reader, CharacterUnion _o, Newtonsoft.Json.JsonSerializer serializer) {
+ if (_o == null) return null;
+ switch (_o.Type) {
+ default: break;
+ case Character.MuLan: _o.Value = serializer.Deserialize<AttackerT>(reader); break;
+ case Character.Rapunzel: _o.Value = serializer.Deserialize<RapunzelT>(reader); break;
+ case Character.Belle: _o.Value = serializer.Deserialize<BookReaderT>(reader); break;
+ case Character.BookFan: _o.Value = serializer.Deserialize<BookReaderT>(reader); break;
+ case Character.Other: _o.Value = serializer.Deserialize<string>(reader); break;
+ case Character.Unused: _o.Value = serializer.Deserialize<string>(reader); break;
+ }
+ return _o;
+ }
+}
+
diff --git a/tests/union_vector/Character.kt b/tests/union_vector/Character.kt
new file mode 100644
index 00000000..ff7dd5e8
--- /dev/null
+++ b/tests/union_vector/Character.kt
@@ -0,0 +1,17 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Character_ private constructor() {
+ companion object {
+ const val NONE: UByte = 0u
+ const val MuLan: UByte = 1u
+ const val Rapunzel: UByte = 2u
+ const val Belle: UByte = 3u
+ const val BookFan: UByte = 4u
+ const val Other: UByte = 5u
+ const val Unused: UByte = 6u
+ val names : Array<String> = arrayOf("NONE", "MuLan", "Rapunzel", "Belle", "BookFan", "Other", "Unused")
+ fun name(e: Int) : String = names[e]
+ }
+}
diff --git a/tests/union_vector/Movie.cs b/tests/union_vector/Movie.cs
index 6a9130a7..f3d8e6ee 100644
--- a/tests/union_vector/Movie.cs
+++ b/tests/union_vector/Movie.cs
@@ -3,31 +3,33 @@
// </auto-generated>
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Movie : IFlatbufferObject
{
private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
+ public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_1_12_0(); }
public static Movie GetRootAsMovie(ByteBuffer _bb) { return GetRootAsMovie(_bb, new Movie()); }
public static Movie GetRootAsMovie(ByteBuffer _bb, Movie obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool MovieBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MOVI"); }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public Character MainCharacterType { get { int o = __p.__offset(4); return o != 0 ? (Character)__p.bb.Get(o + __p.bb_pos) : Character.NONE; } }
- public bool MutateMainCharacterType(Character main_character_type) { int o = __p.__offset(4); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)main_character_type); return true; } else { return false; } }
- public TTable? MainCharacter<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o) : null; }
+ public TTable? MainCharacter<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(6); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
+ public string MainCharacterAsString() { int o = __p.__offset(6); return o != 0 ? __p.__string(o + __p.bb_pos) : null; }
public Character CharactersType(int j) { int o = __p.__offset(8); return o != 0 ? (Character)__p.bb.Get(__p.__vector(o) + j * 1) : (Character)0; }
public int CharactersTypeLength { get { int o = __p.__offset(8); return o != 0 ? __p.__vector_len(o) : 0; } }
#if ENABLE_SPAN_T
- public Span<byte> GetCharactersTypeBytes() { return __p.__vector_as_span(8); }
+ public Span<Character> GetCharactersTypeBytes() { return __p.__vector_as_span<Character>(8, 1); }
#else
public ArraySegment<byte>? GetCharactersTypeBytes() { return __p.__vector_as_arraysegment(8); }
#endif
- public Character[] GetCharactersTypeArray() { return __p.__vector_as_array<Character>(8); }
- 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 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 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) : null; }
+ public string CharactersAsString(int j) { int o = __p.__offset(10); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
public int CharactersLength { get { int o = __p.__offset(10); return o != 0 ? __p.__vector_len(o) : 0; } }
public static Offset<Movie> CreateMovie(FlatBufferBuilder builder,
@@ -35,7 +37,7 @@ public struct Movie : IFlatbufferObject
int main_characterOffset = 0,
VectorOffset characters_typeOffset = default(VectorOffset),
VectorOffset charactersOffset = default(VectorOffset)) {
- builder.StartObject(4);
+ builder.StartTable(4);
Movie.AddCharacters(builder, charactersOffset);
Movie.AddCharactersType(builder, characters_typeOffset);
Movie.AddMainCharacter(builder, main_characterOffset);
@@ -43,7 +45,7 @@ public struct Movie : IFlatbufferObject
return Movie.EndMovie(builder);
}
- public static void StartMovie(FlatBufferBuilder builder) { builder.StartObject(4); }
+ public static void StartMovie(FlatBufferBuilder builder) { builder.StartTable(4); }
public static void AddMainCharacterType(FlatBufferBuilder builder, Character mainCharacterType) { builder.AddByte(0, (byte)mainCharacterType, 0); }
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); }
@@ -55,10 +57,147 @@ public struct Movie : IFlatbufferObject
public static VectorOffset CreateCharactersVectorBlock(FlatBufferBuilder builder, int[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
public static void StartCharactersVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
public static Offset<Movie> EndMovie(FlatBufferBuilder builder) {
- int o = builder.EndObject();
+ int o = builder.EndTable();
return new Offset<Movie>(o);
}
public static void FinishMovieBuffer(FlatBufferBuilder builder, Offset<Movie> offset) { builder.Finish(offset.Value, "MOVI"); }
public static void FinishSizePrefixedMovieBuffer(FlatBufferBuilder builder, Offset<Movie> offset) { builder.FinishSizePrefixed(offset.Value, "MOVI"); }
+ public MovieT UnPack() {
+ var _o = new MovieT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(MovieT _o) {
+ _o.MainCharacter = new CharacterUnion();
+ _o.MainCharacter.Type = this.MainCharacterType;
+ switch (this.MainCharacterType) {
+ default: break;
+ case Character.MuLan:
+ _o.MainCharacter.Value = this.MainCharacter<Attacker>().HasValue ? this.MainCharacter<Attacker>().Value.UnPack() : null;
+ break;
+ case Character.Rapunzel:
+ _o.MainCharacter.Value = this.MainCharacter<Rapunzel>().HasValue ? this.MainCharacter<Rapunzel>().Value.UnPack() : null;
+ break;
+ case Character.Belle:
+ _o.MainCharacter.Value = this.MainCharacter<BookReader>().HasValue ? this.MainCharacter<BookReader>().Value.UnPack() : null;
+ break;
+ case Character.BookFan:
+ _o.MainCharacter.Value = this.MainCharacter<BookReader>().HasValue ? this.MainCharacter<BookReader>().Value.UnPack() : null;
+ break;
+ case Character.Other:
+ _o.MainCharacter.Value = this.MainCharacterAsString();
+ break;
+ case Character.Unused:
+ _o.MainCharacter.Value = this.MainCharacterAsString();
+ break;
+ }
+ _o.Characters = new List<CharacterUnion>();
+ for (var _j = 0; _j < this.CharactersLength; ++_j) {
+ var _o_Characters = new CharacterUnion();
+ _o_Characters.Type = this.CharactersType(_j);
+ switch (this.CharactersType(_j)) {
+ default: break;
+ case Character.MuLan:
+ _o_Characters.Value = this.Characters<Attacker>(_j).HasValue ? this.Characters<Attacker>(_j).Value.UnPack() : null;
+ break;
+ case Character.Rapunzel:
+ _o_Characters.Value = this.Characters<Rapunzel>(_j).HasValue ? this.Characters<Rapunzel>(_j).Value.UnPack() : null;
+ break;
+ case Character.Belle:
+ _o_Characters.Value = this.Characters<BookReader>(_j).HasValue ? this.Characters<BookReader>(_j).Value.UnPack() : null;
+ break;
+ case Character.BookFan:
+ _o_Characters.Value = this.Characters<BookReader>(_j).HasValue ? this.Characters<BookReader>(_j).Value.UnPack() : null;
+ break;
+ case Character.Other:
+ _o_Characters.Value = this.CharactersAsString(_j);
+ break;
+ case Character.Unused:
+ _o_Characters.Value = this.CharactersAsString(_j);
+ break;
+ }
+ _o.Characters.Add(_o_Characters);
+ }
+ }
+ public static Offset<Movie> Pack(FlatBufferBuilder builder, MovieT _o) {
+ if (_o == null) return default(Offset<Movie>);
+ var _main_character_type = _o.MainCharacter == null ? Character.NONE : _o.MainCharacter.Type;
+ var _main_character = _o.MainCharacter == null ? 0 : CharacterUnion.Pack(builder, _o.MainCharacter);
+ var _characters_type = default(VectorOffset);
+ if (_o.Characters != null) {
+ var __characters_type = new Character[_o.Characters.Count];
+ for (var _j = 0; _j < __characters_type.Length; ++_j) { __characters_type[_j] = _o.Characters[_j].Type; }
+ _characters_type = CreateCharactersTypeVector(builder, __characters_type);
+ }
+ var _characters = default(VectorOffset);
+ if (_o.Characters != null) {
+ var __characters = new int[_o.Characters.Count];
+ for (var _j = 0; _j < __characters.Length; ++_j) { __characters[_j] = CharacterUnion.Pack(builder, _o.Characters[_j]); }
+ _characters = CreateCharactersVector(builder, __characters);
+ }
+ return CreateMovie(
+ builder,
+ _main_character_type,
+ _main_character,
+ _characters_type,
+ _characters);
+ }
};
+public class MovieT
+{
+ [Newtonsoft.Json.JsonProperty("main_character_type")]
+ private Character MainCharacterType {
+ get {
+ return this.MainCharacter != null ? this.MainCharacter.Type : Character.NONE;
+ }
+ set {
+ this.MainCharacter = new CharacterUnion();
+ this.MainCharacter.Type = value;
+ }
+ }
+ [Newtonsoft.Json.JsonProperty("main_character")]
+ [Newtonsoft.Json.JsonConverter(typeof(CharacterUnion_JsonConverter))]
+ public CharacterUnion MainCharacter { get; set; }
+ [Newtonsoft.Json.JsonProperty("characters_type")]
+ private Character[] CharactersType {
+ get {
+ if (this.Characters == null) return null;
+ var _o = new Character[this.Characters.Count];
+ for (var _j = 0; _j < _o.Length; ++_j) { _o[_j] = this.Characters[_j].Type; }
+ return _o;
+ }
+ set {
+ this.Characters = new List<CharacterUnion>();
+ for (var _j = 0; _j < value.Length; ++_j) {
+ var _o = new CharacterUnion();
+ _o.Type = value[_j];
+ this.Characters.Add(_o);
+ }
+ }
+ }
+ [Newtonsoft.Json.JsonProperty("characters")]
+ [Newtonsoft.Json.JsonConverter(typeof(CharacterUnion_JsonConverter))]
+ public List<CharacterUnion> Characters { get; set; }
+
+ public MovieT() {
+ this.MainCharacter = null;
+ this.Characters = null;
+ }
+
+ public static MovieT DeserializeFromJson(string jsonText) {
+ return Newtonsoft.Json.JsonConvert.DeserializeObject<MovieT>(jsonText);
+ }
+ public string SerializeToJson() {
+ return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
+ }
+ public static MovieT DeserializeFromBinary(byte[] fbBuffer) {
+ return Movie.GetRootAsMovie(new ByteBuffer(fbBuffer)).UnPack();
+ }
+ public byte[] SerializeToBinary() {
+ var fbb = new FlatBufferBuilder(0x10000);
+ fbb.Finish(Movie.Pack(fbb, this).Value);
+ return fbb.DataBuffer.ToSizedArray();
+ }
+}
+
diff --git a/tests/union_vector/Movie.java b/tests/union_vector/Movie.java
index 75791d31..d8a97bf6 100644
--- a/tests/union_vector/Movie.java
+++ b/tests/union_vector/Movie.java
@@ -7,29 +7,32 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Movie extends Table {
+ public static void ValidateVersion() { Constants.FLATBUFFERS_1_12_0(); }
public static Movie getRootAsMovie(ByteBuffer _bb) { return getRootAsMovie(_bb, new Movie()); }
public static Movie getRootAsMovie(ByteBuffer _bb, Movie obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
public static boolean MovieBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MOVI"); }
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; vtable_start = bb_pos - bb.getInt(bb_pos); vtable_size = bb.getShort(vtable_start); }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Movie __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public byte mainCharacterType() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 0; }
- public boolean mutateMainCharacterType(byte main_character_type) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, main_character_type); return true; } else { return false; } }
- public Table mainCharacter(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o) : null; }
+ public Table mainCharacter(Table obj) { int o = __offset(6); return o != 0 ? __union(obj, o + bb_pos) : null; }
public byte charactersType(int j) { int o = __offset(8); return o != 0 ? bb.get(__vector(o) + j * 1) : 0; }
public int charactersTypeLength() { int o = __offset(8); return o != 0 ? __vector_len(o) : 0; }
+ public ByteVector charactersTypeVector() { return charactersTypeVector(new ByteVector()); }
+ public ByteVector charactersTypeVector(ByteVector obj) { int o = __offset(8); return o != 0 ? obj.__assign(__vector(o), bb) : null; }
public ByteBuffer charactersTypeAsByteBuffer() { return __vector_as_bytebuffer(8, 1); }
public ByteBuffer charactersTypeInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 8, 1); }
- public boolean mutateCharactersType(int j, byte characters_type) { int o = __offset(8); if (o != 0) { bb.put(__vector(o) + j * 1, characters_type); return true; } else { return false; } }
- public Table characters(Table obj, int j) { int o = __offset(10); return o != 0 ? __union(obj, __vector(o) + j * 4 - bb_pos) : null; }
+ public Table characters(Table obj, int j) { int o = __offset(10); return o != 0 ? __union(obj, __vector(o) + j * 4) : null; }
public int charactersLength() { int o = __offset(10); return o != 0 ? __vector_len(o) : 0; }
+ public UnionVector charactersVector() { return charactersVector(new UnionVector()); }
+ public UnionVector charactersVector(UnionVector obj) { int o = __offset(10); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
public static int createMovie(FlatBufferBuilder builder,
byte main_character_type,
int main_characterOffset,
int characters_typeOffset,
int charactersOffset) {
- builder.startObject(4);
+ builder.startTable(4);
Movie.addCharacters(builder, charactersOffset);
Movie.addCharactersType(builder, characters_typeOffset);
Movie.addMainCharacter(builder, main_characterOffset);
@@ -37,7 +40,7 @@ public final class Movie extends Table {
return Movie.endMovie(builder);
}
- public static void startMovie(FlatBufferBuilder builder) { builder.startObject(4); }
+ public static void startMovie(FlatBufferBuilder builder) { builder.startTable(4); }
public static void addMainCharacterType(FlatBufferBuilder builder, byte mainCharacterType) { builder.addByte(0, mainCharacterType, 0); }
public static void addMainCharacter(FlatBufferBuilder builder, int mainCharacterOffset) { builder.addOffset(1, mainCharacterOffset, 0); }
public static void addCharactersType(FlatBufferBuilder builder, int charactersTypeOffset) { builder.addOffset(2, charactersTypeOffset, 0); }
@@ -47,10 +50,17 @@ public final class Movie extends Table {
public static int 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(); }
public static void startCharactersVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
public static int endMovie(FlatBufferBuilder builder) {
- int o = builder.endObject();
+ int o = builder.endTable();
return o;
}
public static void finishMovieBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MOVI"); }
public static void finishSizePrefixedMovieBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset, "MOVI"); }
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Movie get(int j) { return get(new Movie(), j); }
+ public Movie get(Movie obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
+ }
}
diff --git a/tests/union_vector/Movie.kt b/tests/union_vector/Movie.kt
new file mode 100644
index 00000000..6ebb9bbd
--- /dev/null
+++ b/tests/union_vector/Movie.kt
@@ -0,0 +1,114 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Movie : Table() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Movie {
+ __init(_i, _bb)
+ return this
+ }
+ val mainCharacterType : UByte
+ get() {
+ val o = __offset(4)
+ return if(o != 0) bb.get(o + bb_pos).toUByte() else 0u
+ }
+ fun mutateMainCharacterType(mainCharacterType: UByte) : Boolean {
+ val o = __offset(4)
+ return if (o != 0) {
+ bb.put(o + bb_pos, mainCharacterType.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ fun mainCharacter(obj: Table) : Table? {
+ val o = __offset(6); return if (o != 0) __union(obj, o + bb_pos) else null
+ }
+ fun charactersType(j: Int) : UByte {
+ val o = __offset(8)
+ return if (o != 0) {
+ bb.get(__vector(o) + j * 1).toUByte()
+ } else {
+ 0u
+ }
+ }
+ val charactersTypeLength : Int
+ get() {
+ val o = __offset(8); return if (o != 0) __vector_len(o) else 0
+ }
+ val charactersTypeAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(8, 1)
+ fun charactersTypeInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 8, 1)
+ fun mutateCharactersType(j: Int, charactersType: UByte) : Boolean {
+ val o = __offset(8)
+ return if (o != 0) {
+ bb.put(__vector(o) + j * 1, charactersType.toByte())
+ true
+ } else {
+ false
+ }
+ }
+ fun characters(obj: Table, j: Int) : Table? {
+ val o = __offset(10)
+ return if (o != 0) {
+ __union(obj, __vector(o) + j * 4 - bb_pos)
+ } else {
+ null
+ }
+ }
+ val charactersLength : Int
+ get() {
+ val o = __offset(10); return if (o != 0) __vector_len(o) else 0
+ }
+ companion object {
+ fun validateVersion() = Constants.FLATBUFFERS_1_12_0()
+ fun getRootAsMovie(_bb: ByteBuffer): Movie = getRootAsMovie(_bb, Movie())
+ fun getRootAsMovie(_bb: ByteBuffer, obj: Movie): Movie {
+ _bb.order(ByteOrder.LITTLE_ENDIAN)
+ return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
+ }
+ fun MovieBufferHasIdentifier(_bb: ByteBuffer) : Boolean = __has_identifier(_bb, "MOVI")
+ fun createMovie(builder: FlatBufferBuilder, mainCharacterType: UByte, mainCharacterOffset: Int, charactersTypeOffset: Int, charactersOffset: Int) : Int {
+ builder.startTable(4)
+ addCharacters(builder, charactersOffset)
+ addCharactersType(builder, charactersTypeOffset)
+ addMainCharacter(builder, mainCharacterOffset)
+ addMainCharacterType(builder, mainCharacterType)
+ return endMovie(builder)
+ }
+ fun startMovie(builder: FlatBufferBuilder) = builder.startTable(4)
+ fun addMainCharacterType(builder: FlatBufferBuilder, mainCharacterType: UByte) = builder.addByte(0, mainCharacterType.toByte(), 0)
+ fun addMainCharacter(builder: FlatBufferBuilder, mainCharacter: Int) = builder.addOffset(1, mainCharacter, 0)
+ fun addCharactersType(builder: FlatBufferBuilder, charactersType: Int) = builder.addOffset(2, charactersType, 0)
+ fun createCharactersTypeVector(builder: FlatBufferBuilder, data: UByteArray) : Int {
+ builder.startVector(1, data.size, 1)
+ for (i in data.size - 1 downTo 0) {
+ builder.addByte(data[i].toByte())
+ }
+ return builder.endVector()
+ }
+ fun startCharactersTypeVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(1, numElems, 1)
+ fun addCharacters(builder: FlatBufferBuilder, characters: Int) = builder.addOffset(3, characters, 0)
+ fun createCharactersVector(builder: FlatBufferBuilder, data: IntArray) : Int {
+ builder.startVector(4, data.size, 4)
+ for (i in data.size - 1 downTo 0) {
+ builder.addOffset(data[i])
+ }
+ return builder.endVector()
+ }
+ fun startCharactersVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
+ fun endMovie(builder: FlatBufferBuilder) : Int {
+ val o = builder.endTable()
+ return o
+ }
+ fun finishMovieBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset, "MOVI")
+ fun finishSizePrefixedMovieBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset, "MOVI")
+ }
+}
diff --git a/tests/union_vector/Rapunzel.cs b/tests/union_vector/Rapunzel.cs
index f95f1004..e5ffff8e 100644
--- a/tests/union_vector/Rapunzel.cs
+++ b/tests/union_vector/Rapunzel.cs
@@ -3,13 +3,14 @@
// </auto-generated>
using global::System;
+using global::System.Collections.Generic;
using global::FlatBuffers;
public struct Rapunzel : IFlatbufferObject
{
private Struct __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } }
- public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __p = new Struct(_i, _bb); }
public Rapunzel __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int HairLength { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
@@ -20,5 +21,29 @@ public struct Rapunzel : IFlatbufferObject
builder.PutInt(HairLength);
return new Offset<Rapunzel>(builder.Offset);
}
+ public RapunzelT UnPack() {
+ var _o = new RapunzelT();
+ this.UnPackTo(_o);
+ return _o;
+ }
+ public void UnPackTo(RapunzelT _o) {
+ _o.HairLength = this.HairLength;
+ }
+ public static Offset<Rapunzel> Pack(FlatBufferBuilder builder, RapunzelT _o) {
+ if (_o == null) return default(Offset<Rapunzel>);
+ return CreateRapunzel(
+ builder,
+ _o.HairLength);
+ }
};
+public class RapunzelT
+{
+ [Newtonsoft.Json.JsonProperty("hair_length")]
+ public int HairLength { get; set; }
+
+ public RapunzelT() {
+ this.HairLength = 0;
+ }
+}
+
diff --git a/tests/union_vector/Rapunzel.java b/tests/union_vector/Rapunzel.java
index 7cc66794..96d3cfea 100644
--- a/tests/union_vector/Rapunzel.java
+++ b/tests/union_vector/Rapunzel.java
@@ -7,7 +7,7 @@ import com.google.flatbuffers.*;
@SuppressWarnings("unused")
public final class Rapunzel extends Struct {
- public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
+ public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
public Rapunzel __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public int hairLength() { return bb.getInt(bb_pos + 0); }
@@ -18,5 +18,12 @@ public final class Rapunzel extends Struct {
builder.putInt(hairLength);
return builder.offset();
}
+
+ public static final class Vector extends BaseVector {
+ public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
+
+ public Rapunzel get(int j) { return get(new Rapunzel(), j); }
+ public Rapunzel get(Rapunzel obj, int j) { return obj.__assign(__element(j), bb); }
+ }
}
diff --git a/tests/union_vector/Rapunzel.kt b/tests/union_vector/Rapunzel.kt
new file mode 100644
index 00000000..080a7f7d
--- /dev/null
+++ b/tests/union_vector/Rapunzel.kt
@@ -0,0 +1,27 @@
+// automatically generated by the FlatBuffers compiler, do not modify
+
+import java.nio.*
+import kotlin.math.sign
+import com.google.flatbuffers.*
+
+@Suppress("unused")
+@ExperimentalUnsignedTypes
+class Rapunzel : Struct() {
+
+ fun __init(_i: Int, _bb: ByteBuffer) {
+ __reset(_i, _bb)
+ }
+ fun __assign(_i: Int, _bb: ByteBuffer) : Rapunzel {
+ __init(_i, _bb)
+ return this
+ }
+ val hairLength : Int get() = bb.getInt(bb_pos + 0)
+ fun mutateHairLength(hairLength: Int) : ByteBuffer = bb.putInt(bb_pos + 0, hairLength)
+ companion object {
+ fun createRapunzel(builder: FlatBufferBuilder, hairLength: Int) : Int {
+ builder.prep(4, 4)
+ builder.putInt(hairLength)
+ return builder.offset()
+ }
+ }
+}
diff --git a/tests/union_vector/union_vector_generated.h b/tests/union_vector/union_vector_generated.h
index 757a9584..a03f7227 100644
--- a/tests/union_vector/union_vector_generated.h
+++ b/tests/union_vector/union_vector_generated.h
@@ -7,6 +7,7 @@
#include "flatbuffers/flatbuffers.h"
struct Attacker;
+struct AttackerBuilder;
struct AttackerT;
struct Rapunzel;
@@ -14,6 +15,7 @@ struct Rapunzel;
struct BookReader;
struct Movie;
+struct MovieBuilder;
struct MovieT;
bool operator==(const AttackerT &lhs, const AttackerT &rhs);
@@ -59,7 +61,7 @@ inline const Character (&EnumValuesCharacter())[7] {
}
inline const char * const *EnumNamesCharacter() {
- static const char * const names[] = {
+ static const char * const names[8] = {
"NONE",
"MuLan",
"Rapunzel",
@@ -73,7 +75,7 @@ inline const char * const *EnumNamesCharacter() {
}
inline const char *EnumNameCharacter(Character e) {
- if (e < Character_NONE || e > Character_Unused) return "";
+ if (flatbuffers::IsOutRange(e, Character_NONE, Character_Unused)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesCharacter()[index];
}
@@ -86,8 +88,8 @@ struct CharacterUnion {
CharacterUnion(CharacterUnion&& u) FLATBUFFERS_NOEXCEPT :
type(Character_NONE), value(nullptr)
{ std::swap(type, u.type); std::swap(value, u.value); }
- CharacterUnion(const CharacterUnion &) FLATBUFFERS_NOEXCEPT;
- CharacterUnion &operator=(const CharacterUnion &u) FLATBUFFERS_NOEXCEPT
+ CharacterUnion(const CharacterUnion &);
+ CharacterUnion &operator=(const CharacterUnion &u)
{ CharacterUnion t(u); std::swap(type, t.type); std::swap(value, t.value); return *this; }
CharacterUnion &operator=(CharacterUnion &&u) FLATBUFFERS_NOEXCEPT
{ std::swap(type, u.type); std::swap(value, u.value); return *this; }
@@ -278,6 +280,7 @@ inline bool operator!=(const AttackerT &lhs, const AttackerT &rhs) {
struct Attacker FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef AttackerT NativeTableType;
+ typedef AttackerBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return AttackerTypeTable();
}
@@ -301,6 +304,7 @@ struct Attacker FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct AttackerBuilder {
+ typedef Attacker Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_sword_attack_damage(int32_t sword_attack_damage) {
@@ -349,6 +353,7 @@ inline bool operator!=(const MovieT &lhs, const MovieT &rhs) {
struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef MovieT NativeTableType;
+ typedef MovieBuilder Builder;
static const flatbuffers::TypeTable *MiniReflectTypeTable() {
return MovieTypeTable();
}
@@ -361,9 +366,6 @@ struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
Character main_character_type() const {
return static_cast<Character>(GetField<uint8_t>(VT_MAIN_CHARACTER_TYPE, 0));
}
- bool mutate_main_character_type(Character _main_character_type) {
- return SetField<uint8_t>(VT_MAIN_CHARACTER_TYPE, static_cast<uint8_t>(_main_character_type), 0);
- }
const void *main_character() const {
return GetPointer<const void *>(VT_MAIN_CHARACTER);
}
@@ -418,6 +420,7 @@ struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct MovieBuilder {
+ typedef Movie Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_main_character_type(Character main_character_type) {
@@ -477,15 +480,15 @@ inline flatbuffers::Offset<Movie> CreateMovieDirect(
flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
inline AttackerT *Attacker::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new AttackerT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<AttackerT> _o = flatbuffers::unique_ptr<AttackerT>(new AttackerT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void Attacker::UnPackTo(AttackerT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = sword_attack_damage(); _o->sword_attack_damage = _e; };
+ { auto _e = sword_attack_damage(); _o->sword_attack_damage = _e; }
}
inline flatbuffers::Offset<Attacker> Attacker::Pack(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -503,18 +506,18 @@ inline flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuild
}
inline MovieT *Movie::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
- auto _o = new MovieT();
- UnPackTo(_o, _resolver);
- return _o;
+ flatbuffers::unique_ptr<MovieT> _o = flatbuffers::unique_ptr<MovieT>(new MovieT());
+ UnPackTo(_o.get(), _resolver);
+ return _o.release();
}
inline void Movie::UnPackTo(MovieT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
- { auto _e = main_character_type(); _o->main_character.type = _e; };
- { auto _e = main_character(); if (_e) _o->main_character.value = CharacterUnion::UnPack(_e, main_character_type(), _resolver); };
- { auto _e = characters_type(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].type = static_cast<Character>(_e->Get(_i)); } } };
- { auto _e = characters(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].value = CharacterUnion::UnPack(_e->Get(_i), characters_type()->GetEnum<Character>(_i), _resolver); } } };
+ { auto _e = main_character_type(); _o->main_character.type = _e; }
+ { auto _e = main_character(); if (_e) _o->main_character.value = CharacterUnion::UnPack(_e, main_character_type(), _resolver); }
+ { auto _e = characters_type(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].type = static_cast<Character>(_e->Get(_i)); } } }
+ { auto _e = characters(); if (_e) { _o->characters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->characters[_i].value = CharacterUnion::UnPack(_e->Get(_i), characters_type()->GetEnum<Character>(_i), _resolver); } } }
}
inline flatbuffers::Offset<Movie> Movie::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MovieT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
@@ -563,7 +566,7 @@ inline bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Ch
auto ptr = reinterpret_cast<const flatbuffers::String *>(obj);
return verifier.VerifyString(ptr);
}
- default: return false;
+ default: return true;
}
}
@@ -639,7 +642,7 @@ inline flatbuffers::Offset<void> CharacterUnion::Pack(flatbuffers::FlatBufferBui
}
}
-inline CharacterUnion::CharacterUnion(const CharacterUnion &u) FLATBUFFERS_NOEXCEPT : type(u.type), value(nullptr) {
+inline CharacterUnion::CharacterUnion(const CharacterUnion &u) : type(u.type), value(nullptr) {
switch (type) {
case Character_MuLan: {
value = new AttackerT(*reinterpret_cast<AttackerT *>(u.value));
@@ -850,4 +853,10 @@ inline flatbuffers::unique_ptr<MovieT> UnPackMovie(
return flatbuffers::unique_ptr<MovieT>(GetMovie(buf)->UnPack(res));
}
+inline flatbuffers::unique_ptr<MovieT> UnPackSizePrefixedMovie(
+ const void *buf,
+ const flatbuffers::resolver_function_t *res = nullptr) {
+ return flatbuffers::unique_ptr<MovieT>(GetSizePrefixedMovie(buf)->UnPack(res));
+}
+
#endif // FLATBUFFERS_GENERATED_UNIONVECTOR_H_
diff --git a/tests/union_vector/union_vector_generated.js b/tests/union_vector/union_vector_generated.js
index 380da2d3..2507c31f 100644
--- a/tests/union_vector/union_vector_generated.js
+++ b/tests/union_vector/union_vector_generated.js
@@ -17,13 +17,13 @@ var Character = {
* @enum {string}
*/
var CharacterName = {
- 0: 'NONE',
- 1: 'MuLan',
- 2: 'Rapunzel',
- 3: 'Belle',
- 4: 'BookFan',
- 5: 'Other',
- 6: 'Unused'
+ '0': 'NONE',
+ '1': 'MuLan',
+ '2': 'Rapunzel',
+ '3': 'Belle',
+ '4': 'BookFan',
+ '5': 'Other',
+ '6': 'Unused'
};
/**
@@ -62,6 +62,16 @@ Attacker.getRootAsAttacker = function(bb, obj) {
};
/**
+ * @param {flatbuffers.ByteBuffer} bb
+ * @param {Attacker=} obj
+ * @returns {Attacker}
+ */
+Attacker.getSizePrefixedRootAsAttacker = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
* @returns {number}
*/
Attacker.prototype.swordAttackDamage = function() {
@@ -274,6 +284,16 @@ Movie.getRootAsMovie = function(bb, obj) {
/**
* @param {flatbuffers.ByteBuffer} bb
+ * @param {Movie=} obj
+ * @returns {Movie}
+ */
+Movie.getSizePrefixedRootAsMovie = function(bb, obj) {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param {flatbuffers.ByteBuffer} bb
* @returns {boolean}
*/
Movie.bufferHasIdentifier = function(bb) {
@@ -289,21 +309,6 @@ Movie.prototype.mainCharacterType = function() {
};
/**
- * @param {Character} value
- * @returns {boolean}
- */
-Movie.prototype.mutate_main_character_type = function(value) {
- var offset = this.bb.__offset(this.bb_pos, 4);
-
- if (offset === 0) {
- return false;
- }
-
- this.bb.writeUint8(this.bb_pos + offset, value);
- return true;
-};
-
-/**
* @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table}
*/
@@ -455,6 +460,14 @@ Movie.finishMovieBuffer = function(builder, offset) {
/**
* @param {flatbuffers.Builder} builder
+ * @param {flatbuffers.Offset} offset
+ */
+Movie.finishSizePrefixedMovieBuffer = function(builder, offset) {
+ builder.finish(offset, 'MOVI', true);
+};
+
+/**
+ * @param {flatbuffers.Builder} builder
* @param {Character} mainCharacterType
* @param {flatbuffers.Offset} mainCharacterOffset
* @param {flatbuffers.Offset} charactersTypeOffset
diff --git a/tests/union_vector/union_vector_generated.ts b/tests/union_vector/union_vector_generated.ts
index 44ffbcf6..4c30b667 100644
--- a/tests/union_vector/union_vector_generated.ts
+++ b/tests/union_vector/union_vector_generated.ts
@@ -37,7 +37,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):Attacker {
* @returns Attacker
*/
static getRootAsAttacker(bb:flatbuffers.ByteBuffer, obj?:Attacker):Attacker {
- return (obj || new Attacker).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new Attacker()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Attacker= obj
+ * @returns Attacker
+ */
+static getSizePrefixedRootAsAttacker(bb:flatbuffers.ByteBuffer, obj?:Attacker):Attacker {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new Attacker()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -221,7 +231,17 @@ __init(i:number, bb:flatbuffers.ByteBuffer):Movie {
* @returns Movie
*/
static getRootAsMovie(bb:flatbuffers.ByteBuffer, obj?:Movie):Movie {
- return (obj || new Movie).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+ return (obj || new Movie()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
+};
+
+/**
+ * @param flatbuffers.ByteBuffer bb
+ * @param Movie= obj
+ * @returns Movie
+ */
+static getSizePrefixedRootAsMovie(bb:flatbuffers.ByteBuffer, obj?:Movie):Movie {
+ bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
+ return (obj || new Movie()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
@@ -241,21 +261,6 @@ mainCharacterType():Character {
};
/**
- * @param Character value
- * @returns boolean
- */
-mutate_main_character_type(value:Character):boolean {
- var offset = this.bb!.__offset(this.bb_pos, 4);
-
- if (offset === 0) {
- return false;
- }
-
- this.bb!.writeUint8(this.bb_pos + offset, value);
- return true;
-};
-
-/**
* @param flatbuffers.Table obj
* @returns ?flatbuffers.Table
*/
@@ -405,6 +410,14 @@ static finishMovieBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset)
builder.finish(offset, 'MOVI');
};
+/**
+ * @param flatbuffers.Builder builder
+ * @param flatbuffers.Offset offset
+ */
+static finishSizePrefixedMovieBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
+ builder.finish(offset, 'MOVI', true);
+};
+
static createMovie(builder:flatbuffers.Builder, mainCharacterType:Character, mainCharacterOffset:flatbuffers.Offset, charactersTypeOffset:flatbuffers.Offset, charactersOffset:flatbuffers.Offset):flatbuffers.Offset {
Movie.startMovie(builder);
Movie.addMainCharacterType(builder, mainCharacterType);