Squashed 'third_party/flatbuffers/' changes from e5f331db9..bc44fad35
bc44fad35 UnPackTo disable merge by default (#7527)
4fca4dc60 [TS/JS] Move TS tests to dedicated folder and deps upgrade (#7508)
036032373 Bump junit from 4.13 to 4.13.1 in /java (#7526)
89dfb43f3 Replace `bash JavaTest.sh` with `mvn test` (#7500)
c49aff4b6 enabled cpp17 tests in CI (#7524)
56e60223c prevent force_align attribute on enums (#7523)
89b1f5aa1 remove travis config (#7522)
b90159823 [Java][Flexbuffers] Add API to add nullables into the buffer. (#7521)
8cdc6a288 Install BuildFlatBuffers.cmake (#7519)
a67e35aff Moves all of the swift test code into tests/swift (#7509)
f124e41ae Updated Readme
4c954181c [Java][FlexBuffers] throwing exception for untyped fixed vectors (#7507)
7f7547737 [Android] Remove maven dependency of flatbuffers and use source folder (#7503)
a79d61ea8 Fixes issue with cocoapods failing to be published because of docc (#7505)
d465b39c3 [CMake]: fix breaking find_package change (#7499) (#7502)
c5a609dc2 [C#] Prepares for official Nuget release (#7496)
5634dc3d0 [ISSUE-6268] returns NaN insteadof nan (#7498)
37e37b8ca Updates cocoapods version (#7497)
8fd4534fb update android multidex setting (#7495)
d5427da52 Disable Android Build (#7494)
06c5c7ed0 FlatBuffers Version 2.0.8 (#7492)
b190ce11b Verifier Refinements (#7490)
bf5d23230 Namer applied to Typescript generator (#7488)
ce382d6dd [TS/JS] Add rollup and config to generate iife flatbuffers bundle (#7449)
41d9add7e C++: Add option to skip verifying nested flatbuffers (#7489)
6a8742754 [C++] support native_inline attribute for vector of tables (#7479)
694add668 Refactor test.cpp (#7487)
7edf8c908 Update scorecard to 1.1.2
b86387442 Fix typos (#7483)
e2eb5ee67 Include <array> head in stl_emulation.h (#7480)
994502b6d Version number in file package.json updated to 2.0.7 (#7476)
fa41e8367 [C++] Fixed crash when copying table with empty shared strings (#7477)
799cc8f7b Use type traits for specialization (#7475)
b7eb44147 Disable RTTI and rework use in idl_gen_ts.cpp (#7474)
8d01c5859 CMake project version detection made more robust (#7473)
237e8b71f Moved compiler warnings around (#7471)
eeb8fd60d Include builder.addOffset for vector of structs (#7470)
fef2ffc4d Use schema include name for keep-prefix (#7469)
8367664f1 Flatbuffers Version 2.0.7 (#7462)
d6f06c33f Reworked keep prefix (#7456)
627e8bf36 update grpc version (#7457)
883c42b7d disabling unpackto optimization (#7459)
7aae0af30 Remove old GRPC bash script and convert to python3 (#7454)
b057aa917 Grouped anonymous namespaces together, (#7455)
f1b26ff7f Change to GetTypeName (#7453)
9610a666b Generate SLSA signatures for Released zip files (#7450)
1e0f75a64 [WIP] speedup (#7452)
82b75407a Wrap types in namespace for --ts-flat-files and --gen-all (#7451)
f7c511957 Audit and fixups for GCC and Clang (#7212)
a66de58af Partial support for --ts-flat-files and --gen-all (#7446)
a3508f36d [Kotlin] Make sure namespace path exist for code generation (#7357)
137fec716 Stop using __has_trivial_copy on recent clang versions. (#7443)
214125e41 [C#] Rework how sorted vectors are looked up (#7441)
44a7dc999 Define minimum buffer size (#7440)
3cc2daa78 make_span overloads for pointer to vector (#7374) (#7435)
fa1174aa7 [TypeScript] Fix namespaceless schema generation (#7432)
83d4e2a10 Add checks to verifier (#7438)
8a09f3fb0 Fix FlexBuffers JS/TS bug https://github.com/google/flatbuffers/issues/6934 (#7434)
9dbe819ef Add flatc python tests to CI (#7437)
67c414958 Update TypeScriptTest.py to work better cross platform (#7436)
8b8c7dbdf Update gitingore to reflect name change (#7431)
2ee20a5f3 Remove auto including locale functions (#7430)
4be605604 [C++] Set StructDef::has_key property when deserializing from binary schema (#7386) (#7428)
fc5d86f1e [C++] Make template parameter in stl_emulation.h more explicit to avoid conflicts with cpprestsdk U macro (#7424)
9dce287ad Issue#6959 :Updated Automatically generated rust files. (#7425)
7798be3bb avoid zero-as-null-pointer warning (#7423)
966362e07 [C++] Vector of Tables equality (#7415)
a89c279ed [golang] Perform keyword escaping after case conversion (#7421)
a212b3c03 Turn of fail fast for C++ CI
9230f600d Remove stringop-overflow from error (#7422)
c79362156 [golang] Add support for text parsing with json struct tags (#7353)
ee2ced236 Moved TypeScriptTests to python script (#7411)
468c00a3f Rebased: grpc/compiler: Respect filename suffix and extension during code generation (#7414)
47c757f71 Add tests for flatc (#7405)
9a5ff8900 Add FLATBUFFERS_STRICT_MODE (#7408)
950444a34 [TS] Use TextEncoder and TextDecoder (#7400)
30d76198c Compilation issue msys2 #7399 (#7409)
cce3a66f0 Delete .travis directory
8d1cc6ac7 Revert "Compilation issue msys2 (#7403)" (#7407)
5b207639a Update readme.md
359e0f9d6 Revert "grpc/compiler: Respect filename suffix and extension during code generation (#7343)" (#7406)
ebbed0513 Delete cpp-linter.yml
aa395e5a5 (#7323) Rename CMake files according to project name (#7378)
32328075d Fix error msg format when generate GRPC failed (#7350)
97e89c5ac grpc/compiler: Respect filename suffix and extension during code generation (#7343)
5f6672be4 Fix Clang-Cl compile on Windows (#7308)
28e858c85 [TS/Bazel] Minor improvements to typescript.bzl (#7300)
987bebe67 [TS] fix incorrect reverse when writting array of structs (#7271)
ec0129369 Fix FlexBuffers Verifier tracking vectors reuse at wrong offset
50dd385b3 Add missing const (#7401)
da702cfd8 Compilation issue msys2 (#7403)
6e2791640 keep-prefix keeps relative pathing (#7394)
52fce5e53 fix(#7360): grpc used deprecated functions (#7361)
b7f13cd8e cpp_generator: comment out unused parameter to avoid warnings (#7381)
e42985e5a Updated Newtonsoft.Json to 13.0.1 (#7393)
0a8064637 Fix references to LICENSE file (#7377)
b9eea76a8 [Dart] Implement putBool to fix errors when serializing structs with bools (#7359)
1b9030015 Bump Newtonsoft.Json from 12.0.3 to 13.0.1 in /tests/FlatBuffers.Test (#7363)
83a43fc79 Reenable optional json (#7352)
5f0137602 Only include direct included filed (#7348)
9a1913a87 Revert "Implement optional scalars for JSON (#7322)" (#7351)
b4647beb8 Revert "Move reflection_ts_fbs into a separate directory (#7342)" (#7349)
d6060977a Remove asserting in verifier for flattests
987aa5b5e move -Wextra-semi to GCC 8.0+
42acdb63c [TS] Don't generate self-imports with --ts-flat-file (#7340)
0cc1aeb8c [golang] Create missing namespace directory structure (#7324) (#7325)
ba6c67170 [Kotlin] Remove download benchmark files dependency (#7314)
d2f33fc45 Disable Android on Linux CI build
0d1b72cbc [TS] fix ts import path issue (#7298)
9fce2fbf2 replace io/ioutil to os (#7281)
a18ea40d6 Implement optional scalars for JSON (#7322)
090caa280 Move reflection_ts_fbs into a separate directory (#7342)
49e1ea333 Implement optional scalars for Python (#7318)
11a198870 Started implementation for private flags in rust (#7269)
967df08b1 Adds full supposed for Wasm in the swift lib (#7328)
9aa08a429 Use keep case for Rust union discriminant type. (#7321)
9e8c758f5 Add explicit return types to lobster generated code (#7312)
74a25536b Add size check to fix out of bounds read risk (#7304)
12917af8a Update Rust docs page (#7296)
1ea2472f7 [swift] add had<ArrayName> property for arrays to check presence in a message (#7280)
0fe13cb28 Remove span ConstIterator/cbegin()/cend(). (#7295)
385dddc66 Namerkot (#7245)
750dde766 Make `flatc` generate Rust files not requiring `std` (#7273)
9917a168c [swift] Make swift module public (#7274)
76d3cca19 Rust: fix a name conflict when building with "no_std" feature (#7268)
c86e6d0e3 json inf parsing
d34dc32c2 fix include order
234d86c92 fixed off-by-one in parser
746c73b91 Add Annotations for Monster schema and example buffer
0bbfd4b2e fixes for annotator
716521953 Update readme.md (#7257)
a45f564cf [performance] Add aggressive systematic inlining in ByteBuffer and FlatBufferBuilder (#7253)
9d45a6403 more google merge fixes
ccfb4c20b Handle +/-inf in protos (#7256)
7bcd857b8 Specialize CreateVector with std::initializer_list (#7254)
23c8ab34c Swift update performance benchmark infrastructure (#7255)
70002dc5c various fixes for google merge
6e0e79f24 Add test for nested buffer verifier (#7252)
b856368d7 Turn off go modules temporary until we get a proper fix (#7251)
e37156a30 Keep the underlying storage capacity when clearing the FlatBufferBuilder. Gives a significant performance boost for serialisation of many small messages. (#7250)
a10b0e546 Java namer variable keep case (#7249)
275b73994 allow overriding FLATBUFFERS_MAX_ALIGNMENT
9d1ce9a10 Add parameter back to EndVector (#7246)
79afe6c3d Make Java namespaces keep case by default (#7243)
c6dbb2230 Add write permissions for labeller
18bacd3ea Expand test to make sure {}-initializers are properly understood by template. (#7242)
a2c913aec Add -Wnon-virtual-dtor
67b33b294 set workflows permissions to read-only (#7239)
7b5fd2bd0 [Kotlin] Fix key lookup returning null clashing with default value (#7237)
7181d7770 [Java] Fix key lookup returning null clashing with default value (#7236)
7f663b120 Allow CreateVectorOfStrings() to work with any string-type. (#7238)
173ebb694 Fixes a bug where the create function doesnt optional + required items (#7228)
d65823948 [Kotlin] Update gradle to 7.4.1 and simplify config files. (#7231)
ab4bf59e8 remove toascii (#7234)
eee44bbb2 disable cpp-linter (#7229)
a63fa51a1 Create cpp-linter.yml (#7208)
2049e5210 Adds a way to verify/exposes Entities ids (#7221)
832c618f5 Adds implementation flag for swift (#7202)
14615699f Started to migrate to target_compile_options (#7222)
20aad0c41 [C++] stl_emulation span::count_ is not const anymore (#7226) (#7227)
f083b33f2 code gen flexbuffer verifier (#7207)
bf17df346 [C++] generate sorted #include directives (#7213)
35281dedb Fix for [C++] flatc generates invalid Code in the default constructor for structs, when --cpp-field-case-style is used #7209 (#7211)
c9651b742 Add overloads for C# ByteBuffer/FlatBufferBuilder to allow adding vector blocks from ArraySegments or IntPtr (#7193)
26c3b3ada Update codeql.yml
da6e1b985 Update codeql.yml
ad27d751e Added Oss fuzz badge
0aab623cb Create codeql.yml
6a446bdd8 maximize parallel builds in CI (#7206)
21fb5cbbc Create scorecards.yml
0da6f9486 [C++] Static assert on Flatbuffers Version (#7203)
59e971308 reduce fuzzing time to 1 minute in CI
40866a892 fixed padding in struct for annotated binary (#7199)
b71d968fa Apply Namer prefix/suffix to other generators (#7197)
fac0d7be0 Apply Namer to Java. (#7194)
6c5603fd9 [C#] Fix collision of field name and type name (#7149)
2d21853a7 monster fuzzer fix for json default scalars
fec1a8d01 [swift] Add bazel configuration for Swift (#7195)
7fd857623 structured comments (#7192)
a4cb1599d Namerdart (#7187)
ae4ce7265 fuzzed binary annotator (#7188)
e2be0c0b0 Handle root offset and root table vtable invalidation (#7177)
2ad408697 [TS] Fix generation of struct members in object api (#7148)
4213d9105 VerifySizePrefixed (reflection::Schema) and GetAnySizePrefixedRoot added (#7181)
5a13f622c Correctly parse lists of enums in Dart generated code (#7157)
23a7e4e0b Adds no-includes flags to the swift code generator (#7182)
eeb49c275 Move flatbuffer_ts_library to typescript.bzl (#7183)
824763b31 Typo in flatc options (warning-as-errors instead of warnings-as-errors) (#7180)
d3aeee32b Annotated Flatbuffer Binary (#7174)
0bceba24d [Lua] Apply Namer to Lua (#7171)
b8c77d404 Make inclusion of header <optional> opt-out via macro (#7168)
8468eab83 Namersw (#7167)
2b2e8d4ae Nameroverloads (#7164)
b80b32bfa Use DESCRIPTION only if CMake version >= 3.9 (#7166)
Change-Id: Ic2681dabb1a798b7515e62753ee06aecb9933260
git-subtree-dir: third_party/flatbuffers
git-subtree-split: bc44fad35271e43fd7a79b4d691ac9e41708797f
Signed-off-by: Austin Schuh <austin.schuh@bluerivertech.com>
diff --git a/tests/monster_test.cpp b/tests/monster_test.cpp
new file mode 100644
index 0000000..4fc9e14
--- /dev/null
+++ b/tests/monster_test.cpp
@@ -0,0 +1,845 @@
+#include "monster_test.h"
+
+#include <vector>
+
+#include "flatbuffers/flatbuffer_builder.h"
+#include "flatbuffers/idl.h"
+#include "flatbuffers/registry.h"
+#include "flatbuffers/verifier.h"
+#include "is_quiet_nan.h"
+#include "monster_extra_generated.h"
+#include "monster_test_generated.h"
+#include "test_assert.h"
+
+namespace flatbuffers {
+namespace tests {
+
+// Shortcuts for the infinity.
+static const auto infinity_f = std::numeric_limits<float>::infinity();
+static const auto infinity_d = std::numeric_limits<double>::infinity();
+
+using namespace MyGame::Example;
+
+// example of how to build up a serialized buffer algorithmically:
+flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
+ flatbuffers::FlatBufferBuilder builder;
+
+ auto vec = Vec3(1, 2, 3, 0, Color_Red, Test(10, 20));
+
+ auto name = builder.CreateString("MyMonster");
+
+ // Use the initializer_list specialization of CreateVector.
+ auto inventory =
+ builder.CreateVector<uint8_t>({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+
+ // Alternatively, create the vector first, and fill in data later:
+ // unsigned char *inv_buf = nullptr;
+ // auto inventory = builder.CreateUninitializedVector<unsigned char>(
+ // 10, &inv_buf);
+ // memcpy(inv_buf, inv_data, 10);
+
+ Test tests[] = { Test(10, 20), Test(30, 40) };
+ auto testv = builder.CreateVectorOfStructs(tests, 2);
+
+ // Create a vector of structures from a lambda.
+ auto testv2 = builder.CreateVectorOfStructs<Test>(
+ 2, [&](size_t i, Test *s) -> void { *s = tests[i]; });
+
+ // create monster with very few fields set:
+ // (same functionality as CreateMonster below, but sets fields manually)
+ flatbuffers::Offset<Monster> mlocs[3];
+ auto fred = builder.CreateString("Fred");
+ auto barney = builder.CreateString("Barney");
+ auto wilma = builder.CreateString("Wilma");
+ MonsterBuilder mb1(builder);
+ mb1.add_name(fred);
+ mlocs[0] = mb1.Finish();
+ MonsterBuilder mb2(builder);
+ mb2.add_name(barney);
+ mb2.add_hp(1000);
+ mlocs[1] = mb2.Finish();
+ MonsterBuilder mb3(builder);
+ mb3.add_name(wilma);
+ mlocs[2] = mb3.Finish();
+
+ // Create an array of strings. Also test string pooling, and lambdas.
+ auto vecofstrings =
+ builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(
+ 4,
+ [](size_t i, flatbuffers::FlatBufferBuilder *b)
+ -> flatbuffers::Offset<flatbuffers::String> {
+ static const char *names[] = { "bob", "fred", "bob", "fred" };
+ return b->CreateSharedString(names[i]);
+ },
+ &builder);
+
+ // Creating vectors of strings in one convenient call.
+ std::vector<std::string> names2;
+ names2.push_back("jane");
+ names2.push_back("mary");
+ auto vecofstrings2 = builder.CreateVectorOfStrings(names2);
+
+ // Creating vectors from types that are different from std::string
+ std::vector<const char *> names3;
+ names3.push_back("foo");
+ names3.push_back("bar");
+ builder.CreateVectorOfStrings(names3); // Also an accepted type
+
+#ifdef FLATBUFFERS_HAS_STRING_VIEW
+ std::vector<flatbuffers::string_view> names4;
+ names3.push_back("baz");
+ names3.push_back("quux");
+ builder.CreateVectorOfStrings(names4); // Also an accepted type
+#endif
+
+ // Make sure the template deduces an initializer as std::vector<std::string>
+ builder.CreateVectorOfStrings({ "hello", "world" });
+
+ // Create many vectors of strings
+ std::vector<std::string> manyNames;
+ for (auto i = 0; i < 100; i++) { manyNames.push_back("john_doe"); }
+ auto manyNamesVec = builder.CreateVectorOfStrings(manyNames);
+ TEST_EQ(false, manyNamesVec.IsNull());
+ auto manyNamesVec2 =
+ builder.CreateVectorOfStrings(manyNames.cbegin(), manyNames.cend());
+ TEST_EQ(false, manyNamesVec2.IsNull());
+
+ // Create an array of sorted tables, can be used with binary search when read:
+ auto vecoftables = builder.CreateVectorOfSortedTables(mlocs, 3);
+
+ // Create an array of sorted structs,
+ // can be used with binary search when read:
+ std::vector<Ability> abilities;
+ abilities.push_back(Ability(4, 40));
+ abilities.push_back(Ability(3, 30));
+ abilities.push_back(Ability(2, 20));
+ abilities.push_back(Ability(0, 0));
+ auto vecofstructs = builder.CreateVectorOfSortedStructs(&abilities);
+
+ flatbuffers::Offset<Stat> mlocs_stats[1];
+ auto miss = builder.CreateString("miss");
+ StatBuilder mb_miss(builder);
+ mb_miss.add_id(miss);
+ mb_miss.add_val(0);
+ mb_miss.add_count(0); // key
+ mlocs_stats[0] = mb_miss.Finish();
+ auto vec_of_stats = builder.CreateVectorOfSortedTables(mlocs_stats, 1);
+
+ // Create a nested FlatBuffer.
+ // Nested FlatBuffers are stored in a ubyte vector, which can be convenient
+ // since they can be memcpy'd around much easier than other FlatBuffer
+ // values. They have little overhead compared to storing the table directly.
+ // As a test, create a mostly empty Monster buffer:
+ flatbuffers::FlatBufferBuilder nested_builder;
+ auto nmloc = CreateMonster(nested_builder, nullptr, 0, 0,
+ nested_builder.CreateString("NestedMonster"));
+ FinishMonsterBuffer(nested_builder, nmloc);
+ // Now we can store the buffer in the parent. Note that by default, vectors
+ // are only aligned to their elements or size field, so in this case if the
+ // buffer contains 64-bit elements, they may not be correctly aligned. We fix
+ // that with:
+ builder.ForceVectorAlignment(nested_builder.GetSize(), sizeof(uint8_t),
+ nested_builder.GetBufferMinAlignment());
+ // If for whatever reason you don't have the nested_builder available, you
+ // can substitute flatbuffers::largest_scalar_t (64-bit) for the alignment, or
+ // the largest force_align value in your schema if you're using it.
+ auto nested_flatbuffer_vector = builder.CreateVector(
+ nested_builder.GetBufferPointer(), nested_builder.GetSize());
+
+ // Test a nested FlexBuffer:
+ flexbuffers::Builder flexbuild;
+ flexbuild.Int(1234);
+ flexbuild.Finish();
+ auto flex = builder.CreateVector(flexbuild.GetBuffer());
+ // Test vector of enums.
+ Color colors[] = { Color_Blue, Color_Green };
+ // 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<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,
+ MyGame::Example::Race_None, 0, vec_of_stats);
+
+ FinishMonsterBuffer(builder, mloc);
+
+ // clang-format off
+ #ifdef FLATBUFFERS_TEST_VERBOSE
+ // print byte data for debugging:
+ auto p = builder.GetBufferPointer();
+ for (flatbuffers::uoffset_t i = 0; i < builder.GetSize(); i++)
+ printf("%d ", p[i]);
+ #endif
+ // clang-format on
+
+ // return the buffer for the caller to use.
+ auto bufferpointer =
+ reinterpret_cast<const char *>(builder.GetBufferPointer());
+ buffer.assign(bufferpointer, bufferpointer + builder.GetSize());
+
+ return builder.Release();
+}
+
+// example of accessing a buffer loaded in memory:
+void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, bool pooled) {
+ // First, verify the buffers integrity (optional)
+ flatbuffers::Verifier verifier(flatbuf, length);
+ std::vector<uint8_t> flex_reuse_tracker;
+ verifier.SetFlexReuseTracker(&flex_reuse_tracker);
+ TEST_EQ(VerifyMonsterBuffer(verifier), true);
+
+ // clang-format off
+ #ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
+ std::vector<uint8_t> test_buff;
+ test_buff.resize(length * 2);
+ std::memcpy(&test_buff[0], flatbuf, length);
+ std::memcpy(&test_buff[length], flatbuf, length);
+
+ flatbuffers::Verifier verifier1(&test_buff[0], length);
+ TEST_EQ(VerifyMonsterBuffer(verifier1), true);
+ TEST_EQ(verifier1.GetComputedSize(), length);
+
+ flatbuffers::Verifier verifier2(&test_buff[length], length);
+ TEST_EQ(VerifyMonsterBuffer(verifier2), true);
+ TEST_EQ(verifier2.GetComputedSize(), length);
+ #endif
+ // clang-format on
+
+ TEST_EQ(strcmp(MonsterIdentifier(), "MONS"), 0);
+ TEST_EQ(MonsterBufferHasIdentifier(flatbuf), true);
+ TEST_EQ(strcmp(MonsterExtension(), "mon"), 0);
+
+ // Access the buffer from the root.
+ auto monster = GetMonster(flatbuf);
+
+ TEST_EQ(monster->hp(), 80);
+ TEST_EQ(monster->mana(), 150); // default
+ TEST_EQ_STR(monster->name()->c_str(), "MyMonster");
+ // Can't access the following field, it is deprecated in the schema,
+ // which means accessors are not generated:
+ // monster.friendly()
+
+ auto pos = monster->pos();
+ TEST_NOTNULL(pos);
+ TEST_EQ(pos->z(), 3);
+ TEST_EQ(pos->test3().a(), 10);
+ TEST_EQ(pos->test3().b(), 20);
+
+ auto inventory = monster->inventory();
+ TEST_EQ(VectorLength(inventory), 10UL); // Works even if inventory is null.
+ TEST_NOTNULL(inventory);
+ 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());
+ size_t 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());
+
+ 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());
+
+ 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());
+
+ 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);
+
+ // Example of accessing a union:
+ TEST_EQ(monster->test_type(), Any_Monster); // First make sure which it is.
+ auto monster2 = reinterpret_cast<const Monster *>(monster->test());
+ TEST_NOTNULL(monster2);
+ TEST_EQ_STR(monster2->name()->c_str(), "Fred");
+
+ // Example of accessing a vector of strings:
+ auto vecofstrings = monster->testarrayofstring();
+ TEST_EQ(vecofstrings->size(), 4U);
+ TEST_EQ_STR(vecofstrings->Get(0)->c_str(), "bob");
+ TEST_EQ_STR(vecofstrings->Get(1)->c_str(), "fred");
+ if (pooled) {
+ // These should have pointer equality because of string pooling.
+ TEST_EQ(vecofstrings->Get(0)->c_str(), vecofstrings->Get(2)->c_str());
+ TEST_EQ(vecofstrings->Get(1)->c_str(), vecofstrings->Get(3)->c_str());
+ }
+
+ auto vecofstrings2 = monster->testarrayofstring2();
+ if (vecofstrings2) {
+ TEST_EQ(vecofstrings2->size(), 2U);
+ TEST_EQ_STR(vecofstrings2->Get(0)->c_str(), "jane");
+ TEST_EQ_STR(vecofstrings2->Get(1)->c_str(), "mary");
+ }
+
+ // 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) {
+ 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");
+ TEST_EQ_STR(vecoftables->Get(2)->name()->c_str(), "Wilma");
+ TEST_NOTNULL(vecoftables->LookupByKey("Barney"));
+ TEST_NOTNULL(vecoftables->LookupByKey("Fred"));
+ TEST_NOTNULL(vecoftables->LookupByKey("Wilma"));
+
+ // Test accessing a vector of sorted structs
+ auto vecofstructs = monster->testarrayofsortedstruct();
+ if (vecofstructs) { // not filled in monster_test.bfbs
+ for (flatbuffers::uoffset_t i = 0; i < vecofstructs->size() - 1; i++) {
+ auto left = vecofstructs->Get(i);
+ auto right = vecofstructs->Get(i + 1);
+ TEST_EQ(true, (left->KeyCompareLessThan(right)));
+ }
+ TEST_NOTNULL(vecofstructs->LookupByKey(0)); // test default value
+ TEST_NOTNULL(vecofstructs->LookupByKey(3));
+ TEST_EQ(static_cast<const Ability *>(nullptr),
+ vecofstructs->LookupByKey(5));
+ }
+
+ if (auto vec_of_stat = monster->scalar_key_sorted_tables()) {
+ auto stat_0 = vec_of_stat->LookupByKey(static_cast<uint16_t>(0u));
+ TEST_NOTNULL(stat_0);
+ TEST_NOTNULL(stat_0->id());
+ TEST_EQ(0, stat_0->count());
+ TEST_EQ_STR("miss", stat_0->id()->c_str());
+ }
+
+ // Test nested FlatBuffers if available:
+ auto nested_buffer = monster->testnestedflatbuffer();
+ if (nested_buffer) {
+ // nested_buffer is a vector of bytes you can memcpy. However, if you
+ // actually want to access the nested data, this is a convenient
+ // accessor that directly gives you the root table:
+ auto nested_monster = monster->testnestedflatbuffer_nested_root();
+ TEST_EQ_STR(nested_monster->name()->c_str(), "NestedMonster");
+ }
+
+ // Test flexbuffer if available:
+ auto flex = monster->flex();
+ // flex is a vector of bytes you can memcpy etc.
+ TEST_EQ(flex->size(), 4); // Encoded FlexBuffer bytes.
+ // However, if you actually want to access the nested data, this is a
+ // convenient accessor that directly gives you the root value:
+ TEST_EQ(monster->flex_flexbuffer_root().AsInt16(), 1234);
+
+ // Test vector of enums:
+ auto colors = monster->vector_of_enums();
+ if (colors) {
+ TEST_EQ(colors->size(), 2);
+ TEST_EQ(colors->Get(0), Color_Blue);
+ TEST_EQ(colors->Get(1), Color_Green);
+ }
+
+ // Since Flatbuffers uses explicit mechanisms to override the default
+ // compiler alignment, double check that the compiler indeed obeys them:
+ // (Test consists of a short and byte):
+ TEST_EQ(flatbuffers::AlignOf<Test>(), 2UL);
+ TEST_EQ(sizeof(Test), 4UL);
+
+ const flatbuffers::Vector<const Test *> *tests_array[] = {
+ monster->test4(),
+ monster->test5(),
+ };
+ for (size_t i = 0; i < sizeof(tests_array) / sizeof(tests_array[0]); ++i) {
+ auto tests = tests_array[i];
+ TEST_NOTNULL(tests);
+ auto test_0 = tests->Get(0);
+ auto test_1 = tests->Get(1);
+ TEST_EQ(test_0->a(), 10);
+ TEST_EQ(test_0->b(), 20);
+ TEST_EQ(test_1->a(), 30);
+ TEST_EQ(test_1->b(), 40);
+ for (auto it = tests->begin(); it != tests->end(); ++it) {
+ TEST_EQ(it->a() == 10 || it->a() == 30, true); // Just testing iterators.
+ }
+ }
+
+ // Checking for presence of fields:
+ TEST_EQ(flatbuffers::IsFieldPresent(monster, Monster::VT_HP), true);
+ TEST_EQ(flatbuffers::IsFieldPresent(monster, Monster::VT_MANA), false);
+
+ // Obtaining a buffer from a root:
+ TEST_EQ(GetBufferStartFromRootPointer(monster), flatbuf);
+}
+
+// Change a FlatBuffer in-place, after it has been constructed.
+void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
+ // Get non-const pointer to root.
+ auto monster = GetMutableMonster(flatbuf);
+
+ // Each of these tests mutates, then tests, then set back to the original,
+ // so we can test that the buffer in the end still passes our original test.
+ auto hp_ok = monster->mutate_hp(10);
+ TEST_EQ(hp_ok, true); // Field was present.
+ TEST_EQ(monster->hp(), 10);
+ // Mutate to default value
+ auto hp_ok_default = monster->mutate_hp(100);
+ TEST_EQ(hp_ok_default, true); // Field was present.
+ TEST_EQ(monster->hp(), 100);
+ // Test that mutate to default above keeps field valid for further mutations
+ auto hp_ok_2 = monster->mutate_hp(20);
+ TEST_EQ(hp_ok_2, true);
+ TEST_EQ(monster->hp(), 20);
+ monster->mutate_hp(80);
+
+ // Monster originally at 150 mana (default value)
+ auto mana_default_ok = monster->mutate_mana(150); // Mutate to default value.
+ TEST_EQ(mana_default_ok,
+ true); // Mutation should succeed, because default value.
+ TEST_EQ(monster->mana(), 150);
+ auto mana_ok = monster->mutate_mana(10);
+ TEST_EQ(mana_ok, false); // Field was NOT present, because default value.
+ TEST_EQ(monster->mana(), 150);
+
+ // Mutate structs.
+ auto pos = monster->mutable_pos();
+ auto test3 = pos->mutable_test3(); // Struct inside a struct.
+ test3.mutate_a(50); // Struct fields never fail.
+ TEST_EQ(test3.a(), 50);
+ test3.mutate_a(10);
+
+ // Mutate vectors.
+ auto inventory = monster->mutable_inventory();
+ inventory->Mutate(9, 100);
+ TEST_EQ(inventory->Get(9), 100);
+ inventory->Mutate(9, 9);
+
+ auto tables = monster->mutable_testarrayoftables();
+ auto first = tables->GetMutableObject(0);
+ TEST_EQ(first->hp(), 1000);
+ first->mutate_hp(0);
+ TEST_EQ(first->hp(), 0);
+ first->mutate_hp(1000);
+
+ // Mutate via LookupByKey
+ TEST_NOTNULL(tables->MutableLookupByKey("Barney"));
+ TEST_EQ(static_cast<Monster *>(nullptr),
+ tables->MutableLookupByKey("DoesntExist"));
+ TEST_EQ(tables->MutableLookupByKey("Barney")->hp(), 1000);
+ TEST_EQ(tables->MutableLookupByKey("Barney")->mutate_hp(0), true);
+ TEST_EQ(tables->LookupByKey("Barney")->hp(), 0);
+ TEST_EQ(tables->MutableLookupByKey("Barney")->mutate_hp(1000), true);
+
+ // Run the verifier and the regular test to make sure we didn't trample on
+ // anything.
+ AccessFlatBufferTest(flatbuf, length);
+}
+
+// Unpack a FlatBuffer into objects.
+void ObjectFlatBuffersTest(uint8_t *flatbuf) {
+ // Optional: we can specify resolver and rehasher functions to turn hashed
+ // strings into object pointers and back, to implement remote references
+ // and such.
+ auto resolver = flatbuffers::resolver_function_t(
+ [](void **pointer_adr, flatbuffers::hash_value_t hash) {
+ (void)pointer_adr;
+ (void)hash;
+ // Don't actually do anything, leave variable null.
+ });
+ auto rehasher = flatbuffers::rehasher_function_t(
+ [](void *pointer) -> flatbuffers::hash_value_t {
+ (void)pointer;
+ return 0;
+ });
+
+ // Turn a buffer into C++ objects.
+ auto monster1 = UnPackMonster(flatbuf, &resolver);
+
+ // Re-serialize the data.
+ flatbuffers::FlatBufferBuilder fbb1;
+ fbb1.Finish(CreateMonster(fbb1, monster1.get(), &rehasher),
+ MonsterIdentifier());
+
+ // Unpack again, and re-serialize again.
+ auto monster2 = UnPackMonster(fbb1.GetBufferPointer(), &resolver);
+ flatbuffers::FlatBufferBuilder fbb2;
+ fbb2.Finish(CreateMonster(fbb2, monster2.get(), &rehasher),
+ MonsterIdentifier());
+
+ // Now we've gone full round-trip, the two buffers should match.
+ const auto len1 = fbb1.GetSize();
+ const auto len2 = fbb2.GetSize();
+ TEST_EQ(len1, len2);
+ TEST_EQ(memcmp(fbb1.GetBufferPointer(), fbb2.GetBufferPointer(), len1), 0);
+
+ // Test it with the original buffer test to make sure all data survived.
+ AccessFlatBufferTest(fbb2.GetBufferPointer(), len2, false);
+
+ // Test accessing fields, similar to AccessFlatBufferTest above.
+ CheckMonsterObject(monster2.get());
+
+ // Test object copy.
+ auto monster3 = *monster2;
+ flatbuffers::FlatBufferBuilder fbb3;
+ fbb3.Finish(CreateMonster(fbb3, &monster3, &rehasher), MonsterIdentifier());
+ const auto len3 = fbb3.GetSize();
+ TEST_EQ(len2, len3);
+ TEST_EQ(memcmp(fbb2.GetBufferPointer(), fbb3.GetBufferPointer(), len2), 0);
+ // Delete monster1 and monster2, then test accessing fields in monster3.
+ monster1.reset();
+ monster2.reset();
+ CheckMonsterObject(&monster3);
+}
+
+// Utility function to check a Monster object.
+void CheckMonsterObject(MonsterT *monster2) {
+ TEST_EQ(monster2->hp, 80);
+ TEST_EQ(monster2->mana, 150); // default
+ TEST_EQ_STR(monster2->name.c_str(), "MyMonster");
+
+ auto &pos = monster2->pos;
+ TEST_NOTNULL(pos);
+ TEST_EQ(pos->z(), 3);
+ TEST_EQ(pos->test3().a(), 10);
+ TEST_EQ(pos->test3().b(), 20);
+
+ auto &inventory = monster2->inventory;
+ TEST_EQ(inventory.size(), 10UL);
+ unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ for (auto it = inventory.begin(); it != inventory.end(); ++it)
+ TEST_EQ(*it, inv_data[it - inventory.begin()]);
+
+ TEST_EQ(monster2->color, Color_Blue);
+
+ auto monster3 = monster2->test.AsMonster();
+ TEST_NOTNULL(monster3);
+ TEST_EQ_STR(monster3->name.c_str(), "Fred");
+
+ auto &vecofstrings = monster2->testarrayofstring;
+ TEST_EQ(vecofstrings.size(), 4U);
+ TEST_EQ_STR(vecofstrings[0].c_str(), "bob");
+ TEST_EQ_STR(vecofstrings[1].c_str(), "fred");
+
+ auto &vecofstrings2 = monster2->testarrayofstring2;
+ TEST_EQ(vecofstrings2.size(), 2U);
+ TEST_EQ_STR(vecofstrings2[0].c_str(), "jane");
+ TEST_EQ_STR(vecofstrings2[1].c_str(), "mary");
+
+ auto &vecoftables = monster2->testarrayoftables;
+ TEST_EQ(vecoftables.size(), 3U);
+ TEST_EQ_STR(vecoftables[0]->name.c_str(), "Barney");
+ TEST_EQ(vecoftables[0]->hp, 1000);
+ TEST_EQ_STR(vecoftables[1]->name.c_str(), "Fred");
+ TEST_EQ_STR(vecoftables[2]->name.c_str(), "Wilma");
+
+ auto &tests = monster2->test4;
+ TEST_EQ(tests[0].a(), 10);
+ TEST_EQ(tests[0].b(), 20);
+ TEST_EQ(tests[1].a(), 30);
+ TEST_EQ(tests[1].b(), 40);
+}
+
+// Prefix a FlatBuffer with a size field.
+void SizePrefixedTest() {
+ // Create size prefixed buffer.
+ flatbuffers::FlatBufferBuilder fbb;
+ FinishSizePrefixedMonsterBuffer(
+ fbb, CreateMonster(fbb, nullptr, 200, 300, fbb.CreateString("bob")));
+
+ // Verify it.
+ flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
+ TEST_EQ(VerifySizePrefixedMonsterBuffer(verifier), true);
+
+ // Access it.
+ auto m = GetSizePrefixedMonster(fbb.GetBufferPointer());
+ TEST_EQ(m->mana(), 200);
+ TEST_EQ(m->hp(), 300);
+ TEST_EQ_STR(m->name()->c_str(), "bob");
+}
+
+void TestMonsterExtraFloats(const std::string &tests_data_path) {
+#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
+ TEST_EQ(is_quiet_nan(1.0), false);
+ TEST_EQ(is_quiet_nan(infinity_d), false);
+ TEST_EQ(is_quiet_nan(-infinity_f), 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((tests_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(tests_data_path, "include_test");
+ const char *include_directories[] = { tests_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(), +infinity_f);
+ TEST_EQ(def_extra->f3(), -infinity_f);
+ TEST_EQ(is_quiet_nan(def_extra->d0()), true);
+ TEST_EQ(is_quiet_nan(def_extra->d1()), true);
+ TEST_EQ(def_extra->d2(), +infinity_d);
+ TEST_EQ(def_extra->d3(), -infinity_d);
+ 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 = tests_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(), +infinity_f);
+ TEST_EQ(extra->f3(), -infinity_f);
+ TEST_EQ(is_quiet_nan(extra->d0()), true);
+ TEST_EQ(extra->d1(), +infinity_d);
+ TEST_EQ(extra->d2(), -infinity_d);
+ 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), -infinity_f);
+ TEST_EQ(extra->fvec()->Get(2), +infinity_f);
+ 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), +infinity_d);
+ TEST_EQ(extra->dvec()->Get(2), -infinity_d);
+ TEST_EQ(is_quiet_nan(extra->dvec()->Get(3)), true);
+#endif
+}
+
+void EnumNamesTest() {
+ TEST_EQ_STR("Red", EnumNameColor(Color_Red));
+ TEST_EQ_STR("Green", EnumNameColor(Color_Green));
+ TEST_EQ_STR("Blue", EnumNameColor(Color_Blue));
+ // Check that Color to string don't crash while decode a mixture of Colors.
+ // 1) Example::Color enum is enum with unfixed underlying type.
+ // 2) Valid enum range: [0; 2^(ceil(log2(Color_ANY))) - 1].
+ // Consequence: A value is out of this range will lead to UB (since C++17).
+ // 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)));
+}
+
+void TypeAliasesTest() {
+ flatbuffers::FlatBufferBuilder builder;
+
+ builder.Finish(CreateTypeAliases(
+ builder, flatbuffers::numeric_limits<int8_t>::min(),
+ flatbuffers::numeric_limits<uint8_t>::max(),
+ flatbuffers::numeric_limits<int16_t>::min(),
+ flatbuffers::numeric_limits<uint16_t>::max(),
+ flatbuffers::numeric_limits<int32_t>::min(),
+ flatbuffers::numeric_limits<uint32_t>::max(),
+ flatbuffers::numeric_limits<int64_t>::min(),
+ flatbuffers::numeric_limits<uint64_t>::max(), 2.3f, 2.3));
+
+ auto p = builder.GetBufferPointer();
+ auto ta = flatbuffers::GetRoot<TypeAliases>(p);
+
+ TEST_EQ(ta->i8(), flatbuffers::numeric_limits<int8_t>::min());
+ TEST_EQ(ta->u8(), flatbuffers::numeric_limits<uint8_t>::max());
+ TEST_EQ(ta->i16(), flatbuffers::numeric_limits<int16_t>::min());
+ TEST_EQ(ta->u16(), flatbuffers::numeric_limits<uint16_t>::max());
+ TEST_EQ(ta->i32(), flatbuffers::numeric_limits<int32_t>::min());
+ TEST_EQ(ta->u32(), flatbuffers::numeric_limits<uint32_t>::max());
+ TEST_EQ(ta->i64(), flatbuffers::numeric_limits<int64_t>::min());
+ 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
+ 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");
+ static_assert(is_same<decltype(ta->i64()), int64_t>::value, "invalid type");
+ static_assert(is_same<decltype(ta->u8()), uint8_t>::value, "invalid type");
+ static_assert(is_same<decltype(ta->u16()), uint16_t>::value, "invalid type");
+ static_assert(is_same<decltype(ta->u32()), uint32_t>::value, "invalid type");
+ static_assert(is_same<decltype(ta->u64()), uint64_t>::value, "invalid type");
+ static_assert(is_same<decltype(ta->f32()), float>::value, "invalid type");
+ static_assert(is_same<decltype(ta->f64()), double>::value, "invalid type");
+}
+
+// example of parsing text straight into a buffer, and generating
+// text back from it:
+void ParseAndGenerateTextTest(const std::string &tests_data_path, bool binary) {
+ // load FlatBuffer schema (.fbs) and JSON from disk
+ std::string schemafile;
+ std::string jsonfile;
+ TEST_EQ(flatbuffers::LoadFile(
+ (tests_data_path + "monster_test." + (binary ? "bfbs" : "fbs"))
+ .c_str(),
+ binary, &schemafile),
+ true);
+ TEST_EQ(flatbuffers::LoadFile(
+ (tests_data_path + "monsterdata_test.golden").c_str(), false,
+ &jsonfile),
+ true);
+
+ auto include_test_path =
+ flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
+ const char *include_directories[] = { tests_data_path.c_str(),
+ include_test_path.c_str(), nullptr };
+
+ // parse schema first, so we can use it to parse the data after
+ flatbuffers::Parser parser;
+ if (binary) {
+ flatbuffers::Verifier verifier(
+ 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(
+ reinterpret_cast<const uint8_t *>(schemafile.c_str()),
+ schemafile.size()),
+ true);
+ } else {
+ TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
+ }
+ TEST_EQ(parser.ParseJson(jsonfile.c_str()), true);
+
+ // here, parser.builder_ contains a binary buffer that is the parsed data.
+
+ // First, verify it, just in case:
+ flatbuffers::Verifier verifier(parser.builder_.GetBufferPointer(),
+ parser.builder_.GetSize());
+ TEST_EQ(VerifyMonsterBuffer(verifier), true);
+
+ AccessFlatBufferTest(parser.builder_.GetBufferPointer(),
+ parser.builder_.GetSize(), false);
+
+ // to ensure it is correct, we now generate text back from the binary,
+ // and compare the two:
+ std::string jsongen;
+ auto result =
+ GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
+ TEST_EQ(result, true);
+ TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
+
+ // We can also do the above using the convenient Registry that knows about
+ // a set of file_identifiers mapped to schemas.
+ flatbuffers::Registry registry;
+ // Make sure schemas can find their includes.
+ registry.AddIncludeDirectory(tests_data_path.c_str());
+ registry.AddIncludeDirectory(include_test_path.c_str());
+ // Call this with many schemas if possible.
+ registry.Register(MonsterIdentifier(),
+ (tests_data_path + "monster_test.fbs").c_str());
+ // Now we got this set up, we can parse by just specifying the identifier,
+ // the correct schema will be loaded on the fly:
+ auto buf = registry.TextToFlatBuffer(jsonfile.c_str(), MonsterIdentifier());
+ // If this fails, check registry.lasterror_.
+ TEST_NOTNULL(buf.data());
+ // Test the buffer, to be sure:
+ AccessFlatBufferTest(buf.data(), buf.size(), false);
+ // We can use the registry to turn this back into text, in this case it
+ // will get the file_identifier from the binary:
+ std::string text;
+ auto ok = registry.FlatBufferToText(buf.data(), buf.size(), &text);
+ // If this fails, check registry.lasterror_.
+ TEST_EQ(ok, true);
+ TEST_EQ_STR(text.c_str(), jsonfile.c_str());
+
+ // Generate text for UTF-8 strings without escapes.
+ std::string jsonfile_utf8;
+ TEST_EQ(flatbuffers::LoadFile((tests_data_path + "unicode_test.json").c_str(),
+ false, &jsonfile_utf8),
+ true);
+ TEST_EQ(parser.Parse(jsonfile_utf8.c_str(), include_directories), true);
+ // To ensure it is correct, generate utf-8 text back from the binary.
+ std::string jsongen_utf8;
+ // request natural printing for utf-8 strings
+ parser.opts.natural_utf8 = true;
+ parser.opts.strict_json = true;
+ TEST_EQ(
+ GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen_utf8),
+ true);
+ TEST_EQ_STR(jsongen_utf8.c_str(), jsonfile_utf8.c_str());
+}
+
+void UnPackTo(const uint8_t *flatbuf) {
+ // Get a monster that has a name and no enemy
+ auto orig_monster = GetMonster(flatbuf);
+ TEST_EQ_STR(orig_monster->name()->c_str(), "MyMonster");
+ TEST_ASSERT(orig_monster->enemy() == nullptr);
+
+ // Create an enemy
+ MonsterT *enemy = new MonsterT();
+ enemy->name = "Enemy";
+
+ // And create another monster owning the enemy,
+ MonsterT mon;
+ mon.name = "I'm monster 1";
+ mon.enemy.reset(enemy);
+ TEST_ASSERT(mon.enemy != nullptr);
+
+ // Assert that all the Monster objects are correct.
+ TEST_EQ_STR(mon.name.c_str(), "I'm monster 1");
+ TEST_EQ_STR(enemy->name.c_str(), "Enemy");
+ TEST_EQ_STR(mon.enemy->name.c_str(), "Enemy");
+
+ // Now unpack monster ("MyMonster") into monster
+ orig_monster->UnPackTo(&mon);
+
+ // Monster name should be from monster
+ TEST_EQ_STR(mon.name.c_str(), "MyMonster");
+
+ // The monster shouldn't have any enemies, because monster didn't.
+ TEST_ASSERT(mon.enemy == nullptr);
+}
+
+} // namespace tests
+} // namespace flatbuffers
\ No newline at end of file