SIGN IN SIGN UP
google / flatbuffers UNCLAIMED

FlatBuffers: Memory Efficient Serialization Library

/*
* 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.
*/
#include <stdint.h>
#include <cmath>
#include <limits>
#include <memory>
#include <string>
2023-05-31 19:31:47 +00:00
#if defined(__ANDROID__)
2023-05-31 11:52:05 -07:00
#define INCLUDE_64_BIT_TESTS 0
#else
#define INCLUDE_64_BIT_TESTS 1
#endif
#if __has_include("third_party/absl/container/flat_hash_set.h")
#define HAS_ABSL_CONTAINERS 1
#endif
#ifdef HAS_ABSL_CONTAINERS
#include "third_party/absl/container/flat_hash_set.h"
#endif
#include "alignment_test.h"
#include "cross_namespace_pack_test_generated.h"
2025-12-19 14:32:51 -08:00
#include "default_vectors_strings_test.h"
#include "evolution_test.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/minireflect.h"
#include "flatbuffers/reflection_generated.h"
#include "flatbuffers/registry.h"
#include "flatbuffers/util.h"
#include "fuzz_test.h"
#include "json_test.h"
#include "key_field_test.h"
#include "monster_test.h"
#include "monster_test_generated.h"
#include "native_inline_table_test_generated.h"
#include "optional_scalars_test.h"
#include "parser_test.h"
#include "proto_test.h"
#include "reflection_test.h"
2023-05-31 11:52:05 -07:00
#include "tests/union_vector/union_vector_generated.h"
#include "union_underlying_type_test_generated.h"
#if !defined(_MSC_VER) || _MSC_VER >= 1700
#include "tests/arrays_test_generated.h"
2023-05-31 11:52:05 -07:00
#endif
#if INCLUDE_64_BIT_TESTS
#include "tests/64bit/offset64_test.h"
#endif
#include "flexbuffers_test.h"
#include "is_quiet_nan.h"
#include "monster_test_bfbs_generated.h" // Generated using --bfbs-comments --bfbs-builtins --cpp --bfbs-gen-embed
#include "native_type_test_generated.h"
#include "test_assert.h"
#include "util_test.h"
#include "vector_table_naked_ptr_test.h"
void FlatBufferBuilderTest();
namespace flatbuffers {
namespace tests {
namespace {
2021-11-19 17:01:48 -08:00
// 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
using namespace MyGame::Example;
void TriviallyCopyableTest() {
FlatBuffers 64 for C++ (#7935) * First working hack of adding 64-bit. Don't judge :) * Made vector_downward work on 64 bit types * vector_downward uses size_t, added offset64 to reflection * cleaned up adding offset64 in parser * Add C++ testing skeleton for 64-bit * working test for CreateVector64 * working >2 GiB buffers * support for large strings * simplified CreateString<> to just provide the offset type * generalize CreateVector template * update test_64.afb due to upstream format change * Added Vector64 type, which is just an alias for vector ATM * Switch to Offset64 for Vector64 * Update for reflection bfbs output change * Starting to add support for vector64 type in C++ * made a generic CreateVector that can handle different offsets and vector types * Support for 32-vector with 64-addressing * Vector64 basic builder + tests working * basic support for json vector64 support * renamed fields in test_64bit.fbs to better reflect their use * working C++ vector64 builder * Apply --annotate-sparse-vector to 64-bit tests * Enable Vector64 for --annotate-sparse-vectors * Merged from upstream * Add `near_string` field for testing 32-bit offsets alongside * keep track of where the 32-bit and 64-bit regions are for flatbufferbuilder * move template<> outside class body for GCC * update run.sh to build and run tests * basic assertion for adding 64-bit offset at the wrong time * started to separate `FlatBufferBuilder` into two classes, 1 64-bit aware, the other not * add test for nested flatbuffer vector64, fix bug in alignment of big vectors * fixed CreateDirect method by iterating by Offset64 first * internal refactoring of flatbufferbuilder * block not supported languages in the parser from using 64-bit * evolution tests for adding a vector64 field * conformity tests for adding/removing offset64 attributes * ensure test is for a big buffer * add parser error tests for `offset64` and `vector64` attributes * add missing static that GCC only complains about * remove stdint-uintn.h header that gets automatically added * move 64-bit CalculateOffset internal * fixed return size of EndVector * various fixes on windows * add SizeT to vector_downward * minimze range of size changes in vector and builder * reworked how tracking if 64-offsets are added * Add ReturnT to EndVector * small cleanups * remove need for second Array definition * combine IndirectHelpers into one definition * started support for vector of struct * Support for 32/64-vectors of structs + Offset64 * small cleanups * add verification for vector64 * add sized prefix for 64-bit buffers * add fuzzer for 64-bit * add example of adding many vectors using a wrapper table * run the new -bfbs-gen-embed logic on the 64-bit tests * remove run.sh and fix cmakelist issue * fixed bazel rules * fixed some PR comments * add 64-bit tests to cmakelist
2023-05-09 09:16:30 -07:00
// clang-format off
#if __GNUG__ && __GNUC__ < 5 && \
!(defined(__clang__) && __clang_major__ >= 16)
TEST_EQ(__is_trivially_copyable(Vec3), true);
#else
#if __cplusplus >= 201103L
TEST_EQ(std::is_trivially_copyable<Vec3>::value, true);
#endif
#endif
// clang-format on
}
// Guard against -Wunused-function on platforms without file tests.
#ifndef FLATBUFFERS_NO_FILE_TESTS
void GenerateTableTextTest(const std::string& tests_data_path) {
std::string schemafile;
std::string jsonfile;
bool ok =
flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
false, &schemafile) &&
flatbuffers::LoadFile((tests_data_path + "monsterdata_test.json").c_str(),
false, &jsonfile);
TEST_EQ(ok, 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};
flatbuffers::IDLOptions opt;
opt.indent_step = -1;
flatbuffers::Parser parser(opt);
ok = parser.Parse(schemafile.c_str(), include_directories) &&
parser.Parse(jsonfile.c_str(), include_directories);
TEST_EQ(ok, true);
// Test root table
const Monster* monster = GetMonster(parser.builder_.GetBufferPointer());
const auto abilities = monster->testarrayofsortedstruct();
TEST_EQ(abilities->size(), 3);
TEST_EQ(abilities->Get(0)->id(), 0);
TEST_EQ(abilities->Get(0)->distance(), 45);
TEST_EQ(abilities->Get(1)->id(), 1);
TEST_EQ(abilities->Get(1)->distance(), 21);
TEST_EQ(abilities->Get(2)->id(), 5);
TEST_EQ(abilities->Get(2)->distance(), 12);
std::string jsongen;
auto result =
GenTextFromTable(parser, monster, "MyGame.Example.Monster", &jsongen);
TEST_NULL(result);
// Test sub table
const Vec3* pos = monster->pos();
jsongen.clear();
result = GenTextFromTable(parser, pos, "MyGame.Example.Vec3", &jsongen);
TEST_NULL(result);
TEST_EQ_STR(
jsongen.c_str(),
"{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}");
const Test& test3 = pos->test3();
jsongen.clear();
result = GenTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
TEST_NULL(result);
TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}");
const Test* test4 = monster->test4()->Get(0);
jsongen.clear();
result = GenTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
TEST_NULL(result);
TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}");
}
void MultiFileNameClashTest(const std::string& tests_data_path) {
const auto name_clash_path =
flatbuffers::ConCatPathFileName(tests_data_path, "name_clash_test");
const char* include_directories[] = {name_clash_path.c_str()};
// Load valid 2 file Flatbuffer schema
const auto valid_path =
flatbuffers::ConCatPathFileName(name_clash_path, "valid_test1.fbs");
std::string valid_schema;
TEST_ASSERT(flatbuffers::LoadFile(valid_path.c_str(), false, &valid_schema));
// Clashing table and union names in different namespaces must be parsable
TEST_ASSERT(
flatbuffers::Parser().Parse(valid_schema.c_str(), include_directories));
flatbuffers::Parser p;
TEST_ASSERT(p.Parse(valid_schema.c_str(), include_directories));
// Load invalid 2 file Flatbuffer schema
const auto invalid_path =
flatbuffers::ConCatPathFileName(name_clash_path, "invalid_test1.fbs");
std::string invalid_schema;
TEST_ASSERT(
flatbuffers::LoadFile(invalid_path.c_str(), false, &invalid_schema));
// Clashing table and union names in same namespace must fail to parse
TEST_EQ(
flatbuffers::Parser().Parse(invalid_schema.c_str(), include_directories),
false);
}
void InvalidNestedFlatbufferTest(const std::string& tests_data_path) {
// First, load and parse FlatBuffer schema (.fbs)
std::string schemafile;
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
false, &schemafile),
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};
flatbuffers::Parser parser1;
TEST_EQ(parser1.Parse(schemafile.c_str(), include_directories), true);
// "color" inside nested flatbuffer contains invalid enum value
TEST_EQ(parser1.Parse("{ name: \"Bender\", testnestedflatbuffer: { name: "
"\"Leela\", color: \"nonexistent\"}}"),
false);
}
void UnionVectorTest(const std::string& tests_data_path) {
// load FlatBuffer fbs schema and json.
std::string schemafile, jsonfile;
TEST_EQ(flatbuffers::LoadFile(
(tests_data_path + "union_vector/union_vector.fbs").c_str(),
false, &schemafile),
true);
2017-01-24 11:52:36 -08:00
TEST_EQ(flatbuffers::LoadFile(
(tests_data_path + "union_vector/union_vector.json").c_str(),
false, &jsonfile),
true);
2017-01-24 11:52:36 -08:00
// parse schema.
flatbuffers::IDLOptions idl_opts;
idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
2017-01-24 11:52:36 -08:00
flatbuffers::Parser parser(idl_opts);
TEST_EQ(parser.Parse(schemafile.c_str()), true);
2017-01-24 11:52:36 -08:00
flatbuffers::FlatBufferBuilder fbb;
// union types.
std::vector<uint8_t> types;
types.push_back(static_cast<uint8_t>(Character_Belle));
types.push_back(static_cast<uint8_t>(Character_MuLan));
types.push_back(static_cast<uint8_t>(Character_BookFan));
types.push_back(static_cast<uint8_t>(Character_Other));
types.push_back(static_cast<uint8_t>(Character_Unused));
2017-01-24 11:52:36 -08:00
// union values.
std::vector<flatbuffers::Offset<void>> characters;
characters.push_back(fbb.CreateStruct(BookReader(/*books_read=*/7)).Union());
characters.push_back(CreateAttacker(fbb, /*sword_attack_damage=*/5).Union());
characters.push_back(fbb.CreateStruct(BookReader(/*books_read=*/2)).Union());
characters.push_back(fbb.CreateString("Other").Union());
characters.push_back(fbb.CreateString("Unused").Union());
2017-01-24 11:52:36 -08:00
// create Movie.
const auto movie_offset =
CreateMovie(fbb, Character_Rapunzel,
fbb.CreateStruct(Rapunzel(/*hair_length=*/6)).Union(),
fbb.CreateVector(types), fbb.CreateVector(characters));
2017-01-24 11:52:36 -08:00
FinishMovieBuffer(fbb, movie_offset);
flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
2017-01-24 11:52:36 -08:00
TEST_EQ(VerifyMovieBuffer(verifier), true);
auto flat_movie = GetMovie(fbb.GetBufferPointer());
auto TestMovie = [](const Movie* movie) {
TEST_EQ(movie->main_character_type() == Character_Rapunzel, true);
auto cts = movie->characters_type();
TEST_EQ(movie->characters_type()->size(), 5);
TEST_EQ(cts->GetEnum<Character>(0) == Character_Belle, true);
TEST_EQ(cts->GetEnum<Character>(1) == Character_MuLan, true);
TEST_EQ(cts->GetEnum<Character>(2) == Character_BookFan, true);
TEST_EQ(cts->GetEnum<Character>(3) == Character_Other, true);
TEST_EQ(cts->GetEnum<Character>(4) == Character_Unused, true);
auto rapunzel = movie->main_character_as_Rapunzel();
TEST_NOTNULL(rapunzel);
TEST_EQ(rapunzel->hair_length(), 6);
auto cs = movie->characters();
TEST_EQ(cs->size(), 5);
auto belle = cs->GetAs<BookReader>(0);
TEST_EQ(belle->books_read(), 7);
auto mu_lan = cs->GetAs<Attacker>(1);
TEST_EQ(mu_lan->sword_attack_damage(), 5);
auto book_fan = cs->GetAs<BookReader>(2);
TEST_EQ(book_fan->books_read(), 2);
auto other = cs->GetAsString(3);
TEST_EQ_STR(other->c_str(), "Other");
auto unused = cs->GetAsString(4);
TEST_EQ_STR(unused->c_str(), "Unused");
};
TestMovie(flat_movie);
// Also test the JSON we loaded above.
TEST_EQ(parser.Parse(jsonfile.c_str()), true);
auto jbuf = parser.builder_.GetBufferPointer();
flatbuffers::Verifier jverifier(jbuf, parser.builder_.GetSize());
TEST_EQ(VerifyMovieBuffer(jverifier), true);
TestMovie(GetMovie(jbuf));
auto movie_object = flat_movie->UnPack();
TEST_EQ(movie_object->main_character.AsRapunzel()->hair_length(), 6);
TEST_EQ(movie_object->characters[0].AsBelle()->books_read(), 7);
TEST_EQ(movie_object->characters[1].AsMuLan()->sword_attack_damage, 5);
TEST_EQ(movie_object->characters[2].AsBookFan()->books_read(), 2);
TEST_EQ_STR(movie_object->characters[3].AsOther()->c_str(), "Other");
TEST_EQ_STR(movie_object->characters[4].AsUnused()->c_str(), "Unused");
fbb.Clear();
fbb.Finish(Movie::Pack(fbb, movie_object));
2017-08-11 12:24:33 -07:00
delete movie_object;
auto repacked_movie = GetMovie(fbb.GetBufferPointer());
TestMovie(repacked_movie);
// Generate text using mini-reflection.
auto s =
flatbuffers::FlatBufferToString(fbb.GetBufferPointer(), MovieTypeTable());
TEST_EQ_STR(
s.c_str(),
"{ main_character_type: Rapunzel, main_character: { hair_length: 6 }, "
"characters_type: [ Belle, MuLan, BookFan, Other, Unused ], "
"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"
"}");
// Generate text using parsed schema.
std::string jsongen;
auto result = GenText(parser, fbb.GetBufferPointer(), &jsongen);
TEST_NULL(result);
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);
TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true);
2017-01-24 11:52:36 -08:00
}
#endif
2017-01-24 11:52:36 -08:00
void EndianSwapTest() {
TEST_EQ(flatbuffers::EndianSwap(static_cast<int16_t>(0x1234)), 0x3412);
TEST_EQ(flatbuffers::EndianSwap(static_cast<int32_t>(0x12345678)),
0x78563412);
TEST_EQ(flatbuffers::EndianSwap(static_cast<int64_t>(0x1234567890ABCDEF)),
0xEFCDAB9078563412);
TEST_EQ(flatbuffers::EndianSwap(flatbuffers::EndianSwap(3.14f)), 3.14f);
}
void UninitializedVectorTest() {
flatbuffers::FlatBufferBuilder builder;
Test* buf = nullptr;
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_test4(vector_offset);
builder.Finish(monster_builder.Finish());
auto p = builder.GetBufferPointer();
auto uvt = flatbuffers::GetRoot<Monster>(p);
TEST_NOTNULL(uvt);
auto vec = uvt->test4();
TEST_NOTNULL(vec);
auto test_0 = vec->Get(0);
auto test_1 = vec->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);
}
void EqualOperatorTest() {
MonsterT a;
MonsterT b;
// We have to reset the fields that are NaN to zero to allow the equality
// to evaluate to true.
TEST_EQ(std::isnan(a.nan_default), true);
TEST_EQ(std::isnan(b.nan_default), true);
a.nan_default = 0;
b.nan_default = 0;
TEST_EQ(b == a, true);
TEST_EQ(b != a, false);
b.mana = 33;
TEST_EQ(b == a, false);
TEST_EQ(b != a, true);
b.mana = 150;
TEST_EQ(b == a, true);
TEST_EQ(b != a, false);
b.inventory.push_back(3);
TEST_EQ(b == a, false);
TEST_EQ(b != a, true);
b.inventory.clear();
TEST_EQ(b == a, true);
TEST_EQ(b != a, false);
a.enemy.reset(new MonsterT());
a.enemy->nan_default = 0;
TEST_EQ(b != a, true);
a.enemy->mana = 33;
TEST_EQ(b == a, false);
TEST_EQ(b != a, true);
b.enemy.reset(new MonsterT());
b.enemy->nan_default = 0;
TEST_EQ(b == a, false);
TEST_EQ(b != a, true);
b.enemy->mana = 33;
TEST_EQ(b == a, true);
TEST_EQ(b != a, false);
a.enemy.reset(nullptr);
TEST_EQ(b == a, false);
TEST_EQ(b != a, true);
b.enemy->mana = 150;
TEST_EQ(b == a, false);
TEST_EQ(b != a, true);
a.enemy.reset(new MonsterT());
a.enemy->nan_default = 0;
TEST_EQ(b == a, true);
TEST_EQ(b != a, false);
b.enemy.reset(nullptr);
b.test.type = Any_Monster;
TEST_EQ(b == a, false);
TEST_EQ(b != a, true);
// Test that vector of tables are compared by value and not by reference.
{
// Two tables are equal by default.
MonsterT a, b;
a.nan_default = 0;
b.nan_default = 0;
TEST_EQ(a == b, true);
// Adding only a table to one of the monster vectors should make it not
// equal (due to size mistmatch).
a.testarrayoftables.push_back(
flatbuffers::unique_ptr<MonsterT>(new MonsterT));
a.testarrayoftables.back()->nan_default = 0;
TEST_EQ(a == b, false);
// Adding an equalivant table to the other monster vector should make it
// equal again.
b.testarrayoftables.push_back(
flatbuffers::unique_ptr<MonsterT>(new MonsterT));
b.testarrayoftables.back()->nan_default = 0;
TEST_EQ(a == b, true);
// Create two new monsters that are different.
auto c = flatbuffers::unique_ptr<MonsterT>(new MonsterT);
auto d = flatbuffers::unique_ptr<MonsterT>(new MonsterT);
c->nan_default = 0;
d->nan_default = 0;
c->hp = 1;
d->hp = 2;
TEST_EQ(c == d, false);
// Adding them to the original monsters should also make them different.
a.testarrayoftables.push_back(std::move(c));
b.testarrayoftables.push_back(std::move(d));
TEST_EQ(a == b, false);
// Remove the mismatching monsters to get back to equality
a.testarrayoftables.pop_back();
b.testarrayoftables.pop_back();
TEST_EQ(a == b, true);
// Check that nullptr are OK.
a.testarrayoftables.push_back(nullptr);
b.testarrayoftables.push_back(
flatbuffers::unique_ptr<MonsterT>(new MonsterT));
TEST_EQ(a == b, false);
}
}
void CreateSharedStringTest() {
flatbuffers::FlatBufferBuilder builder;
const auto one1 = builder.CreateSharedString("one");
const auto two = builder.CreateSharedString("two");
const auto one2 = builder.CreateSharedString("one");
TEST_EQ(one1.o, one2.o);
const auto onetwo = builder.CreateSharedString("onetwo");
TEST_EQ(onetwo.o != one1.o, true);
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 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_b2.o);
// Put the strings into an array for round trip verification.
std::array<flatbuffers::Offset<flatbuffers::String>, 7> array = {
one1, two, one2, onetwo, null_b1, null_c, null_b2};
const auto vector_offset =
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(array);
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());
TEST_EQ_STR(monster->name()->c_str(), "two");
const auto* testarrayofstring = monster->testarrayofstring();
TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7));
const auto& a = *testarrayofstring;
TEST_EQ_STR(a[0]->c_str(), "one");
TEST_EQ_STR(a[1]->c_str(), "two");
TEST_EQ_STR(a[2]->c_str(), "one");
TEST_EQ_STR(a[3]->c_str(), "onetwo");
TEST_EQ(a[4]->str(), (std::string(chars_b, sizeof(chars_b))));
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.
TEST_EQ((*a[0]) < (*a[1]), true);
TEST_EQ((*a[1]) < (*a[0]), false);
TEST_EQ((*a[1]) < (*a[2]), false);
TEST_EQ((*a[2]) < (*a[1]), true);
TEST_EQ((*a[4]) < (*a[3]), true);
TEST_EQ((*a[5]) < (*a[4]), false);
TEST_EQ((*a[5]) < (*a[4]), false);
TEST_EQ((*a[6]) < (*a[5]), true);
}
#if !defined(FLATBUFFERS_USE_STD_SPAN) && !defined(FLATBUFFERS_SPAN_MINIMAL)
void FlatbuffersSpanTest() {
// Compile-time checking of non-const [] to const [] conversions.
2022-08-26 14:35:21 -07:00
using flatbuffers::internal::is_span_convertible;
(void)is_span_convertible<int, 1, int, 1>::type(123);
(void)is_span_convertible<const int, 1, int, 1>::type(123);
(void)is_span_convertible<const int64_t, 1, int64_t, 1>::type(123);
(void)is_span_convertible<const uint64_t, 1, uint64_t, 1>::type(123);
(void)is_span_convertible<const int, 1, const int, 1>::type(123);
(void)is_span_convertible<const int64_t, 1, const int64_t, 1>::type(123);
(void)is_span_convertible<const uint64_t, 1, const uint64_t, 1>::type(123);
using flatbuffers::span;
span<char, 0> c1;
TEST_EQ(c1.size(), 0);
span<char, flatbuffers::dynamic_extent> c2;
TEST_EQ(c2.size(), 0);
span<char> c3;
TEST_EQ(c3.size(), 0);
TEST_ASSERT(c1.empty() && c2.empty() && c3.empty());
int i_data7[7] = {0, 1, 2, 3, 4, 5, 6};
span<int, 7> i1(&i_data7[0], 7);
span<int> i2(i1); // make dynamic from static
TEST_EQ(i1.size(), 7);
TEST_EQ(i1.empty(), false);
TEST_EQ(i1.size(), i2.size());
TEST_EQ(i1.data(), i_data7);
TEST_EQ(i1[2], 2);
// Make const span from a non-const one.
span<const int, 7> i3(i1);
// Construct from a C-array.
span<int, 7> i4(i_data7);
span<const int, 7> i5(i_data7);
span<int> i6(i_data7);
span<const int> i7(i_data7);
TEST_EQ(i7.size(), 7);
// Check construction from a const array.
const int i_cdata5[5] = {4, 3, 2, 1, 0};
span<const int, 5> i8(i_cdata5);
span<const int> i9(i_cdata5);
TEST_EQ(i9.size(), 5);
// Construction from a (ptr, size) pair.
span<int, 7> i10(i_data7, 7);
span<int> i11(i_data7, 7);
TEST_EQ(i11.size(), 7);
span<const int, 5> i12(i_cdata5, 5);
span<const int> i13(i_cdata5, 5);
TEST_EQ(i13.size(), 5);
// Construction from std::array.
std::array<int, 6> i_arr6 = {{0, 1, 2, 3, 4, 5}};
span<int, 6> i14(i_arr6);
span<const int, 6> i15(i_arr6);
span<int> i16(i_arr6);
span<const int> i17(i_arr6);
TEST_EQ(i17.size(), 6);
const std::array<int, 8> i_carr8 = {{0, 1, 2, 3, 4, 5, 6, 7}};
span<const int, 8> i18(i_carr8);
span<const int> i19(i_carr8);
TEST_EQ(i18.size(), 8);
TEST_EQ(i19.size(), 8);
TEST_EQ(i19[7], 7);
// Check compatibility with flatbuffers::Array.
int fbs_int3_underlaying[3] = {0};
int fbs_int3_data[3] = {1, 2, 3};
auto& fbs_int3 = flatbuffers::CastToArray(fbs_int3_underlaying);
fbs_int3.CopyFromSpan(fbs_int3_data);
TEST_EQ(fbs_int3.Get(1), 2);
const int fbs_cint3_data[3] = {2, 3, 4};
fbs_int3.CopyFromSpan(fbs_cint3_data);
TEST_EQ(fbs_int3.Get(1), 3);
// Check with Array<Enum, N>
enum class Dummy : uint16_t { Zero = 0, One, Two };
Dummy fbs_dummy3_underlaying[3] = {};
Dummy fbs_dummy3_data[3] = {Dummy::One, Dummy::Two, Dummy::Two};
auto& fbs_dummy3 = flatbuffers::CastToArray(fbs_dummy3_underlaying);
fbs_dummy3.CopyFromSpan(fbs_dummy3_data);
TEST_EQ(fbs_dummy3.Get(1), Dummy::Two);
}
#else
void FlatbuffersSpanTest() {}
#endif
// VS10 does not support typed enums, exclude from tests
#if !defined(_MSC_VER) || _MSC_VER >= 1700
void FixedLengthArrayTest() {
// 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);
MyGame::Example::FinishArrayTableBuffer(fbb, aTable);
// Verify correctness of the ArrayTable.
flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
TEST_ASSERT(MyGame::Example::VerifyArrayTableBuffer(verifier));
// Do test.
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());
TEST_EQ(mArStruct->a(), 2);
TEST_EQ(mArStruct->b()->size(), 15);
mArStruct->mutable_b()->Mutate(14, -14);
TEST_EQ(mArStruct->b()->Get(14), -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);
// Check if default constructor set all memory zero
const size_t arr_size = sizeof(MyGame::Example::ArrayStruct);
char non_zero_memory[arr_size];
// set memory chunk of size ArrayStruct to 1's
std::memset(static_cast<void*>(non_zero_memory), 1, arr_size);
// after placement-new it should be all 0's
2025-12-19 10:42:57 -08:00
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \
defined(_DEBUG)
#undef new
#endif
MyGame::Example::ArrayStruct* ap =
2021-01-22 21:46:53 +03:00
new (non_zero_memory) MyGame::Example::ArrayStruct;
2025-12-19 10:42:57 -08:00
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \
defined(_DEBUG)
#define new DEBUG_NEW
#endif
(void)ap;
for (size_t i = 0; i < arr_size; ++i) {
TEST_EQ(non_zero_memory[i], 0);
}
}
#else
void FixedLengthArrayTest() {}
#endif // !defined(_MSC_VER) || _MSC_VER >= 1700
2021-01-22 21:46:53 +03:00
#if !defined(FLATBUFFERS_SPAN_MINIMAL) && \
(!defined(_MSC_VER) || _MSC_VER >= 1700)
void FixedLengthArrayConstructorTest() {
const int32_t nested_a[2] = {1, 2};
MyGame::Example::TestEnum nested_c[2] = {MyGame::Example::TestEnum::A,
MyGame::Example::TestEnum::B};
const int64_t int64_2[2] = {-2, -1};
std::array<MyGame::Example::NestedStruct, 2> init_d = {
{MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
nested_c, int64_2),
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::A,
nested_c,
std::array<int64_t, 2>{{12, 13}})}};
MyGame::Example::ArrayStruct arr_struct(
8.125,
std::array<int32_t, 0xF>{
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
-17, init_d, 10, int64_2);
TEST_EQ(arr_struct.a(), 8.125);
TEST_EQ(arr_struct.b()->Get(2), 3);
TEST_EQ(arr_struct.c(), -17);
TEST_NOTNULL(arr_struct.d());
const auto& arr_d_0 = *arr_struct.d()->Get(0);
TEST_EQ(arr_d_0.a()->Get(0), 1);
TEST_EQ(arr_d_0.a()->Get(1), 2);
TEST_EQ(arr_d_0.b(), MyGame::Example::TestEnum::B);
TEST_EQ(arr_d_0.c()->Get(0), MyGame::Example::TestEnum::A);
TEST_EQ(arr_d_0.c()->Get(1), MyGame::Example::TestEnum::B);
TEST_EQ(arr_d_0.d()->Get(0), -2);
TEST_EQ(arr_d_0.d()->Get(1), -1);
const auto& arr_d_1 = *arr_struct.d()->Get(1);
TEST_EQ(arr_d_1.a()->Get(0), 1);
TEST_EQ(arr_d_1.a()->Get(1), 2);
TEST_EQ(arr_d_1.b(), MyGame::Example::TestEnum::A);
TEST_EQ(arr_d_1.c()->Get(0), MyGame::Example::TestEnum::A);
TEST_EQ(arr_d_1.c()->Get(1), MyGame::Example::TestEnum::B);
TEST_EQ(arr_d_1.d()->Get(0), 12);
TEST_EQ(arr_d_1.d()->Get(1), 13);
TEST_EQ(arr_struct.e(), 10);
TEST_EQ(arr_struct.f()->Get(0), -2);
TEST_EQ(arr_struct.f()->Get(1), -1);
Fix dereference operator of VectorIterator to structures (#8425) For Vector or Array of structures the dereference operator of an iterator returns the pointer to the structure. However, IndirectHelper, which is used in the implementation of this operator, is instantiated in the way that the IndirectHelper::Read returns structure by value. This is because, Vector and Array instantiate IndirectHelper with const T*, but VectorIterator instantiates IndirectHelper with T. There are three IndirectHelper template definition: first for T, second for Offset<T> and the last one for const T*. Those have different IndirectHelper:Read implementations and (more importantly) return type. This is the reason of mismatch in VectorIterator::operator* between return type declaration and what was exactly returned. That is, for Array<T,...> where T is scalar the VectorIterator is instantiated as VectorIterator<T, T>, dereference operator returns T and its implementation uses IndirectHelper<T> which Read function returns T. When T is not scalar, then VectorIterator is instantiated as VectorIterator<T, const T *>, dereference operator returns const T * and its implementation uses IndirectHelper<T> which Read function returns T. The fix is done as follows: * implement type trait is_specialization_of_Offset and is_specialization_of_Offset64, * change partial specialization of IndirectHelper with const T * that it is instantiated by T and enabled only if T is not scalar and not specialization of Offset or Offset64, * remove type differentiation (due to scalar) from Array.. The above makes the IndirectHelper able to correctly instantiate itself basing only on T. Thus, the instantiation in VectorIterator correctly instantiate IndirectHelper::Read function, especially the return type.
2025-05-18 07:01:09 +02:00
// Test for each loop over NestedStruct entries
for (auto i : *arr_struct.d()) {
for (auto a : *i->a()) {
TEST_EQ(a, 1);
break; // one iteration is enough, just testing compilation
}
TEST_EQ(i->b(), MyGame::Example::TestEnum::B);
for (auto c : *i->c()) {
TEST_EQ(c, MyGame::Example::TestEnum::A);
break; // one iteration is enough, just testing compilation
}
for (auto d : *i->d()) {
TEST_EQ(d, -2);
break; // one iteration is enough, just testing compilation
}
break; // one iteration is enough, just testing compilation
}
}
#else
2021-01-22 21:46:53 +03:00
void FixedLengthArrayConstructorTest() {}
#endif
void FixedLengthArrayOperatorEqualTest() {
const int32_t nested_a[2] = {1, 2};
MyGame::Example::TestEnum nested_c[2] = {MyGame::Example::TestEnum::A,
MyGame::Example::TestEnum::B};
MyGame::Example::TestEnum nested_cc[2] = {MyGame::Example::TestEnum::A,
MyGame::Example::TestEnum::C};
const int64_t int64_2[2] = {-2, -1};
std::array<MyGame::Example::NestedStruct, 2> init_d = {
{MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
nested_c, int64_2),
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
nested_c,
std::array<int64_t, 2>{{-2, -1}})}};
auto different = MyGame::Example::NestedStruct(
nested_a, MyGame::Example::TestEnum::B, nested_cc,
std::array<int64_t, 2>{{-2, -1}});
TEST_ASSERT(init_d[0] == init_d[1]);
TEST_ASSERT(init_d[0] != different);
std::array<MyGame::Example::ArrayStruct, 3> arr_struct = {
MyGame::Example::ArrayStruct(
8.125,
std::array<int32_t, 0xF>{
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
-17, init_d, 10, int64_2),
MyGame::Example::ArrayStruct(
8.125,
std::array<int32_t, 0xF>{
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
-17, init_d, 10, int64_2),
MyGame::Example::ArrayStruct(
8.125,
std::array<int32_t, 0xF>{
{1000, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
-17, init_d, 10, int64_2)};
TEST_ASSERT(arr_struct[0] == arr_struct[1]);
TEST_ASSERT(arr_struct[1] != arr_struct[2]);
}
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
void NativeTypeTest() {
const int N = 3;
Geometry::ApplicationDataT src_data;
src_data.position = flatbuffers::unique_ptr<Native::Vector3D>(
new Native::Vector3D(1.0f, 2.0f, 3.0f));
src_data.position_inline = Native::Vector3D(4.0f, 5.0f, 6.0f);
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
src_data.vectors.reserve(N);
src_data.vectors_alt.reserve(N);
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
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));
src_data.vectors_alt.push_back(
Native::Vector3D(20 * i + 0.1f, 20 * i + 0.2f, 20 * i + 0.3f));
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
}
src_data.matrix = std::unique_ptr<Native::Matrix>(new Native::Matrix(1, 2));
src_data.matrix->values = {3, 4};
for (int i = 0; i < N; ++i) {
2025-12-19 10:42:57 -08:00
src_data.matrices.push_back(
std::unique_ptr<Native::Matrix>(new Native::Matrix(1, i)));
std::fill(src_data.matrices[i]->values.begin(),
src_data.matrices[i]->values.end(), i + 0.5f);
}
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data));
auto dstDataT = Geometry::UnPackApplicationData(fbb.GetBufferPointer());
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
TEST_EQ(dstDataT->position->x, 1.0f);
TEST_EQ(dstDataT->position->y, 2.0f);
TEST_EQ(dstDataT->position->z, 3.0f);
TEST_EQ(dstDataT->position_inline.x, 4.0f);
TEST_EQ(dstDataT->position_inline.y, 5.0f);
TEST_EQ(dstDataT->position_inline.z, 6.0f);
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
for (int i = 0; i < N; ++i) {
const Native::Vector3D& v = dstDataT->vectors[i];
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
TEST_EQ(v.x, 10 * i + 0.1f);
TEST_EQ(v.y, 10 * i + 0.2f);
TEST_EQ(v.z, 10 * i + 0.3f);
const Native::Vector3D& v2 = dstDataT->vectors_alt[i];
TEST_EQ(v2.x, 20 * i + 0.1f);
TEST_EQ(v2.y, 20 * i + 0.2f);
TEST_EQ(v2.z, 20 * i + 0.3f);
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
}
TEST_EQ(dstDataT->matrix->rows, 1);
TEST_EQ(dstDataT->matrix->columns, 2);
TEST_EQ(dstDataT->matrix->values[0], 3);
TEST_EQ(dstDataT->matrix->values[1], 4);
for (int i = 0; i < N; ++i) {
2025-12-19 10:42:57 -08:00
const Native::Matrix& m = *dstDataT->matrices[i];
TEST_EQ(m.rows, 1);
TEST_EQ(m.columns, i);
for (int j = 0; j < i; ++j) {
TEST_EQ(m.values[j], i + 0.5f);
}
}
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
}
// Guard against -Wunused-function on platforms without file tests.
#ifndef FLATBUFFERS_NO_FILE_TESTS
// VS10 does not support typed enums, exclude from tests
#if !defined(_MSC_VER) || _MSC_VER >= 1700
void FixedLengthArrayJsonTest(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 + "arrays_test." + (binary ? "bfbs" : "fbs"))
.c_str(),
binary, &schemafile),
true);
TEST_EQ(
flatbuffers::LoadFile((tests_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(
reinterpret_cast<const uint8_t*>(schemafile.c_str()),
schemafile.size()),
true);
TEST_EQ(parserGen.Deserialize(
reinterpret_cast<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_NULL(
GenText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen));
// 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);
}
void FixedLengthArraySpanTest(const std::string& tests_data_path) {
// load FlatBuffer schema (.fbs) and JSON from disk
std::string schemafile;
std::string jsonfile;
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "arrays_test.fbs").c_str(),
false, &schemafile),
true);
TEST_EQ(
flatbuffers::LoadFile((tests_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 parser;
TEST_EQ(parser.Parse(schemafile.c_str()), true);
TEST_EQ(parser.Parse(jsonfile.c_str()), true);
auto& fbb = parser.builder_;
auto verifier = flatbuffers::Verifier(fbb.GetBufferPointer(), fbb.GetSize());
TEST_EQ(true, VerifyArrayTableBuffer(verifier));
auto p = MyGame::Example::GetMutableArrayTable(fbb.GetBufferPointer());
TEST_NOTNULL(p);
auto table_struct = p->mutable_a();
TEST_NOTNULL(table_struct);
TEST_EQ(2, table_struct->d()->size());
TEST_NOTNULL(table_struct->d());
TEST_NOTNULL(table_struct->mutable_d());
// test array of structs
auto const_d = flatbuffers::make_span(*table_struct->d());
auto mutable_d = flatbuffers::make_span(*table_struct->mutable_d());
TEST_EQ(2, const_d.size());
TEST_EQ(2, mutable_d.size());
TEST_ASSERT(const_d[0] == mutable_d[0]);
TEST_ASSERT(const_d[1] == mutable_d[1]);
mutable_d[0] = const_d[0]; // mutate
// test scalars
auto& const_nested = const_d[0];
auto& mutable_nested = mutable_d[0];
static_assert(sizeof(MyGame::Example::TestEnum) == sizeof(uint8_t),
"TestEnum's underlaying type must by byte");
TEST_NOTNULL(const_nested.d());
TEST_NOTNULL(mutable_nested.d());
{
flatbuffers::span<const MyGame::Example::TestEnum, 2> const_d_c =
flatbuffers::make_span(*const_nested.c());
auto mutable_d_c = flatbuffers::make_span(*mutable_nested.mutable_c());
TEST_EQ(2, const_d_c.size());
TEST_EQ(2, mutable_d_c.size());
TEST_EQ(MyGame::Example::TestEnum::C, const_d_c[0]);
TEST_EQ(MyGame::Example::TestEnum::B, const_d_c[1]);
TEST_ASSERT(mutable_d_c.end() == std::copy(const_d_c.begin(),
const_d_c.end(),
mutable_d_c.begin()));
TEST_ASSERT(
std::equal(const_d_c.begin(), const_d_c.end(), mutable_d_c.begin()));
}
// test little endian array of int32
#if FLATBUFFERS_LITTLEENDIAN
{
flatbuffers::span<const int32_t, 2> const_d_a =
flatbuffers::make_span(*const_nested.a());
auto mutable_d_a = flatbuffers::make_span(*mutable_nested.mutable_a());
TEST_EQ(2, const_d_a.size());
TEST_EQ(2, mutable_d_a.size());
TEST_EQ(-1, const_d_a[0]);
TEST_EQ(2, const_d_a[1]);
TEST_ASSERT(mutable_d_a.end() == std::copy(const_d_a.begin(),
const_d_a.end(),
mutable_d_a.begin()));
TEST_ASSERT(
std::equal(const_d_a.begin(), const_d_a.end(), mutable_d_a.begin()));
}
#endif
}
#else
void FixedLengthArrayJsonTest(bool /*binary*/) {}
void FixedLengthArraySpanTest() {}
#endif
void TestEmbeddedBinarySchema(const std::string& tests_data_path) {
// load JSON from disk
std::string jsonfile;
TEST_EQ(flatbuffers::LoadFile(
(tests_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_NULL(
GenText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen));
// 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);
}
#endif
template <typename T>
void EmbeddedSchemaAccessByType() {
// Get the binary schema from the Type itself.
// Verify the schema is OK.
flatbuffers::Verifier verifierEmbeddedSchema(
T::TableType::BinarySchema::data(), T::TableType::BinarySchema::size());
TEST_EQ(reflection::VerifySchemaBuffer(verifierEmbeddedSchema), true);
// Reflect it.
auto schema = reflection::GetSchema(T::TableType::BinarySchema::data());
// This should equal the expected root table.
TEST_EQ_STR(schema->root_table()->name()->c_str(), "MyGame.Example.Monster");
}
void EmbeddedSchemaAccess() {
// Get the binary schema for the monster.
// Verify the schema is OK.
flatbuffers::Verifier verifierEmbeddedSchema(Monster::BinarySchema::data(),
Monster::BinarySchema::size());
TEST_EQ(reflection::VerifySchemaBuffer(verifierEmbeddedSchema), true);
// Reflect it.
auto schema = reflection::GetSchema(Monster::BinarySchema::data());
// This should equal the expected root table.
TEST_EQ_STR(schema->root_table()->name()->c_str(), "MyGame.Example.Monster");
// Repeat above, but do so through a template parameter:
EmbeddedSchemaAccessByType<StatT>();
}
void NestedVerifierTest() {
// Create a nested monster.
flatbuffers::FlatBufferBuilder nested_builder;
FinishMonsterBuffer(
nested_builder,
CreateMonster(nested_builder, nullptr, 0, 0,
nested_builder.CreateString("NestedMonster")));
// Verify the nested monster
flatbuffers::Verifier verifier(nested_builder.GetBufferPointer(),
nested_builder.GetSize());
TEST_EQ(true, VerifyMonsterBuffer(verifier));
{
// Create the outer monster.
flatbuffers::FlatBufferBuilder builder;
// Add the nested monster as a vector of bytes.
auto nested_monster_bytes = builder.CreateVector(
nested_builder.GetBufferPointer(), nested_builder.GetSize());
auto name = builder.CreateString("OuterMonster");
MonsterBuilder mon_builder(builder);
mon_builder.add_name(name);
mon_builder.add_testnestedflatbuffer(nested_monster_bytes);
FinishMonsterBuffer(builder, mon_builder.Finish());
// Verify the root monster, which includes verifing the nested monster
flatbuffers::Verifier verifier(builder.GetBufferPointer(),
builder.GetSize());
TEST_EQ(true, VerifyMonsterBuffer(verifier));
}
{
// Create the outer monster.
flatbuffers::FlatBufferBuilder builder;
// Purposely invalidate the nested flatbuffer setting its length to 1, an
// invalid length.
uint8_t invalid_nested_buffer[1];
auto nested_monster_bytes = builder.CreateVector(invalid_nested_buffer, 1);
auto name = builder.CreateString("OuterMonster");
MonsterBuilder mon_builder(builder);
mon_builder.add_name(name);
mon_builder.add_testnestedflatbuffer(nested_monster_bytes);
FinishMonsterBuffer(builder, mon_builder.Finish());
// Verify the root monster fails, since the included nested monster fails.
flatbuffers::Verifier verifier(builder.GetBufferPointer(),
builder.GetSize());
TEST_EQ(false, VerifyMonsterBuffer(verifier));
// Verify the root monster succeeds, since we've disabled checking nested
// flatbuffers
flatbuffers::Verifier::Options options;
options.check_nested_flatbuffers = false;
flatbuffers::Verifier no_check_nested(builder.GetBufferPointer(),
builder.GetSize(), options);
TEST_EQ(true, VerifyMonsterBuffer(no_check_nested));
}
{
// Create the outer monster.
flatbuffers::FlatBufferBuilder builder;
// Purposely invalidate the nested flatbuffer setting its length to 0, an
// invalid length.
uint8_t* invalid_nested_buffer = nullptr;
auto nested_monster_bytes = builder.CreateVector(invalid_nested_buffer, 0);
auto name = builder.CreateString("OuterMonster");
MonsterBuilder mon_builder(builder);
mon_builder.add_name(name);
mon_builder.add_testnestedflatbuffer(nested_monster_bytes);
FinishMonsterBuffer(builder, mon_builder.Finish());
// Verify the root monster fails, since the included nested monster fails.
flatbuffers::Verifier verifier(builder.GetBufferPointer(),
builder.GetSize());
TEST_EQ(false, VerifyMonsterBuffer(verifier));
}
}
void SizeVerifierTest() {
// Create a monster.
flatbuffers::FlatBufferBuilder builder;
FinishMonsterBuffer(builder,
CreateMonster(builder, nullptr, 0, 0,
builder.CreateString("NestedMonster")));
size_t length = builder.GetSize();
const uint8_t* data = builder.GetBufferPointer();
// Verify the monster, using SizeVerifier.
// We verify in several ways, using several different API functions/methods,
// to ensure that all of these APIs are tested.
flatbuffers::SizeVerifier size_verifier(data,
FLATBUFFERS_MAX_BUFFER_SIZE - 1);
{
TEST_EQ(true, VerifyMonsterBuffer(size_verifier));
}
{
TEST_EQ(true, size_verifier.VerifyBuffer<Monster>());
}
{
const MyGame::Example::Monster* my_buffer = GetMonster(data);
TEST_EQ(true, my_buffer->Verify(size_verifier));
}
// Verify that the size verifier computed the correct size.
TEST_EQ(length, size_verifier.GetComputedSize());
}
template <class T, class Container>
void TestIterators(const std::vector<T>& expected, const Container& tested) {
TEST_ASSERT(tested.rbegin().base() == tested.end());
TEST_ASSERT(tested.crbegin().base() == tested.cend());
TEST_ASSERT(tested.rend().base() == tested.begin());
TEST_ASSERT(tested.crend().base() == tested.cbegin());
size_t k = 0;
for (auto it = tested.begin(); it != tested.end(); ++it, ++k) {
const auto& e = expected.at(k);
TEST_EQ(*it, e);
}
TEST_EQ(k, expected.size());
k = expected.size();
for (auto it = tested.rbegin(); it != tested.rend(); ++it, --k) {
const auto& e = expected.at(k - 1);
TEST_EQ(*it, e);
}
TEST_EQ(k, 0);
}
void FlatbuffersIteratorsTest() {
{
flatbuffers::FlatBufferBuilder fbb;
const std::vector<unsigned char> inv_data = {1, 2, 3};
{
auto mon_name = fbb.CreateString("MyMonster"); // key, mandatory
auto inv_vec = fbb.CreateVector(inv_data);
auto empty_i64_vec =
fbb.CreateVector(static_cast<const int64_t*>(nullptr), 0);
MonsterBuilder mb(fbb);
mb.add_name(mon_name);
mb.add_inventory(inv_vec);
mb.add_vector_of_longs(empty_i64_vec);
FinishMonsterBuffer(fbb, mb.Finish());
}
const auto& mon = *flatbuffers::GetRoot<Monster>(fbb.GetBufferPointer());
TEST_EQ_STR("MyMonster", mon.name()->c_str());
TEST_ASSERT(mon.inventory());
TEST_ASSERT(mon.vector_of_longs());
TestIterators(inv_data, *mon.inventory());
TestIterators(std::vector<int64_t>(), *mon.vector_of_longs());
}
{
flatbuffers::FlatBufferBuilder fbb;
MyGame::Example::ArrayStruct aStruct;
MyGame::Example::FinishArrayTableBuffer(
fbb, MyGame::Example::CreateArrayTable(fbb, &aStruct));
const auto& array_table =
*flatbuffers::GetRoot<ArrayTable>(fbb.GetBufferPointer());
TEST_ASSERT(array_table.a());
auto& int_15 = *array_table.a()->b();
TestIterators(std::vector<int>(15, 0), int_15);
}
}
void PrivateAnnotationsLeaks() {
// Simple schemas and a "has optional scalar" sentinal.
std::vector<std::string> schemas;
std::vector<std::string> failure_schemas;
// (private) (table/struct)
schemas.push_back(
"table Monster (private) { mana: int; }"
"struct ABC (private) { mana: int; }");
// (public) (table/struct)
schemas.push_back(
"table Monster { mana: int; }"
"struct ABC { mana: int; }");
// (private) (union) containing (private) (table/struct)
schemas.push_back(
"table Monster (private) { mana: int; } "
"struct ABC (private) { mana: int; } "
"union Any (private) { Monster, ABC } ");
// (public) (union) containing (public) (table/struct)
schemas.push_back(
"table Monster { mana: int; }"
"struct ABC { mana: int; }"
"union Any { Monster, ABC }");
// (private) (table/struct/enum)
schemas.push_back(
"table Monster (private) { mana: int; }"
"struct ABC (private) { mana: int; }"
"enum Race:byte (private) { None = -1, Human = 0, }");
// (public) (table/struct/enum)
schemas.push_back(
"table Monster { mana: int; }"
"struct ABC { mana: int; }"
"enum Race:byte { None = -1, Human = 0, }");
// (private) (union) containing (private) (table/struct)
schemas.push_back(
"table Monster (private) { mana: int; }"
"struct ABC (private) { mana: int; }"
"enum Race:byte (private) { None = -1, Human = 0, }"
"union Any (private) { Monster, ABC }");
// (public) (union) containing (public) (table/struct)
schemas.push_back(
"table Monster { mana: int; }"
"struct ABC { mana: int; }"
"enum Race:byte { None = -1, Human = 0, }"
"union Any { Monster, ABC }");
// (private) (table), (public struct)
schemas.push_back(
"table Monster (private) { mana: int; }"
"struct ABC { mana: int; }");
// (private) (table), (public) (struct/enum)
schemas.push_back(
"table Monster (private) { mana: int; }"
"struct ABC { mana: int; }"
"enum Race:byte { None = -1, Human = 0, }");
// (public) (struct) containing (public) (enum)
schemas.push_back(
"enum Race:byte { None = -1, Human = 0, }"
"table Monster { mana: int; }"
"struct ABC { mana: int; type: Race; }");
// (public) (union) containing (private) (table) & (public) (struct)
failure_schemas.push_back(
"table Monster (private) { mana: int; }"
"struct ABC { mana: int; }"
"union Any { Monster, ABC }");
// (public) (union) containing (private) (table/struct)
failure_schemas.push_back(
"table Monster (private) { mana: int; }"
"struct ABC (private) { mana: int; }"
"enum Race:byte { None = -1, Human = 0, }"
"union Any { Monster, ABC }");
// (public) (table) containing (private) (struct)
failure_schemas.push_back(
"table Monster { mana: int; ab: ABC; }"
"struct ABC (private) { mana: int; }");
// (public) (struct) containing (private) (enum)
failure_schemas.push_back(
"enum Race:byte (private) { None = -1, Human = 0, }"
"table Monster { mana: int; }"
"struct ABC { mana: int; type: Race; }");
flatbuffers::IDLOptions opts;
opts.lang_to_generate = flatbuffers::IDLOptions::Language::kSwift;
opts.no_leak_private_annotations = true;
for (auto schema = schemas.begin(); schema < schemas.end(); schema++) {
flatbuffers::Parser parser(opts);
TEST_ASSERT(parser.Parse(schema->c_str()));
}
for (auto schema = failure_schemas.begin(); schema < failure_schemas.end();
schema++) {
flatbuffers::Parser parser(opts);
TEST_EQ(false, parser.Parse(schema->c_str()));
}
opts.no_leak_private_annotations = false;
for (auto schema = schemas.begin(); schema < schemas.end(); schema++) {
flatbuffers::Parser parser(opts);
TEST_ASSERT(parser.Parse(schema->c_str()));
}
for (auto schema = failure_schemas.begin(); schema < failure_schemas.end();
schema++) {
flatbuffers::Parser parser(opts);
TEST_ASSERT(parser.Parse(schema->c_str()));
}
}
void VectorSpanTest() {
flatbuffers::FlatBufferBuilder builder;
auto mloc = CreateMonster(
builder, nullptr, 0, 0, builder.CreateString("Monster"),
builder.CreateVector<uint8_t>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));
FinishMonsterBuffer(builder, mloc);
auto monster = GetMonster(builder.GetBufferPointer());
auto mutable_monster = GetMutableMonster(builder.GetBufferPointer());
{ // using references
TEST_NOTNULL(monster->inventory());
flatbuffers::span<const uint8_t> const_inventory =
flatbuffers::make_span(*monster->inventory());
TEST_EQ(const_inventory.size(), 10);
TEST_EQ(const_inventory[0], 0);
TEST_EQ(const_inventory[9], 9);
flatbuffers::span<uint8_t> mutable_inventory =
flatbuffers::make_span(*mutable_monster->mutable_inventory());
TEST_EQ(mutable_inventory.size(), 10);
TEST_EQ(mutable_inventory[0], 0);
TEST_EQ(mutable_inventory[9], 9);
mutable_inventory[0] = 42;
TEST_EQ(mutable_inventory[0], 42);
mutable_inventory[0] = 0;
TEST_EQ(mutable_inventory[0], 0);
}
{ // using pointers
TEST_EQ(flatbuffers::VectorLength(monster->inventory()), 10);
flatbuffers::span<const uint8_t> const_inventory =
flatbuffers::make_span(monster->inventory());
TEST_EQ(const_inventory.size(), 10);
TEST_EQ(const_inventory[0], 0);
TEST_EQ(const_inventory[9], 9);
flatbuffers::span<uint8_t> mutable_inventory =
flatbuffers::make_span(mutable_monster->mutable_inventory());
TEST_EQ(mutable_inventory.size(), 10);
TEST_EQ(mutable_inventory[0], 0);
TEST_EQ(mutable_inventory[9], 9);
mutable_inventory[0] = 42;
TEST_EQ(mutable_inventory[0], 42);
mutable_inventory[0] = 0;
TEST_EQ(mutable_inventory[0], 0);
}
{
TEST_ASSERT(nullptr == monster->testnestedflatbuffer());
TEST_EQ(flatbuffers::VectorLength(monster->testnestedflatbuffer()), 0);
flatbuffers::span<const uint8_t> const_nested =
flatbuffers::make_span(monster->testnestedflatbuffer());
TEST_ASSERT(const_nested.empty());
flatbuffers::span<uint8_t> mutable_nested =
flatbuffers::make_span(mutable_monster->mutable_testnestedflatbuffer());
TEST_ASSERT(mutable_nested.empty());
}
}
void NativeInlineTableVectorTest() {
TestNativeInlineTableT test;
for (int i = 0; i < 10; ++i) {
NativeInlineTableT t;
t.a = i;
test.t.push_back(t);
}
flatbuffers::FlatBufferBuilder fbb;
auto offset = TestNativeInlineTable::Pack(fbb, &test);
fbb.Finish(offset);
auto* root =
flatbuffers::GetRoot<TestNativeInlineTable>(fbb.GetBufferPointer());
TestNativeInlineTableT unpacked;
root->UnPackTo(&unpacked);
for (int i = 0; i < 10; ++i) {
TEST_ASSERT(unpacked.t[i] == test.t[i]);
}
TEST_ASSERT(unpacked.t == test.t);
}
// Guard against -Wunused-function on platforms without file tests.
#ifndef FLATBUFFERS_NO_FILE_TESTS
void DoNotRequireEofTest(const std::string& tests_data_path) {
std::string schemafile;
bool ok = flatbuffers::LoadFile(
(tests_data_path + "monster_test.fbs").c_str(), false, &schemafile);
TEST_EQ(ok, 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};
flatbuffers::IDLOptions opt;
opt.require_json_eof = false;
flatbuffers::Parser parser(opt);
ok = parser.Parse(schemafile.c_str(), include_directories);
TEST_EQ(ok, true);
const char* str = R"(Some text at the beginning. {
"name": "Blob",
"hp": 5
}{
"name": "Imp",
"hp": 10
}
Some extra text at the end too.
)";
const char* tableStart = std::strchr(str, '{');
ok = parser.ParseJson(tableStart);
TEST_EQ(ok, true);
const Monster* monster = GetMonster(parser.builder_.GetBufferPointer());
TEST_EQ_STR(monster->name()->c_str(), "Blob");
TEST_EQ(monster->hp(), 5);
tableStart += parser.BytesConsumed();
ok = parser.ParseJson(tableStart);
TEST_EQ(ok, true);
monster = GetMonster(parser.builder_.GetBufferPointer());
TEST_EQ_STR(monster->name()->c_str(), "Imp");
TEST_EQ(monster->hp(), 10);
}
#endif
void UnionUnderlyingTypeTest() {
using namespace UnionUnderlyingType;
TEST_ASSERT(sizeof(ABC) == sizeof(uint32_t));
TEST_ASSERT(static_cast<int32_t>(ABC::A) == 555);
TEST_ASSERT(static_cast<int32_t>(ABC::B) == 666);
TEST_ASSERT(static_cast<int32_t>(ABC::C) == 777);
DT buffer;
AT a;
a.a = 42;
BT b;
b.b = "foo";
CT c;
c.c = true;
buffer.test_union = ABCUnion();
buffer.test_union.Set(a);
buffer.test_vector_of_union.resize(3);
buffer.test_vector_of_union[0].Set(a);
buffer.test_vector_of_union[1].Set(b);
buffer.test_vector_of_union[2].Set(c);
flatbuffers::FlatBufferBuilder fbb;
auto offset = D::Pack(fbb, &buffer);
fbb.Finish(offset);
auto* root = flatbuffers::GetRoot<D>(fbb.GetBufferPointer());
DT unpacked;
root->UnPackTo(&unpacked);
TEST_ASSERT(unpacked.test_union == buffer.test_union);
TEST_ASSERT(unpacked.test_vector_of_union == buffer.test_vector_of_union);
}
void StructsInHashTableTest() {
#if defined(HAS_ABSL_CONTAINERS) && (!defined(_MSC_VER) || _MSC_VER >= 1700)
absl::flat_hash_set<ArrayStruct> hash_set;
ArrayStruct array_struct_1;
array_struct_1.mutate_a(0.4);
for (int i = 0; i < array_struct_1.b()->size(); ++i) {
array_struct_1.mutable_b()->Mutate(i, i * 2);
}
for (int i = 0; i < array_struct_1.d()->size(); ++i) {
NestedStruct nested_struct;
nested_struct.mutable_a()->Mutate(0, i * 3);
array_struct_1.mutable_d()->Mutate(i, nested_struct);
}
ArrayStruct array_struct_2;
array_struct_2.mutate_e(999);
hash_set.insert(array_struct_1);
hash_set.insert(array_struct_2);
TEST_EQ(hash_set.size(), 2);
TEST_ASSERT(hash_set.contains(array_struct_1));
TEST_ASSERT(hash_set.contains(array_struct_2));
ArrayStruct array_struct_3 = array_struct_1;
array_struct_3.mutable_b()->Mutate(0, 2);
TEST_ASSERT(!hash_set.contains(array_struct_3));
hash_set.insert(array_struct_3);
TEST_ASSERT(hash_set.contains(array_struct_3));
#endif // defined(HAS_ABSL_CONTAINERS) && (!defined(_MSC_VER) || _MSC_VER >=
// 1700)
}
FlatBuffers 64 for C++ (#7935) * First working hack of adding 64-bit. Don't judge :) * Made vector_downward work on 64 bit types * vector_downward uses size_t, added offset64 to reflection * cleaned up adding offset64 in parser * Add C++ testing skeleton for 64-bit * working test for CreateVector64 * working >2 GiB buffers * support for large strings * simplified CreateString<> to just provide the offset type * generalize CreateVector template * update test_64.afb due to upstream format change * Added Vector64 type, which is just an alias for vector ATM * Switch to Offset64 for Vector64 * Update for reflection bfbs output change * Starting to add support for vector64 type in C++ * made a generic CreateVector that can handle different offsets and vector types * Support for 32-vector with 64-addressing * Vector64 basic builder + tests working * basic support for json vector64 support * renamed fields in test_64bit.fbs to better reflect their use * working C++ vector64 builder * Apply --annotate-sparse-vector to 64-bit tests * Enable Vector64 for --annotate-sparse-vectors * Merged from upstream * Add `near_string` field for testing 32-bit offsets alongside * keep track of where the 32-bit and 64-bit regions are for flatbufferbuilder * move template<> outside class body for GCC * update run.sh to build and run tests * basic assertion for adding 64-bit offset at the wrong time * started to separate `FlatBufferBuilder` into two classes, 1 64-bit aware, the other not * add test for nested flatbuffer vector64, fix bug in alignment of big vectors * fixed CreateDirect method by iterating by Offset64 first * internal refactoring of flatbufferbuilder * block not supported languages in the parser from using 64-bit * evolution tests for adding a vector64 field * conformity tests for adding/removing offset64 attributes * ensure test is for a big buffer * add parser error tests for `offset64` and `vector64` attributes * add missing static that GCC only complains about * remove stdint-uintn.h header that gets automatically added * move 64-bit CalculateOffset internal * fixed return size of EndVector * various fixes on windows * add SizeT to vector_downward * minimze range of size changes in vector and builder * reworked how tracking if 64-offsets are added * Add ReturnT to EndVector * small cleanups * remove need for second Array definition * combine IndirectHelpers into one definition * started support for vector of struct * Support for 32/64-vectors of structs + Offset64 * small cleanups * add verification for vector64 * add sized prefix for 64-bit buffers * add fuzzer for 64-bit * add example of adding many vectors using a wrapper table * run the new -bfbs-gen-embed logic on the 64-bit tests * remove run.sh and fix cmakelist issue * fixed bazel rules * fixed some PR comments * add 64-bit tests to cmakelist
2023-05-09 09:16:30 -07:00
static void Offset64Tests() {
2023-05-31 11:52:05 -07:00
#if INCLUDE_64_BIT_TESTS
FlatBuffers 64 for C++ (#7935) * First working hack of adding 64-bit. Don't judge :) * Made vector_downward work on 64 bit types * vector_downward uses size_t, added offset64 to reflection * cleaned up adding offset64 in parser * Add C++ testing skeleton for 64-bit * working test for CreateVector64 * working >2 GiB buffers * support for large strings * simplified CreateString<> to just provide the offset type * generalize CreateVector template * update test_64.afb due to upstream format change * Added Vector64 type, which is just an alias for vector ATM * Switch to Offset64 for Vector64 * Update for reflection bfbs output change * Starting to add support for vector64 type in C++ * made a generic CreateVector that can handle different offsets and vector types * Support for 32-vector with 64-addressing * Vector64 basic builder + tests working * basic support for json vector64 support * renamed fields in test_64bit.fbs to better reflect their use * working C++ vector64 builder * Apply --annotate-sparse-vector to 64-bit tests * Enable Vector64 for --annotate-sparse-vectors * Merged from upstream * Add `near_string` field for testing 32-bit offsets alongside * keep track of where the 32-bit and 64-bit regions are for flatbufferbuilder * move template<> outside class body for GCC * update run.sh to build and run tests * basic assertion for adding 64-bit offset at the wrong time * started to separate `FlatBufferBuilder` into two classes, 1 64-bit aware, the other not * add test for nested flatbuffer vector64, fix bug in alignment of big vectors * fixed CreateDirect method by iterating by Offset64 first * internal refactoring of flatbufferbuilder * block not supported languages in the parser from using 64-bit * evolution tests for adding a vector64 field * conformity tests for adding/removing offset64 attributes * ensure test is for a big buffer * add parser error tests for `offset64` and `vector64` attributes * add missing static that GCC only complains about * remove stdint-uintn.h header that gets automatically added * move 64-bit CalculateOffset internal * fixed return size of EndVector * various fixes on windows * add SizeT to vector_downward * minimze range of size changes in vector and builder * reworked how tracking if 64-offsets are added * Add ReturnT to EndVector * small cleanups * remove need for second Array definition * combine IndirectHelpers into one definition * started support for vector of struct * Support for 32/64-vectors of structs + Offset64 * small cleanups * add verification for vector64 * add sized prefix for 64-bit buffers * add fuzzer for 64-bit * add example of adding many vectors using a wrapper table * run the new -bfbs-gen-embed logic on the 64-bit tests * remove run.sh and fix cmakelist issue * fixed bazel rules * fixed some PR comments * add 64-bit tests to cmakelist
2023-05-09 09:16:30 -07:00
Offset64Test();
Offset64SerializedFirst();
Offset64NestedFlatBuffer();
Offset64CreateDirect();
Offset64Evolution();
Offset64VectorOfStructs();
Offset64SizePrefix();
Offset64ManyVectors();
Offset64ForceAlign();
2023-05-31 11:52:05 -07:00
#endif
FlatBuffers 64 for C++ (#7935) * First working hack of adding 64-bit. Don't judge :) * Made vector_downward work on 64 bit types * vector_downward uses size_t, added offset64 to reflection * cleaned up adding offset64 in parser * Add C++ testing skeleton for 64-bit * working test for CreateVector64 * working >2 GiB buffers * support for large strings * simplified CreateString<> to just provide the offset type * generalize CreateVector template * update test_64.afb due to upstream format change * Added Vector64 type, which is just an alias for vector ATM * Switch to Offset64 for Vector64 * Update for reflection bfbs output change * Starting to add support for vector64 type in C++ * made a generic CreateVector that can handle different offsets and vector types * Support for 32-vector with 64-addressing * Vector64 basic builder + tests working * basic support for json vector64 support * renamed fields in test_64bit.fbs to better reflect their use * working C++ vector64 builder * Apply --annotate-sparse-vector to 64-bit tests * Enable Vector64 for --annotate-sparse-vectors * Merged from upstream * Add `near_string` field for testing 32-bit offsets alongside * keep track of where the 32-bit and 64-bit regions are for flatbufferbuilder * move template<> outside class body for GCC * update run.sh to build and run tests * basic assertion for adding 64-bit offset at the wrong time * started to separate `FlatBufferBuilder` into two classes, 1 64-bit aware, the other not * add test for nested flatbuffer vector64, fix bug in alignment of big vectors * fixed CreateDirect method by iterating by Offset64 first * internal refactoring of flatbufferbuilder * block not supported languages in the parser from using 64-bit * evolution tests for adding a vector64 field * conformity tests for adding/removing offset64 attributes * ensure test is for a big buffer * add parser error tests for `offset64` and `vector64` attributes * add missing static that GCC only complains about * remove stdint-uintn.h header that gets automatically added * move 64-bit CalculateOffset internal * fixed return size of EndVector * various fixes on windows * add SizeT to vector_downward * minimze range of size changes in vector and builder * reworked how tracking if 64-offsets are added * Add ReturnT to EndVector * small cleanups * remove need for second Array definition * combine IndirectHelpers into one definition * started support for vector of struct * Support for 32/64-vectors of structs + Offset64 * small cleanups * add verification for vector64 * add sized prefix for 64-bit buffers * add fuzzer for 64-bit * add example of adding many vectors using a wrapper table * run the new -bfbs-gen-embed logic on the 64-bit tests * remove run.sh and fix cmakelist issue * fixed bazel rules * fixed some PR comments * add 64-bit tests to cmakelist
2023-05-09 09:16:30 -07:00
}
// Test that Pack() generates correctly namespace-qualified Create* calls
// when referencing tables from different namespaces. (issue #8948)
void CrossNamespacePackTest() {
// Build a Consumer with a cross-namespace TableWithNative reference.
foo::ConsumerT consumer;
consumer.c1 = std::make_unique<native::TableWithNativeT>();
consumer.c1->value = 42;
// Add a vector element too.
consumer.c2.push_back(std::make_unique<native::TableWithNativeT>());
consumer.c2[0]->value = 99;
// Pack and verify round-trip.
flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(foo::Consumer::Pack(fbb, &consumer));
auto* packed = flatbuffers::GetRoot<foo::Consumer>(fbb.GetBufferPointer());
auto unpacked = packed->UnPack();
TEST_EQ(unpacked->c1->value, 42);
TEST_EQ(unpacked->c2.size(), 1);
TEST_EQ(unpacked->c2[0]->value, 99);
}
int FlatBufferTests(const std::string& tests_data_path) {
// Run our various test suites:
std::string rawbuf;
auto flatbuf1 = CreateFlatBufferTest(rawbuf);
auto flatbuf = std::move(flatbuf1); // Test move assignment.
AccessFlatBufferTest(reinterpret_cast<const uint8_t*>(rawbuf.c_str()),
rawbuf.length());
AccessFlatBufferTest(flatbuf.data(), flatbuf.size());
MutateFlatBuffersTest(flatbuf.data(), flatbuf.size());
ObjectFlatBuffersTest(flatbuf.data());
UnPackTo(flatbuf.data());
MiniReflectFlatBuffersTest(flatbuf.data());
MiniReflectFixedLengthArrayTest();
SizePrefixedTest();
AlignmentTest();
#ifndef FLATBUFFERS_NO_FILE_TESTS
ParseAndGenerateTextTest(tests_data_path, false);
ParseAndGenerateTextTest(tests_data_path, true);
FixedLengthArrayJsonTest(tests_data_path, false);
FixedLengthArrayJsonTest(tests_data_path, true);
ReflectionTest(tests_data_path, flatbuf.data(), flatbuf.size());
ParseProtoTest(tests_data_path);
EvolutionTest(tests_data_path);
UnionDeprecationTest(tests_data_path);
UnionVectorTest(tests_data_path);
GenerateTableTextTest(tests_data_path);
TestEmbeddedBinarySchema(tests_data_path);
JsonOptionalTest(tests_data_path, false);
JsonOptionalTest(tests_data_path, true);
MultiFileNameClashTest(tests_data_path);
InvalidNestedFlatbufferTest(tests_data_path);
JsonDefaultTest(tests_data_path);
JsonEnumsTest(tests_data_path);
TestMonsterExtraFloats(tests_data_path);
ParseIncorrectMonsterJsonTest(tests_data_path);
FixedLengthArraySpanTest(tests_data_path);
DoNotRequireEofTest(tests_data_path);
JsonUnionStructTest();
VectorTableNakedPtrTest();
#else
// Guard against -Wunused-parameter.
(void)tests_data_path;
#endif
UtilConvertCase();
FuzzTest1();
FuzzTest2();
TriviallyCopyableTest();
ErrorTest();
ValueTest();
EnumValueTest();
NestedListTest();
EnumStringsTest();
EnumNamesTest();
EnumOutOfRangeTest();
IntegerOutOfRangeTest();
IntegerBoundaryTest();
UnicodeTest();
UnicodeTestAllowNonUTF8();
UnicodeTestGenerateTextFailsOnNonUTF8();
UnicodeSurrogatesTest();
UnicodeInvalidSurrogatesTest();
InvalidUTF8Test();
UnknownFieldsTest();
ParseUnionTest();
ValidSameNameDifferentNamespaceTest();
ConformTest();
ParseProtoBufAsciiTest();
TypeAliasesTest();
EndianSwapTest();
CreateSharedStringTest();
FlexBuffersTest();
FlexBuffersReuseBugTest();
FlexBuffersDeprecatedTest();
UninitializedVectorTest();
EqualOperatorTest();
NumericUtilsTest();
IsAsciiUtilsTest();
ValidFloatTest();
InvalidFloatTest();
FixedLengthArrayTest();
[C++] remove static_cast expression (#5440) * [C++] remove static_cast expression * [C++] Add unit test for native_type usage * [C++] Add flatc compilation for native_type_test.fbs * [C++] update CMakeLists to compile native_type_test.fbs properly * Update BUILD file for bazel * [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList * [C++] remove "= default" from constructor to support old compilers * Update BUILD file for bazel, attempt 2 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types * Update BUILD file for bazel, attempt 3 * Update BUILD file for bazel, attempt 4 * Update BUILD file for bazel, attempt 5 * Update BUILD file for bazel, attempt 6 * [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2 * [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt * native_type_test.fbs style corrected * [C++] Code style modifications * [C++] Fix flatc arguments in CMakeLists * [C++] Remove --gen-compare from default parameters for flatc in CMakeLists * [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix * [C++] Remove one more #if !defined * [C++] Restore version with correct static_cast, add the same fix for SortedStructs * Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs" This reverts commit d61f4d6628cfce530c8b9a4c9e7af368d599f99f. * [C++] Fix Android.mk
2019-08-02 00:31:48 +03:00
NativeTypeTest();
OptionalScalarsTest();
ParseFlexbuffersFromJsonWithNullTest();
FlatbuffersSpanTest();
FixedLengthArrayConstructorTest();
FixedLengthArrayOperatorEqualTest();
FieldIdentifierTest();
StringVectorDefaultsTest();
FlexBuffersFloatingPointTest();
FlatbuffersIteratorsTest();
WarningsAsErrorsTest();
NestedVerifierTest();
SizeVerifierTest();
PrivateAnnotationsLeaks();
JsonUnsortedArrayTest();
VectorSpanTest();
NativeInlineTableVectorTest();
FixedSizedScalarKeyInStructTest();
StructKeyInStructTest();
NestedStructKeyInStructTest();
FixedSizedStructArrayKeyInStructTest();
EmbeddedSchemaAccess();
FlatBuffers 64 for C++ (#7935) * First working hack of adding 64-bit. Don't judge :) * Made vector_downward work on 64 bit types * vector_downward uses size_t, added offset64 to reflection * cleaned up adding offset64 in parser * Add C++ testing skeleton for 64-bit * working test for CreateVector64 * working >2 GiB buffers * support for large strings * simplified CreateString<> to just provide the offset type * generalize CreateVector template * update test_64.afb due to upstream format change * Added Vector64 type, which is just an alias for vector ATM * Switch to Offset64 for Vector64 * Update for reflection bfbs output change * Starting to add support for vector64 type in C++ * made a generic CreateVector that can handle different offsets and vector types * Support for 32-vector with 64-addressing * Vector64 basic builder + tests working * basic support for json vector64 support * renamed fields in test_64bit.fbs to better reflect their use * working C++ vector64 builder * Apply --annotate-sparse-vector to 64-bit tests * Enable Vector64 for --annotate-sparse-vectors * Merged from upstream * Add `near_string` field for testing 32-bit offsets alongside * keep track of where the 32-bit and 64-bit regions are for flatbufferbuilder * move template<> outside class body for GCC * update run.sh to build and run tests * basic assertion for adding 64-bit offset at the wrong time * started to separate `FlatBufferBuilder` into two classes, 1 64-bit aware, the other not * add test for nested flatbuffer vector64, fix bug in alignment of big vectors * fixed CreateDirect method by iterating by Offset64 first * internal refactoring of flatbufferbuilder * block not supported languages in the parser from using 64-bit * evolution tests for adding a vector64 field * conformity tests for adding/removing offset64 attributes * ensure test is for a big buffer * add parser error tests for `offset64` and `vector64` attributes * add missing static that GCC only complains about * remove stdint-uintn.h header that gets automatically added * move 64-bit CalculateOffset internal * fixed return size of EndVector * various fixes on windows * add SizeT to vector_downward * minimze range of size changes in vector and builder * reworked how tracking if 64-offsets are added * Add ReturnT to EndVector * small cleanups * remove need for second Array definition * combine IndirectHelpers into one definition * started support for vector of struct * Support for 32/64-vectors of structs + Offset64 * small cleanups * add verification for vector64 * add sized prefix for 64-bit buffers * add fuzzer for 64-bit * add example of adding many vectors using a wrapper table * run the new -bfbs-gen-embed logic on the 64-bit tests * remove run.sh and fix cmakelist issue * fixed bazel rules * fixed some PR comments * add 64-bit tests to cmakelist
2023-05-09 09:16:30 -07:00
Offset64Tests();
UnionUnderlyingTypeTest();
StructsInHashTableTest();
2025-12-19 14:32:51 -08:00
DefaultVectorsStringsTest();
CrossNamespacePackTest();
return 0;
}
} // namespace
} // namespace tests
} // namespace flatbuffers
int main(int argc, const char* argv[]) {
std::string tests_data_path = "tests/";
for (int argi = 1; argi < argc; argi++) {
std::string arg = argv[argi];
if (arg == "--test_path") {
if (++argi >= argc) {
fprintf(stderr, "error: missing path following: %s\n", arg.c_str());
exit(1);
}
// Override default path if provided one.
tests_data_path = argv[argi];
} else {
fprintf(stderr, "error: Unknown argument: %s\n", arg.c_str());
exit(1);
}
}
InitTestEngine();
std::string req_locale;
if (flatbuffers::ReadEnvironmentVariable("FLATBUFFERS_TEST_LOCALE",
&req_locale)) {
TEST_OUTPUT_LINE("The environment variable FLATBUFFERS_TEST_LOCALE=%s",
req_locale.c_str());
req_locale = flatbuffers::RemoveStringQuotes(req_locale);
std::string the_locale;
TEST_ASSERT_FUNC(
flatbuffers::SetGlobalTestLocale(req_locale.c_str(), &the_locale));
TEST_OUTPUT_LINE("The global C-locale changed: %s", the_locale.c_str());
}
#ifdef FLATBUFFERS_TEST_PATH_PREFIX
tests_data_path =
FLATBUFFERS_STRING(FLATBUFFERS_TEST_PATH_PREFIX) + tests_data_path;
#endif
flatbuffers::tests::FlatBufferTests(tests_data_path);
FlatBufferBuilderTest();
if (!testing_fails) {
TEST_OUTPUT_LINE("ALL TESTS PASSED");
} else {
TEST_OUTPUT_LINE("%d FAILED TESTS", testing_fails);
}
return CloseTestEngine();
}