Compare commits

...

214 Commits

Author SHA1 Message Date
Ali Sherif
1f438bd40f [Swift] Fix verifier accepting truncated scalar vectors (OOB read/write, RCE) (#9081) 2026-05-08 10:16:10 +02:00
mustiikhalil
392165432a [Swift] Migrate to use Swift Testing (#9076)
* Migrating from Xctests to swift testing

This migrates to the new Swift testing framework,
which would allow us to always use the latest tech
from swift moving forward.

* Updates flag to make sure that Wasm testing works
2026-05-07 21:49:41 -04:00
mustiikhalil
e6bbb3d22e [Swift] Migrate to swift 6.0 and Implements support gRPC v2 (#8983)
* Migrate to swift 6.0 & swift-gRPC 2.0

The following migrates to swift 6.0, and also
migrate to swift-grpc 2.0 that uses swift-nio
under the hood to provide nicer API and async await

Adds sendable to enum & update @_implementationOnly imports to use internal imports

* Address PR comments regarding misspelling & proper method naming.
2026-05-06 04:39:53 +02:00
Rifat Al Jubayer
a6979fe14a Fix logic inversion in FlexBuffers VerifyKey() (#9072)
VerifyKey() returns true on the first non-zero byte instead of
checking for a null terminator. This causes VerifyBuffer() to accept
FlexBuffers with non-null-terminated keys. Subsequent access to those
keys via strlen()/strcmp() reads out of bounds.

The condition if (*p++) should be if (!*p++) — return true
when a null terminator is found, not when any non-zero byte is found.

Confirmed with AddressSanitizer: heap-buffer-overflow in strlen()
after VerifyBuffer() returns true on a corrupted buffer.
2026-05-04 22:11:30 -04:00
Zen Dodd
bab10754d9 Stage the Python license file during builds (#9015)
Copy the repo-root LICENSE into the Python package directory for the duration of setup() so license_files = LICENSE remains valid without using deprecated parent-directory paths.

Remove the staged copy after the build completes.
2026-04-17 20:30:06 -04:00
Felix
ac7ef1176a Fix typo in generated header name (#9034) 2026-04-18 00:09:10 +00:00
Felix
d6444fb7fc Fix indention level for --no-python-gen-numpy (#9049) 2026-04-17 16:50:03 -04:00
Felix
e223d69b36 [Python] Extend GRPC Typing (#9007)
Extend function calls with optional type infos for checking
and discovering.

e838ba8a71/src/python/grpcio/grpc/__init__.py (L680)
2026-04-03 14:12:08 +00:00
Tulgaaaaaaaa
05cc7a2eff fix: correct operator precedence in ForAllFields reverse iteration (#8991)
* fix: correct operator precedence in ForAllFields reverse iteration

The expression `size() - i + 1` evaluates as `(size() - i) + 1` due to
left-to-right associativity, producing an out-of-bounds index when
reverse=true. For a vector of size N, the first iteration (i=0) accesses
index N+1, which is 2 past the last valid index.

Changed to `size() - (i + 1)` to match the correct implementation
already present in bfbs_gen.h:192.

Bug: CWE-125 (Out-of-bounds Read), CWE-783 (Operator Precedence Error)

* test: add ForAllFieldsReverseTest for reverse iteration correctness

Verify that ForAllFields with reverse=true iterates fields in
descending ID order. Tests both Stat (3 fields) and Monster
(many fields with non-sequential definition order) tables.

---------

Co-authored-by: Tulgaa <tulgaa.kek@gmail.com>
2026-04-02 10:14:27 +00:00
Noam ismach moshe
8a12183c3b Fix out-of-bounds vector access in StructDef::Deserialize (#8988)
* Fix out-of-bounds vector access in StructDef::Deserialize

* Fix syntax: use error_ instead of error()
2026-04-02 08:03:03 +00:00
Renzo
21b706b62d fix: swapped argument order in new_inconsistent_union calls (#9001) (#9010) 2026-04-02 07:05:58 +00:00
Tomasz Andrzejak
c5f151ab33 Add fallible try_* API for rust FlatBufferBuilder (#8918)
* Add fallible try_* API for FlatBufferBuilder

This is to support error propagation from Allocator trait. The Allocator
grow_downwards() method returns Result<(), Self::Error>, but
FlatBufferBuilder panics via .expect() when allocation fails instead of
propagating the error.

* Add rust fallible API docs
2026-04-02 06:49:51 +00:00
Björn Harrtell
3860f1cf7f [TS] Fixup TS test run at CI (#9004) 2026-03-30 13:32:24 +01:00
Thomas Köppe
4e582b0c1d [flexbuffers] Add "AlignedBlob", a version of "Blob" with explicit alignment. (#8993)
A blob is an array of bytes and has no intrinsic alignment (i.e. the
alignment is 1). The alignment of the existing flexbuffers blob is
solely affected by the width of the integer needed to store the blob's
size: that integer's width becomes the alignment of the blob.

The proposed AlignedBlob function here piggybacks on this effect and
simply uses a user-defined alignment for the width of the integer that
stores the blob's size; this automatically imparts that same alignment
on the blob itself. (The width is bounded below by the actual width
needed to store the blob's size.)

The ability to control the alignment of a blob is important for use
cases in which the blob itself stores structured data that we want to
access without further copies (e.g. other flatbuffer messages).
2026-03-23 10:28:03 -07:00
Fedor Osetrov
8396e00dd8 allow to use reflection in constant time evaluation (#8978)
* Update reflection.h

allow to use reflection in constant time evaluation

* make GetTypeSize constexpr

* fix clang-format
2026-03-20 02:01:45 +00:00
dependabot[bot]
48babd417d Bump flatted in the npm_and_yarn group across 1 directory (#8989)
Bumps the npm_and_yarn group with 1 update in the / directory: [flatted](https://github.com/WebReflection/flatted).


Updates `flatted` from 3.3.1 to 3.4.2
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.1...v3.4.2)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-19 21:48:28 -04:00
tmimmanuel
22770f7e85 Fix inconsistent Python union creator function naming (#8981) 2026-03-19 12:36:37 +00:00
Dexter.k
21b033227e Add bounds check for root offset in AddFlatBuffer (#8982) 2026-03-19 08:22:26 -04:00
dataCenter430
93f587a6d3 fix: annotated output for size-prefixed binaries (#8976) 2026-03-18 22:54:46 -04:00
Kevin Zhao
8afb68f074 codegen: escape string default values to prevent code injection (#8964)
String default values parsed from .fbs schemas are un-escaped by the IDL
parser (e.g., \x22 becomes a raw " byte), but code generators embed these
raw values directly into generated source code string literals. This allows
specially crafted .fbs files to break out of string literals and inject
arbitrary code into generated C++, Rust, TypeScript, and Swift source.

Fix by adding EscapeCodeGenString() helper that re-escapes string content
before embedding, and applying it to all 7 affected injection points across
5 code generators (C++, Rust, TypeScript, Swift, FBS).

Resolves the TODO comments in idl_gen_cpp.cpp and idl_gen_rust.cpp.
2026-03-18 22:01:23 -04:00
Derek Bailey
2e07f269b9 Update build.yml
Remove 64-core windows github action runner as it is a charged product we need to do expense
2026-03-17 09:58:26 -07:00
Renzo
10c994155c Fix: allow flexbuffers alloc check test (#8972)
* Fix: allow flexbuffers alloc check test

* fix: flaky CI failure

* fix: set flexbuffers alloc check false
2026-03-12 09:44:32 -04:00
dataCenter430
fc9909c30a fix: infinite loop in proto reserved range parser (CWE-835) (#8966) 2026-03-11 22:23:32 -04:00
tmimmanuel
e35817577c Fix missing namespace qualifier in Pack() (#8967)
* Fix missing namespace qualifier in Pack() for cross-namespace table references

* Fix missing namespace qualifier in Pack()

* Add cross_namespace_pack_test to Bazel build
2026-03-11 22:11:06 -04:00
Moritz Walker
9e3fe5d3f6 rust: add secondary function with preallocated internal vecs (#8936)
* rust: add secondary function with preallocated internal vecs

* docs: document pre allocation feature for rust implementation
2026-03-11 15:26:23 +00:00
statxc
dc9217347e fix: add missing bracket (#8969) 2026-03-11 02:42:46 +00:00
statxc
a7fed2ce67 feat: add lookup_index_by_key to Rust Vector for index-based search (#8959)
* feat: add lookup_index_by_key to Rust Vector for index-based binary search

* fix: remove duplicated code
2026-03-11 02:15:21 +00:00
statxc
de3b97355d feat: use HashMap for create_shared_string to fix O(N²) performance (#8958)
* feat: use HashMap for create_shared_string to fix O(N²) performance

* refactor: clean up no_std binary_search_by with direct slice comparison
2026-03-10 21:56:34 -04:00
Renzo
8aa7084f01 Fix flaky flexbuffers_alloc_check test in cargo test (#8965) 2026-03-08 23:43:07 -04:00
Justin Davis
0f469cad54 Revert "fix using null string in vector (#7872)" (#8879)
This reverts commit 1cb1c4baee.
2026-03-07 13:19:34 +00:00
dependabot[bot]
72e51c61f7 Bump actions/upload-artifact from 6 to 7 (#8963)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-06 22:18:54 -05:00
Sutou Kouhei
31590a8a3b Enable Dependabot for GitHub Actions (#8778)
Our workflows use old GitHub Actions. For example, we use
`actions/checkout@v3` but `actions/checkout@v5` is the latest version:

599847236c/.github/workflows/build.yml (L33)

https://github.com/actions/checkout/releases

How about enabling Dependabot? If we enable Dependabot, Dependabot
opens PRs that update old GitHub Actions.

Dependabot document:
https://docs.github.com/en/code-security/dependabot

Dependabot configuration document:
https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference
2026-03-06 22:12:18 -05:00
Felix
24c2432d99 [Python]: Modernize setup and drop Python 2 (#8955) 2026-03-06 20:49:58 +00:00
Renzo
292870612c fix(flatbuffers): use manual impl Default for struct object types (#8947)
* fix(flatbuffers): use manual impl Default for struct object types

* fix: handle bool and float zero literals in struct object Default impl

* fix: regenerate all test bindings with generate_code.py

* fix: data type check on swift build

* fix: test large array on struct and enum
2026-03-06 11:20:32 -08:00
Cameron Mulhern
57659d9f38 Updates Rust codegen to use proper indentation (#8952)
* Fixes identation of generated Rust code

* Regenerates generated schemas
2026-03-05 14:04:55 +00:00
Udaya Prakash
2b8e4d3af0 build: Upgrade rules_swift to 3.1.2 and grpc to 1.76.0 (#8909) 2026-03-05 13:26:33 +00:00
Cameron Mulhern
08b6372a36 Generate better formatted Rust code (#8919)
* Cleans up Rust formatting

* Regenerates generated schemas
2026-03-05 02:49:46 +00:00
dependabot[bot]
9c383559e0 Bump minimatch in the npm_and_yarn group across 1 directory (#8951)
Bumps the npm_and_yarn group with 1 update in the / directory: [minimatch](https://github.com/isaacs/minimatch).


Updates `minimatch` from 3.1.2 to 3.1.5
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-05 02:43:14 +00:00
Salman Chishti
c13c3bf956 Upgrade GitHub Actions for Node 24 compatibility (#8934)
Signed-off-by: Salman Muin Kayser Chishti <13schishti@gmail.com>
2026-03-04 21:36:59 -05:00
dependabot[bot]
47eeb8f4e9 Bump ajv in the npm_and_yarn group across 1 directory (#8933)
Bumps the npm_and_yarn group with 1 update in the / directory: [ajv](https://github.com/ajv-validator/ajv).


Updates `ajv` from 6.12.6 to 6.14.0
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v6.14.0)

---
updated-dependencies:
- dependency-name: ajv
  dependency-version: 6.14.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-05 02:28:53 +00:00
Uwe (ObjectBox)
e7c6874192 [Dart] Actually use resized FlexBuffers buffer (#8935)
When building a FlexBuffer using the Builder and adding data that exceeds the default buffer size (2048 bytes), in _newOffset() a larger buffer is created, but never used. This results in a RangeError.

Resolve by actually replacing the too small with the new larger buffer. Add a test that verifies this by adding multiple large strings to a vector.
2026-03-05 02:15:45 +00:00
RCRalph
8d2c333b36 fix: Added return value to non type-prefixed create vector function (#8945)
* fix: Added return value to non type-prefixed create vector function

* chore: Added generated code
2026-03-05 02:09:09 +00:00
Damian Sypniewski
abc9bfebff Update Go support for Optional Scalars (#8946) 2026-03-04 21:03:49 -05:00
Abhay Agarwal
94d6b8086b Ensure optional arrays, arrays with defaults, and strings with defaults are supported (#8896)
Fixing issues with generated ts/js
2026-02-23 08:55:37 +01:00
dependabot[bot]
fa709636b4 Bump lodash (#8913)
Bumps the npm_and_yarn group with 1 update in the /tests/ts/bazel_repository_test_dir directory: [lodash](https://github.com/lodash/lodash).


Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:development
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-19 01:09:46 +00:00
Stevan Coroller
60463e25a8 Remove empty 'required' section from schema.md (#8900)
There is a typo in the schema.md file in documentation. An empty 'required' section was added right before the 'required' item in the middle of the attributes list. It even appears in the table of content, which might confuse readers, making it look like following attributes might be required while they are not. You can notice the issue there: https://flatbuffers.dev/schema/#attributes.

I did check that `mkdocs serve -f mkdocs.yml` does produce the expected output (the same attributes list without that extra empty `required` section in the middle) with my changes.
2026-02-18 20:03:01 -05:00
Austin Chick
b8e3d215b8 [TS] Fix relative import paths of generated TypeScript code (#8880)
* Refactor logic that generates import paths in AddImport

* Add new tests to validate relative import path fix

* Generate goldens

* Generate example code

* Format TS generator file

* Revert "Format TS generator file"

This reverts commit 0f0b24aee9.

* Fix merge conflicts

---------

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
2026-02-17 10:22:32 +01:00
mustiikhalil
d71c0ab4ac Moves the internal stack to use a pointer stack instead of the native array for improved performance (#8891)
Remove custom flags for native arrays when using flexbuffers on Wasm

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2026-02-12 19:42:21 +01:00
mustiikhalil
fcf75449b8 [Swift] Moves VTs from enums to structs to prevent empty enum generation
Moves VTs from enums to structs to prevent empty enum generation, which would usually cause a compilation error.
2026-02-12 08:04:26 -10:00
Sebastian Barfurth
c21bda1649 Remove root_package from npm_translate_lock. (#8921)
This attribute is removed in the next major version of `aspect_rules_js`. It's
not actually needed here [according to](https://github.com/aspect-build/rules_js/pull/2709#issuecomment-3855183151)
a maintainer of `aspect_rules_js`.
2026-02-07 08:04:22 +00:00
Marcel
03fffb25e2 Set max_compatibility_level=3 for rules_swift (#8920)
This is necessary to be compatible with both rules_swift 2.x and 3.x.
2026-02-05 09:57:00 -08:00
bigjt
1a7495a6dd [C#] Add GetBytes methods for fixed arrays (#8633)
* [C#] Add GetBytes methods for fixed arrays

I wanted to direct access to fixed array bytes. I made some changes to the idl generator to create GetBytes functions following the same naming conventions used for vectors of scalar types. There was not a 'Length' field present to bound the existing index accessor so I added that too.

+ Add generic GetBytes for fixed length arrays of scalar types
+ Implement conditional compilation for ENABLE_SPAN_T:
  - ENABLE_SPAN_T: Returns `Span<T>` using `MemoryMarshal.Cast<byte, T>()` as needed.
  - Else: Returns `ArraySegment<byte>?` for raw byte access
+ Added tests reusing arrays_test.fbs definitions
+ Added const int Length field to support existing index based accessors

* [C#] Sync generated code for after adding GetBytes methods for fixed arrays

---------

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
2026-02-04 23:13:32 +00:00
Fawdlstty
3c1bb67ae1 sync human-readable value (#8859)
Co-authored-by: Justin Davis <jtdavis777@gmail.com>
2026-02-04 15:43:19 +00:00
Cameron Mulhern
5b9de8b6c0 Fixes Rust code generation for single file output when using namespaces (#8877)
* Adds tests for Rust single file mode

All existing tests only compile Rust code using --rust-module-root-file.

* Adds standalone include tests for Rust

The imports for these tests have been moved to their own file, as the existing intergration_test.rs file hides compilation issues from code generation due to symbols brought into scope outside of the generated code (e.g. `extern crate alloc`).

* Declare alloc crate in every Rust namespace

When performing code generation within a single file, extern crate alloc needs to be delcared to bring alloc into scope within every inner namespace.

* Regenerates generated schemas
2026-02-04 15:28:18 +00:00
Justin Davis
ea0a73d168 disallow circular struct references (#8851)
* detect and fail for circular struct dependencies

* pr comments

* pr comment
2026-02-04 15:15:05 +00:00
souma987
4623cfa4bc Opt in to using experimental Kotlin Native APIs to suppress build warnings (#8885)
- fixes #8846
2026-02-04 14:54:08 +00:00
Peter Shih
9c2c56dc6a Fix typo in comment in idl.h (#8907)
Co-authored-by: Justin Davis <jtdavis777@gmail.com>
2026-02-04 14:12:50 +00:00
brianmacy
429c28c783 fix(rust): Zero vtable memory in write_vtable to prevent uninitialized data (#8898)
The write_vtable() function's comment claimed to "fill the WIP vtable
with zeros" but make_space() only reserves memory without initializing
it. When using custom allocators with non-zeroed buffers, unset vtable
field entries would contain garbage instead of zero (which indicates
"use default value").

This fix explicitly zeros the vtable memory after reserving space,
matching the C++ implementation's buf_.fill_big() behavior.

Added regression test using a garbage-filled allocator (0xAA) that
verifies vtable entries for unset fields are properly zeroed.

Fixes #8894
2026-02-04 09:00:44 -05:00
Markus Junginger
e5a9ff757f flatbuffers.h: fix C++11 compilation (#8857) (#8858)
This constexpr officially works only with C++14 (assignment to lhs, 2 statements) and actually broke some C++11 compilers
2026-02-04 13:34:55 +00:00
Justin Davis
e53732b9b9 Feature: lua now file_ident aware (#8850)
* lua code not file ident aware

* update genned code

* make mac happy

* pr comments
2026-02-04 13:05:08 +00:00
Thiébaud Weksteen
b84b676c89 Fix example of JSON export with flatc (#8892)
Binary files should be placed after "--". Also add a note about missing
file_identifier and --raw-binary.
2026-02-04 07:51:49 -05:00
Iñaki Baz Castillo
3211f857d1 Add --ts-undefined-for-optionals command line option (#8861)
* Add --ts-undefined-for-optionals command line option

# Details

- Fixes #7656
- Added a new `--ts-undefined-for-optionals` command line option for `flatc`.
- If enabled, generated TypeScript code uses `undefined` for optional fields rather than `null`.

* Also add TS generated test files

* Run `sh scripts/clang-format-git.sh`

* also add tests/ts/lalala-options.ts to the repo

* move new tests to tests/ts/optional_values dir

* add tests/ts/optional_values/optional_values_generated.cjs to the repo

* reuse existing optional_scalars.fbs and add new test

* add comma

* sh scripts/clang-format-git.sh

* remove comma

* sh scripts/clang-format-git.sh

* trying things

* sh scripts/clang-format-git.sh

* done

* address feedback

* sh scripts/clang-format-git.sh

* run `sh scripts/clang-format-git.sh`

* remove uneeded `eslint-disable @typescript-eslint/no-namespace` line

---------

Co-authored-by: José Luis Millán <jmillan@aliax.net>
2026-02-04 13:37:41 +01:00
Stefan F.
95ff1f1d80 [c#] Fix Table __vector_as_array correct len calc (#8911)
* fix for https://github.com/google/flatbuffers/issues/8759
__vector_as_array<T> calling ByteBuffer.ToArray<T> with the length in bytes by multiplying len with ByteBuffer.Sizeof<T> and FlatBuffersExampleTests extended to call GetVectorOfLongsArray/GetVectorOfDoublesArray which failed without the fix

* first try to repair build-dotnet-windows

* syntax error fixed

* Update solution creation command in build workflow

add --format sln to the dotnet new command, maybe it is currently creating a .slnx instead?
2026-02-04 13:13:01 +01:00
Jacob Abrams
af8997b567 [Python] Improve python API (#8781)
* Fix generate_code script path

* [Python] Make StartVector public

Make StartVector vector public since it is already being used in
generated code

* [Python] Improve vector creation for Python API

Makes Python API for vectors cleaner like Rust and Swift

---------

Co-authored-by: Derek Bailey <derekbailey@google.com>
2026-01-21 01:01:20 +00:00
Derek Bailey
0d67abde45 MODULE.bazel: Upgrade rules_swift version (#8908) 2026-01-20 16:56:11 -08:00
razvanalex
d74e2945f7 [C++] Check for case insensitive keywords (#8420)
* chore(idl): Check for case insensitive keywords

Most languages are not affected by this change. In PHP, some names such
as Bool cannot be used because it is a reserved keyword for to the bool
data type. The field `keywords_casing` in the configs enables checking
all characters in lowercase against every keyword. This should be safe
as flatbuffers does not allow non-ASCII characters in its grammar.

* chore: Fix formatting to follow google's coding style for enums

* chore: Extract convert case to lower when CaseInsensitive

---------

Co-authored-by: Justin Davis <jtdavis777@gmail.com>
Co-authored-by: Derek Bailey <derekbailey@google.com>
2026-01-20 16:06:07 -08:00
Nicolas Ulrich
8914d06ab7 Remove invalid dependency on FLATBUFFERS_GENERATE_HEADERS_SCHEMAS (#8834)
* Remove invalid dependency on FLATBUFFERS_GENERATE_HEADERS_SCHEMAS

add_dependencies() is for targets.

CMake 4.2.0 fails because of this (it shouldn't crash though, but that's another topic). See https://gitlab.kitware.com/cmake/cmake/-/issues/27415

* Use FLATC_TARGET

---------

Co-authored-by: Justin Davis <jtdavis777@gmail.com>
2025-12-22 02:25:14 +00:00
Derek Bailey
522f2379a6 Update CODEOWNERS 2025-12-21 16:10:34 -08:00
Justin Davis
7cb0bcb212 C++ Feature: Mutable union getters (#8852)
* generate mutable union accessors

* add test

* Revert "add test"

This reverts commit 45e352b18f.

* update file

* formatter got in the way

* merge conflicts

* updated genned code

* manually fix code gen bc I can't figure out why this file won't code gen

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-12-21 17:36:47 -05:00
Justin Davis
b1e7868db6 add verification that type_vec.size == vec.size() (#8853)
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-12-21 21:55:54 +00:00
Justin Davis
68e3c839c3 update provenance (#8873) 2025-12-21 21:50:57 +00:00
mustiikhalil
0723245085 [Swift] Fixes bazel.build file allowing it to find Vectors folder in 8.5.0 (#8875) 2025-12-21 21:22:49 +00:00
Ville Vesilehto
9d64b9c0c0 fix(go): add bounds checking to ByteVector (#8776)
Add missing bounds checking to ByteVector before slice
operations in the Go FlatBuffers implementation. Relative offset and
vector length are now checked against the buffer size. Instead of
panicking, the code now returns nil. Regression test added.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
Co-authored-by: Justin Davis <jtdavis777@gmail.com>
2025-12-21 20:25:30 +00:00
Justin Davis
d01f20f2fb Fix python generation with nested flatbuffers (#8854)
* implement fix from issue

* implement actual fix
2025-12-21 11:18:05 -08:00
Derek Bailey
7e163021e5 FlatBuffers Version 25.12.19 (#8871) 2025-12-19 15:06:07 -08:00
Derek Bailey
57fdd4f995 Default Vector Support C++ (#8870) 2025-12-19 14:32:51 -08:00
Derek Bailey
8cb53ccc95 Add --gen-absl-hash option to generate AbslHashValue for structs. (#8868) 2025-12-19 11:49:50 -08:00
Derek Bailey
fb55e0c9de Run clang-format -i **/*.cpp (#8865) 2025-12-19 10:42:57 -08:00
Derek Bailey
d9fde67eb5 Remove progaurd-rules.pro (#8866) 2025-12-19 09:54:43 -08:00
Derek Bailey
f74fda299d Update CODEOWNERS
Ensure no-one can add to owners other than myself as the official Google representative of this repo.
2025-12-18 17:14:33 -08:00
Derek Bailey
15802fa26c Create CODEOWNERS
Add a CODEOWNERS files to assign ownership to different parts of the code base
2025-12-18 17:03:50 -08:00
souma987
a86afae939 Fix casing in generated Kotlin struct constructor function (#8849)
* fixes #8419
2025-12-14 23:59:17 +00:00
souma987
60910fb7f5 Fix nullability of generated Kotlin ByteBuffer accessors (#8844)
* fixes #8691
2025-12-14 18:56:40 -05:00
Justin Davis
7bfaabc358 [TS] Flexbuffers root vector fix (#8847)
* fix and test

* chatgpt help

* consistent throws in reference.ts
2025-12-14 22:59:27 +01:00
Justin Davis
e1407e4341 Upgrade Kotlin to MacOS 15 (#8845)
* upgrade kotlin and macos

* remove xcode version selection
2025-12-14 13:28:24 -05:00
Justin Davis
c9a301e601 Arrays of Enumerations without a value for 0 are no longer valid (#8836)
* arrays of enums with no value for 0 now throw errors

* move setting key field outside struct check

* set to default instead of required

* unsure of why these bfbs files have changed at this time, checking them in to run the pipelines.

* remove known bad test
2025-12-13 18:40:58 -05:00
James Thompson
19b2300f93 chore: switch package to license expression (#8840)
* switch package to license expression

* Remove license file from package
2025-12-10 09:50:50 -05:00
Justin Davis
e60c0ab9e2 deprecate the two options which have no effect of their own (#8831) 2025-12-08 06:03:11 -05:00
Justin Davis
541dd1a8f5 Fix vector of table with naked ptr (#8830)
* create test that fails to compile

* fix the issue

* add test body

* force commit gneerated header

* build failures

* fix bazel some more
2025-12-07 11:05:54 -08:00
Justin Davis
7711e84919 Fix TS object API generation of schema containing array of enumeration having no zero default (#8832)
* set the array constructor to fill with minvalue

* add regression generation test
2025-12-07 07:35:38 -05:00
Kende Gömöri
89430a14d6 Fix docs: typo & dead link (#8826)
* Fix CHANGELOG.md

* Fix broken doc link
2025-12-05 20:31:04 -05:00
Cameron Mulhern
cfce38ec99 Fixes unused imports in Rust code generator (#8828)
* Fixes unused imports in Rust code generator

* Regenerates generated schemas
2025-12-04 21:59:47 -08:00
Justin Davis
5469bc9ef1 Update flatc.md (#8821) 2025-12-03 14:16:59 +01:00
Ky0toFu
b39f79e5e9 Fix(ts): escape doc comment terminator in generated JSDoc (#8820) 2025-12-03 12:26:13 +00:00
Justin Davis
dc623919bd update docs (#8819)
Fixes #8733
2025-12-03 07:31:49 +01:00
Justin Davis
a1e125af11 Implement --file-names-only (#8788)
* flatc builds and seems to work, some of the extra targets are having linker errors

* fix build system

* pipeline failures

* un-rename files

* refactor to use unique_ptr

* typo

* rm make_unique, add comments

* fix cmake

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-12-03 04:37:06 +00:00
Richard Patel
0b60686e3d rust: impl TrustedLen for VectorIter (#8797)
Improves unpack performance for vectors by allowing the compiler
to vectorize flatbuffers::Vector to std::vec::Vec conversions,
using the unstable trusted_len feature.

Internally, enables an optimization in src/alloc/vec/spec_extend.rs:
Previously, unpacking a flatbuffers::Vector called
SpecExtend::extend_desugared fallback, which inhibits vectorization
(due to a branch before every element move).  Declaring TrustedLen
allows SpecExtend::extend_trusted, which LLVM can often vectorize
into a memcpy.

For [ubyte] vectors in particular, this turns a rather expensive
loop of 'mov BYTE PTR [rax+r13*1], bpl' into a `call memcpy`.
2025-12-03 04:21:16 +00:00
Fawdlstty
17ceaae16e [rust] add deser support for enum type (#8803)
* add deser support for enum type

* update generated files

* remove deser generator when bitflag enable

* add deser test

* Restore the Rust editions version

* Remove unnecessary modifications
2025-12-02 22:48:45 -05:00
Rob Jellinghaus
a5343d6116 fix(idl_gen_rust): Fix lifetime warning added in Rust 1.89 (#8709)
Rust 1.89 added a new lifetime-related warning:
<https://blog.rust-lang.org/2025/08/07/Rust-1.89.0/#mismatched-lifetime-syntaxes-lint>

The Rust code generator currently emits code which trips this warning. This very small PR
fixes the issue for the relevant generated functions and for the Rust flexbuffers code.

Fixes #8705
2025-12-02 22:27:40 -05:00
Justin Davis
4786322b90 update labeler.yml to v5+ format (#8818) 2025-12-02 21:21:25 -05:00
Cameron Mulhern
646a8bc96a Improves Rust code generation (#8564)
* Fixes checks for serde features in flexbuffers crate

* Removes unused MapReaderIndexer use statement

* Fixes warning about nightly cfg usage

Enabling a cfg attribute through cargo::rustc-cfg in build.rs should be coupled with a cargo::rust-check-cfg value so that the compiler knows about the custom cfg. See: https://doc.rust-lang.org/rustc/check-cfg/cargo-specifics.html#cargorustc-check-cfg-for-buildrsbuild-script.

* Migrates usage of deprecated float constants

This update fixes a compiler warning from use of the old constants.

Constants like EPSILON are now directly on the float primitives (e.g. f32::EPSILON) rather than in the f32 module (std::f32::EPSILON).

The new constants have existed since 1.43.0, which appears to be below the MSRV for the flatbuffers crate.

* Fixes incorrect key in flatbuffers Cargo.toml

The old code was using package.rust, which triggered a warning about an unused key:

warning: flatbuffers/rust/flatbuffers/Cargo.toml: unused manifest key: package.rust

The correct key for specifying MSRV is rust-version. See: https://doc.rust-lang.org/cargo/reference/rust-version.html#rust-version.

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-12-02 18:06:24 -08:00
Felix
0e3471d6a7 WIP error messages (#8764)
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-12-02 17:52:30 -08:00
Felix
b07589a0f9 CI: Fix typo in version (#8817) 2025-12-02 16:14:43 -05:00
mustiikhalil
2062c33cd4 Add support for Flexbuffers in wasm (#8815) 2025-12-02 16:18:24 +01:00
Felix
adb7add87e Modernize GitHub CI actions (#8812)
* CI: Modernize actions/checkout

* CI: Modernize actions/stale

* CI: Modernize softprops/action-gh-release

* CI: Modernize microsoft/setup-msbuild

* CI: Modernize gradle/actions/setup-gradle

* CI: Modernize actions/setup-dotnet

* CI: Modernize actions/setup-java

* CI: Modernize jiro4989/setup-nim-action

* CI: Update to latest image seems to be fixed

The readme list swift now for 24.04

* CI: Update to latest actions/labeler tag instead of sha
2025-12-02 10:11:55 -05:00
mustiikhalil
29f99937c4 Migrating to swift wasm on for github actions (#8814)
Migrate to use the native SDK for Wasm that's built for swift
2025-12-02 02:13:22 +01:00
Jacob Abrams
597e76a268 Optimize Offset/Pad/Prep: use cached head and slicing, reduce casting (#8808) 2025-12-01 19:00:20 -05:00
Wakahisa
a577050817 [Java] Use Table's fully qualified path (#8729)
* [Java] Use Table's fully qualified path

When a table's name is called `Table`, the Java bindings generated result in an error due to there being  2 Tables. This fixes the issue by fully qualifyng the flatbuffers Table import.

* Update codegen

* Update generated Java code

---------

Co-authored-by: Neville Dipale <neville@urbanlogiq.com>
2025-12-01 11:28:50 -05:00
razvanalex
31ab0bf6c8 [Go] Write required string fields into the buffer when using Object API (#8402)
* [Go] Write required string fields into the buffer when using Object API

In C++, CreateX allows to write the default "" value of a required
string, when the string is not explicitly set. Object API Pack method
uses this implementation of CreateX.

However, in go, despite whether the field is optional or required, it is
always checked against empty string allowing to create messages that
fail to pass the verifier. This commits partially reverts #7719 when the
string field is required.

* Add test for serializing required string fields using Object API

* Update generated code

The Monster schema contains a key string field. For historical
convenience reasons, string keys are assumed required.
2025-12-01 09:50:03 -05:00
Jeroen Demeyer
e4775aa3fe [Go] add BenchmarkBuildAllocations (#8287) 2025-11-30 22:12:12 -05:00
whiteye
97d26ab4ae fix CScript string.compare (#8547)
* fix CScript string.compare

Because the default compare sorting rules of c# string are different from those of cpp, the binary file exported by flatc -b cannot use LookupByKey

* run generate_code.py

---------
2025-11-30 22:06:41 -05:00
James Robinson
7dd38fa23a Fix platform ifdefs for locale independent str functions (#8678)
Android libraries include <android/api-level.h> which defines the __ANDROID_API__ symbol even when targeting non-Android platforms and not using Android's libc. This updates the FLATBUFFERS_LOCALE_INDEPENDENT ifdef to check for __ANDROID__ before checking the Android API level.

Removes an extra check from the __Fuchsia__ branch. Fuchsia's libc does not support locales or the locale independent entry points.

Updates the Android API check to check for an API level >= 26 instead of 21. This matches the Android header file's availability macros and Bionic documentation:

https://android.googlesource.com/platform/bionic/+/HEAD/docs/status.md
2025-11-30 21:38:37 -05:00
Jacob Abrams
7350c3668f Optimize Builder startup: lazy sharedStrings and fast vtable init (#8807) 2025-11-30 23:33:34 +00:00
Felix
49d2db93a7 [Python] Fix generating __init__.py for invalid path (#8810)
This tried to generate from a directories "MyGame/Sample/"
for a empty path_ in M, MyGame & MyGame/Sample.
Which is incorrect since we want to start with the first
kPathSeparator `/` and not position 1.
2025-11-30 23:30:55 +00:00
Uilian Ries
807b43c0d7 Remove legacy Conan recipe and update documentation (#8712)
* Remove legacy Conan recipe

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* Document how to install flatbuffers with Conan

Signed-off-by: Uilian Ries <uilianries@gmail.com>

---------

Signed-off-by: Uilian Ries <uilianries@gmail.com>
Co-authored-by: Justin Davis <jtdavis777@gmail.com>
2025-11-30 11:35:02 +00:00
peter-soos
4b823b1b98 [Python] Fix inconsistent creator function naming in generated code (#8791) (#8792) 2025-11-29 16:48:53 -05:00
mustiikhalil
4c47f4c11e Revert back to using swift-actions (#8806)
Reverting to swift-actions since they seem to have fixed the issue with GPG keys
2025-11-27 21:56:20 -05:00
coder7695
2b107e20c5 [fuzzer] Adds code generation target. (#8795)
* adds code generation fuzzer target.

* add buffer verification

* add table verification in codegen fuzzer

---------

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
2025-11-27 15:52:28 +00:00
Jacob Bandes-Storch
84f4b83d3e TypeScript: read vtable entries as uint16 (#8435)
Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
2025-11-27 10:55:34 +00:00
dependabot[bot]
185e41fac4 Bump js-yaml in the npm_and_yarn group across 1 directory (#8779)
Bumps the npm_and_yarn group with 1 update in the / directory: [js-yaml](https://github.com/nodeca/js-yaml).


Updates `js-yaml` from 4.1.0 to 4.1.1
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/compare/4.1.0...4.1.1)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.1.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
2025-11-27 11:50:31 +01:00
Grzegorz Owsiany
8b02fe6178 [C++] Fix vtable deduplication for 64-bit buffers >2GB (#8591)
Fixes #8590
2025-11-26 21:12:24 -05:00
Sutou Kouhei
6e0dad8c5f Use macos-15-intel not macos-latest-large for Intel macOS (#8777)
We can't use macos-latest-large in non paid GitHub account but we can
use macos-15-intel in public repositories. If we use macos-15-intel,
we can run CI jobs for Intel macOS in fork repositories.
2025-11-26 19:31:24 -05:00
obones
e3e355d498 feat: library definition for PlatformIO (#8261)
* feat: library definition for PlatformIO

* Update library.json version with release.sh

---------

Co-authored-by: Flávio Zanoni <flaviozg888@gmail.com>
2025-11-26 19:18:13 -05:00
Jakob Kordež
8e901ce17c Fix dart object api test (#8751) 2025-11-26 17:36:08 -05:00
Yuanyuan Chen
7808ae5c88 More robust <span> check (#8631) 2025-11-26 17:33:06 -05:00
Wakahisa
20068cfa05 [Java] Add notify to Java keywords (#8724)
Fixes #8723

Co-authored-by: Neville Dipale <neville@urbanlogiq.com>
Co-authored-by: Max Burke <max@urbanlogiq.com>
2025-11-26 07:59:18 -08:00
Wakahisa
afd07bdec5 [Java] Generate Longs from uint enums (#8727)
Co-authored-by: Neville Dipale <neville@urbanlogiq.com>
Co-authored-by: Max Burke <max@urbanlogiq.com>
2025-11-26 07:58:25 -08:00
Hjalti Leifsson
2951d5383a chore: fix quick start typos (#8520)
* chore: fix another typo

* chore: undo overzealous IDE changes
2025-11-25 16:24:23 -05:00
Glenn Fiedler
ba563de877 add assert to fix GCC warning on Ubuntu 24.04 LTS (#8804) 2025-11-25 14:08:51 -05:00
Fawdlstty
46a2f3f2c2 [dart] fix bug which generated wrong code (#8780) 2025-11-24 10:54:43 -05:00
Ivan Dlugos
7675121eab Add Dart changelog entry for v25.9.23 (#8785)
Documents changes included in the Dart package v25.9.23 release,
which was published to pub.dev.
2025-11-24 09:18:23 -05:00
Benjamin Kietzman
ea2b5148e5 Fix issue #8389: any nonzero byte is truthy (#8690) 2025-11-24 07:26:39 -05:00
Fergus Henderson
20548ff3b6 Size verifier fix 2 (#8740)
* Fixes to make SizeVerifier work.

In particular change all the places in the Flatbuffers library
and generated code that were using `Verifier` to instead use
`VerifierTemplate<TrackBufferSize>` and wrap them all inside
`template <bool TrackBufferSize = false>`.

Also add unit tests for SizeVerifier.

* Format using `sh scripts/clang-format-git.sh`

* Use `B` rather than `TrackBufferSize` for the name of the template parameter.

* Update generated files.
2025-11-24 07:11:32 -05:00
Jacob Abrams
7ea8db05d8 [Python] Add unit test for github issue 8653 (#8786) 2025-11-24 06:41:50 -05:00
Justin Davis
c7b6b66ccb fix: remove a single type hint to retain 2.7.x compatibility (#8799)
Co-authored-by: Hjalti Leifsson <hjaltileifsson@gmail.com>
2025-11-23 12:00:21 -08:00
Justin Davis
ac8b124496 don't crash on a lua file with no root table (#8770)
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-11-17 22:31:32 +00:00
Justin Davis
88b033b964 add proposed fixes from #8731 (#8771)
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-11-17 13:46:41 -08:00
Justin Davis
e68355cb22 [C++] Add Vector64 specialization for std::vector<bool> (#8757)
* add vector64 specialization for vector<bool>

* fix generated code

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-11-17 13:44:28 -08:00
Justin Davis
e3ee24830e Fix Issue #8653 - Python vtables not considering object size (#8683)
* have vtables consider size

* simplification from comment

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-11-17 13:43:28 -08:00
Felix
2a8f4568e0 Replace usage of make_unique with unique_ptr for cpp11 (#8763) 2025-11-17 13:42:06 -08:00
mustiikhalil
cbf0850828 [Swift] Inline arrays (#8755)
Implements InlineArrays which allow us to use Flatbuffers arrays within
Structs natively, and also implements FlatbufferVectors as a secondary API
when using mutable Structs

Fixes mutations within fixed sizes arrays

Adds tests and remove inout and mutating from generated objects in favor of borrowing

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-11-15 00:33:16 +01:00
mustiikhalil
7150dfb5c4 [Swift] Bump minimum supported version of swift to 5.10 (#8758) 2025-11-14 15:07:49 -08:00
mustiikhalil
fa87eccd1a Update swift supported features (#8769) 2025-11-14 15:07:25 -08:00
mustiikhalil
a62f45fed8 Improves the performance of the string imp (#8772)
Improves the performance of the implementation in Swift
by using withCString instead of the contigiousString
2025-11-14 15:06:52 -08:00
cosmith-nvidia
599847236c Support native_type for tables when using the C++ object API. (#8668)
* Support native_type for tables when using the C++ object API.

If native_type is specified on a table:
- No object API struct type is generated.
- The object API refers to the table by its native_type.
- UnPack and Create<TableName> methods are declared but not defined; as they
  must be user-provided.

* Add tests for native_type on tables.

* Add documentation for native_type on tables.
2025-11-05 07:50:10 -08:00
cosmith-nvidia
4173b84d4b Fix --gen-compare to not generate comparators for native types. (#8681)
Per the definition of --gen-compare: only generate comparators for object API
generated structs. Types annoated with native_type must define their own
comparators if `--gen-compare` is enabled.

Also enables --gen-compare for native_type_test and fixes the test by adding a
comparator for the Native::Vector3D type.
2025-11-05 00:43:00 +00:00
mustiikhalil
5fe90a9160 [Swift] Implements FlatbuffersVector which confirms to RandomAccessCollection (#8752)
* Implements FlatbuffersVector in swift

Implements FlatbuffersVector which confirms to RandomAccessCollection,
this would give us semi-native sugary syntax to all the arrays in swift port.

This work will also be the foundation of using arrays in swift

* Fix failing tests for Swift
2025-11-04 23:53:59 +00:00
cosmith-nvidia
78a3d59a65 Swap the dependency of CreateX and X::Pack object API functions. (#8754)
Previously: X::Pack forwarded to CreateX.

Now: CreateX will forward to X::Pack.

This is a step toward enabling using native types for tables when using the
object API. When defining a native table, the user will be able to define a
custom X::Pack method (which is more consistent with the existing native_type
functionality for structs). By reversing the order of the dependencies, CreateX
can continue to be auto-generated and will use the custom X::Pack method when
overriden for native_type tables.
2025-11-04 15:42:16 -08:00
are-you-tilted-already
5ed02dc04a Prevent make_span from working with vectors and arrays of pointers (#8735)
* Prevent `make_span` from working with vectors and arrays of pointers

* support `make_structs_span` for little-endian

* fix build: add the required parentheses

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-11-04 13:47:44 -08:00
Jakob Kordež
592dc50037 Refactor lazy list unpacking (#8746)
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-10-31 13:41:59 -07:00
coder7695
dd77af75b7 Add conditional check (#8736)
* resolve windows compile error

* add conditional for undef new

---------

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-10-31 11:20:18 -07:00
Jakob Kordež
051604aeb5 Fix struct vector ordering in pack function (#8747) 2025-10-31 09:59:01 -07:00
Jakob Kordež
4b09586652 Fix union unpacking (#8748) 2025-10-31 09:58:30 -07:00
David Sanderson
4c0eecd25a treat npm_typescript as a dev dependency (#8719)
Treat flatbuffers' definition of npm_typescript as a dev dependency, in order to avoid conflicts when consuming flatbuffers in a repo that also depends on aspect_rules_ts.
2025-10-30 07:49:54 -07:00
mustiikhalil
de25052c72 Fixes failing tests on macOS due to file loading (#8742)
Fixes failing tests due to the usage of URL(fileURLWithPath:isDirectory:) instead of URL(string:)
2025-10-29 11:36:47 -07:00
vsmcea
95053e6a47 Correct span and non-span versions of ToArray() and ToArrayPadded() methods (#8734)
* Correction of bug inside ToArray<T> methods

Avoid allocating too large buffers (len is expressed in bytes, not in Ts).
Added validation to ensure len is a multiple of SizeOf<T>() before converting to array.

* Update ByteBuffer.cs

* Refactor ToArray and ToArrayPadded methods

I understand from failed test that pos, len, padLeft and padRight are expressed in Ts

* Refactor ToArray and ToArrayPadded methods

* Final correction
All functions parameters expressed in bytes for homogeneity
Tests run:
  - UNSAFE_BYTEBUFFER=true/ENABLE_SPAN_T=true: passed
  - UNSAFE_BYTEBUFFER=true/ENABLE_SPAN_T=false: passed
  - UNSAFE_BYTEBUFFER=false/ENABLE_SPAN_T=false: passed
  - UNSAFE_BYTEBUFFER=false/ENABLE_SPAN_T=true: configuration forbidden by compilation
Correction of FlatBuffers.Test.csproj to allow UNSAFE_BYTEBUFFER/ENABLE_SPAN_T tests
Correction of FlatBuffersExampleTests.cs: I think the test was not run because it could not pass (to be reviewed carefully)
2025-10-25 11:58:05 -07:00
Daniel Nguyen
27325e002a docs: clean up whitespace and fix typo in tutorial.md (#8695)
* docs: remove trailing whitespace

* docs: fix typo in tutorial.md
2025-09-25 09:02:22 -07:00
Derek Bailey
1872409707 FlatBuffers Version 25.9.23 (#8708) 2025-09-23 22:18:02 -07:00
dependabot[bot]
c427e1a65d Bump the npm_and_yarn group across 1 directory with 2 updates (#8704)
Bumps the npm_and_yarn group with 2 updates in the / directory: [@eslint/plugin-kit](https://github.com/eslint/rewrite/tree/HEAD/packages/plugin-kit) and [brace-expansion](https://github.com/juliangruber/brace-expansion).


Updates `@eslint/plugin-kit` from 0.3.2 to 0.3.5
- [Release notes](https://github.com/eslint/rewrite/releases)
- [Changelog](https://github.com/eslint/rewrite/blob/main/packages/plugin-kit/CHANGELOG.md)
- [Commits](https://github.com/eslint/rewrite/commits/plugin-kit-v0.3.5/packages/plugin-kit)

Updates `brace-expansion` from 1.1.11 to 1.1.12
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/1.1.11...v1.1.12)

---
updated-dependencies:
- dependency-name: "@eslint/plugin-kit"
  dependency-version: 0.3.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: brace-expansion
  dependency-version: 1.1.12
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Derek Bailey <derekbailey@google.com>
2025-09-23 21:54:56 -07:00
Derek Bailey
caf3b494db bulk code format fix (#8707) 2025-09-23 21:50:27 -07:00
Derek Bailey
0e047869da Use the Google Style for clang-format without exceptions (#8706)
This reduces the friction when merging from github and google repos by
using the exact same clang style guide.

MARKDOWN=true
2025-09-23 21:19:33 -07:00
mustiikhalil
881eaab706 Revert back to use the latest from the swiftly ci (#8702) 2025-09-21 21:47:05 -07:00
nurbo
48eccb83db fix(idl_gen_ts): bool to number conversion in mutable API (#8677)
Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
2025-09-11 08:36:15 -07:00
Peter Petrov
3c0511fa6a [C#] Added ToSizedArrayPadded(int padLeft, int padRight) to ByteBuffers to avoid unnecessary copying. (#8658)
* Added ToSizedArrayPadded(int padLeft, int padRight) + ToArrayPadded(pos, len, padLeft, padRight) to the byteBuffers.
This is for API completion and to avoid unnecessary copy when framing my packets. I needed this to create a flat buffer with space in front of it for header / metadata.

* Fix indentation

---------

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-09-09 11:38:15 -07:00
bigjt
82396fa0fe [C#] Improve Span<> utilization (#8588)
There are a couple instances where the ByteBuffer's Span property was accessed in a loop.
 + Extracted the use of the property outside of the loop to save a few cpu cycles.

Access to the allocator's internal buffer isn't exposed as a ReadOnlySpan<byte> from the ByteBuffer
or the FlatBufferBuilder.
 + Added a few convenience functions to access the buffer using a ReadOnlySpan<byte>.

There are a few cases where built in Span extensions can be used to run optimized code.
 + Added the use of Span.Fill() and ReadOnlySpan.SequenceCompareTo to replace existing loops.

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-08-28 16:06:18 -07:00
Curt Hagenlocher
a6b337f803 Add bounds checking to a method where it was missing (#8673)
Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-08-28 16:06:03 -07:00
TorsteinTenstadNorsonic
35230bd70c [C#] Fix union verifier (#8593)
* [C#] Add test verifying unions

* [C#] Fix verifying unions

---------

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-08-28 16:05:42 -07:00
Shashank
deb3d93454 gRPC callbackService support added (#8666)
* grpc callbackService support added

Signed-off-by: shankeleven <shashanksati11@gmail.com>

* tests: regenerate C++ gRPC golden with --grpc-callback-api (CallbackService & async_ reactor APIs); update formatting and method placement

---------

Signed-off-by: shankeleven <shashanksati11@gmail.com>
Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-08-28 15:49:27 -07:00
Felix
b87d04af8c Bugfix: grpc supress incorrect warning (#8669)
new_p is a local addr but is owned now by slice_
thus the life time does not end at the end of the function

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-08-28 14:27:31 -07:00
Ville Vesilehto
1e6c851dba fix(go/grpc): avoid panic on short FlatBuffers input (#8684)
* fix(go/grpc): avoid panic on short FlatBuffers input

The gRPC codec read the root UOffsetT without checking input size. On
buffers shorter than SizeUOffsetT, GetUint32 touched data[3] and the
process panics.

Add a simple length check and validate the root offset stays within the
buffer. Return clear errors (insufficient data / invalid root offset)
instead of panicking.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>

* fix(go/grpc): avoid signed overflow in offset

Keep the bounds check in the unsigned domain (UOffsetT) to avoid
signedness pitfalls.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>

* chore: clarify comment regarding offset

A full FlatBuffer structure would be:

- uoffset_t: root table offset (4 bytes)
- soffset_t: vtable offset in root table (4 bytes)
- uint16_t: vtable size (2 bytes)
- uint16_t: table size (2 bytes)

In total 12 bytes. We are only validating the data length
before trying to read the uoffset_t, not the full structure.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>

---------

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
Co-authored-by: Derek Bailey <derekbailey@google.com>
2025-08-28 00:31:57 -07:00
mustiikhalil
6164edf558 Fixes swift windows CI (#8685)
Fixes ci failing to a missing component on the github actions side, and
this is enabled until its fixed from the swiftlylab side

Enables swift ci
2025-08-27 23:49:50 -07:00
Derek Bailey
ef1030ff0b Update build.yml - disable gradle CI failures
Both of this are failing and blocking other non-related PRs, disabling for now.
2025-08-27 23:22:12 -07:00
Derek Bailey
53c8c2ef16 Update build.yml - disable Test Swift Windows
This continually fails and the error message is cryptic enough that I don't know how to fix it without an expert.
2025-08-27 23:11:24 -07:00
Derek Bailey
f83525fe67 Update build.yml - update gradle actions
This follows the recommendation here: https://github.com/gradle/actions/blob/main/docs/setup-gradle.md#general-usage
2025-08-27 22:55:17 -07:00
Derek Bailey
b2cce474ba Update build.yml - use java-version 21
Our CI is broken and this is the error:

```
FAILURE: Build failed with an exception.

* What went wrong:
Gradle requires JVM 17 or later to run. Your build is currently configured to use JVM 11.
```

So updating our java-versions to the latest stable version which is 21 apparently.
2025-08-27 22:41:07 -07:00
Jason
067bfdbde9 Update ts codegen (#8421)
Makes the return type of `static getFullyQualifiedName()` be a string literal instead of just the string type

Update tests

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
2025-08-17 20:19:08 -07:00
Justin Davis
5218e29aa4 Fix: Actually call ValidateOptions (#8665)
* fix: actually call ValidateOptions

* convert error to warning in validateoptions
2025-08-12 15:30:35 -07:00
vzjc
957e09d684 CMakeLists: include(CheckSymbolExists) so check_symbol_exists() will work (#8580)
CMake 3.6 and earlier included this implicitly. Newer versions require
it to be explicit.

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-08-11 23:11:14 -07:00
Chan Wang
af4b99a1d7 Add Rust reflection documentation (#8536)
* Add Rust reflection documentation

* Update rust.md
2025-08-08 10:18:17 -07:00
Isaiah Pettingill
b85b90e346 Fix typo in word JavaScript (#8530)
Noticed this on the site. I'm not sure if you have to change it anywhere else, but this looks like the only place the typo occurs
2025-08-08 10:16:52 -07:00
Nugine
ae3821233c docs: fix broken link in readme (#8656) 2025-08-06 22:06:44 -07:00
Felix
ff9cba2bff Doc fix verifier example code for cpp (#8664) 2025-08-06 13:53:44 -07:00
Felix
1759061908 Remove stray required in docs (#8663) 2025-08-06 13:52:57 -07:00
Sourya Kovvali
34af7fff70 Fix native_type non-native_inline fields, add tests (#8655)
* Fix native_type non-native_inline fields, add tests

* Format

* Add 'native_type_test' and 'native_inline_table_test' to generate_code.py

* Remove '--gen-compare' from native_type_test generation
2025-08-03 15:06:01 -07:00
mustiikhalil
518bf42df8 Fixes misaligned pointer by reading from the buffer instead of loading the memory separately (#8649) 2025-07-29 21:26:30 +00:00
mustiikhalil
575d616e60 [Swift] Moves capacity outside of Storage (#8650)
- Cleans up capacity usage within the lib and moves it outside of the Storage

-  Use overflow operators
2025-07-29 14:21:20 -07:00
Felix
f32a7dcbd2 Bugfix __eq__ for numpy data types (#8646)
* [Python] Sync PythonTest.sh flags with generate_code.py

* [Python] Update generated code to latest flatc version for tests

* [Python] Fix test support for numpy newer than 2.0.0

* [Python] Remove unused variable

* [Python] Fix __eq__ for numpy arrays

* [Python] Run clang-format over the entire file
2025-07-26 10:31:38 -07:00
Alex Băluț
860d645349 Support Rust edition 2024 (#8638)
* Developers intro how to contribute

* Fix Rust code generation for Rust edition 2024

The errors look like:

```
warning[E0133]: call to unsafe function `fbs::flatbuffers::emplace_scalar` is unsafe and requires unsafe block
warning[E0133]: call to unsafe function `fbs::flatbuffers::follow_cast_ref` is unsafe and requires unsafe block
warning[E0133]: call to unsafe function `fbs::flatbuffers::Follow::follow` is unsafe and requires unsafe block
warning[E0133]: call to unsafe function `fbs::flatbuffers::read_scalar_at` is unsafe and requires unsafe block
warning[E0133]: call to unsafe function `fbs::flatbuffers::root_unchecked` is unsafe and requires unsafe block
warning[E0133]: call to unsafe function `fbs::flatbuffers::size_prefixed_root_unchecked` is unsafe and requires unsafe block
warning[E0133]: call to unsafe function `fbs::flatbuffers::Table::<'a>::new` is unsafe and requires unsafe block
warning[E0133]: call to unsafe function `std::slice::from_raw_parts` is unsafe and requires unsafe block
```

* Update goldens

Ran `goldens/generate_goldens.py`

* Regenerate code files

Ran `scripts/generate_code.py`
2025-07-25 23:12:52 +00:00
Felix
06a53df0d3 Fix start page: Backwards and Forwards Compatibility (#8645) 2025-07-25 16:06:50 -07:00
Łukasz Kurowski
c526cb640b [Python] Enhance object API __init__ with typed keyword arguments (#8615)
This commit significantly improves the developer experience for the Python Object-Based API by overhauling the generated `__init__` method for `T`-suffixed classes.

Previously, `T` objects had to be instantiated with an empty constructor, and their fields had to be populated manually one by one. This was verbose and not idiomatic Python.

This change modifies the Python code generator (`GenInitialize`) to produce `__init__` methods that are:

1.  **Keyword-Argument-Friendly**: The constructor now accepts all table/struct fields as keyword arguments, allowing for concise, single-line object creation.

2.  **Fully Typed**: The signature of the `__init__` method is now annotated with Python type hints. This provides immediate benefits for static analysis tools (like Mypy) and IDEs, enabling better autocompletion and type checking.

3.  **Correctly Optional**: The generator now correctly wraps types in `Optional[...]` if their default value is `None`. This applies to strings, vectors, and other nullable fields, ensuring strict type safety.

The new approach remains **fully backward-compatible**, as all arguments have default values. Existing code that uses the empty constructor will continue to work without modification.

#### Example of a Generated `__init__`

**Before:**

```python
class KeyValueT(object):
    def __init__(self):
        self.key = None  # type: str
        self.value = None  # type: str
```

**After:**

```python
class KeyValueT(object):
    def __init__(self, key: Optional[str] = None, value: Optional[str] = None):
        self.key = key
        self.value = value
```

#### Example of User Code

**Before:**

```python
# Old, verbose way
kv = KeyValueT()
kv.key = "instrument"
kv.value = "EUR/USD"
```

**After:**

```python
# New, Pythonic way
kv = KeyValueT(key="instrument", value="EUR/USD")
```
2025-07-22 23:57:39 -07:00
mustiikhalil
ca73ff34b7 [Swift] Memory usage fix (#8643)
Allows a complete reset for the underlying memory of the
_InternalByteBuffers within FlatBuffers and FlexBuffers.
2025-07-18 09:37:58 -07:00
Rogério Lino
2e49b3ba60 docs: Fixing typo on PHP sample (#8566) 2025-07-17 19:42:14 +00:00
Felix
f830c47d68 [Python] Avoid double flatbuffers include in pyi files (#8626) 2025-07-17 12:37:19 -07:00
Emma
501810f4d1 Fix JavaScript typo in mkdocs.yml (#8515) 2025-07-17 17:53:12 +00:00
Felix
1047d7ec13 Fix Enum type definition (#8624)
Using the : syntax leads to non member attributes.

> If an attribute is defined in the class body with a type annotation
> but with no assigned value, a type checker should assume this is a non-member attribute

```
class Pet(Enum):
    genus: str  # Non-member attribute
    species: str  # Non-member attribute

    CAT = 1  # Member attribute
    DOG = 2  # Member attribute
```

https://typing.python.org/en/latest/spec/enums.html#defining-members
2025-07-16 12:22:45 -07:00
mustiikhalil
07c2eb5fe7 Moves away from @_exported import to add the import in the generated code (#8637) 2025-07-16 12:07:08 -07:00
Felix
c7b9dc83f5 [Python] Avoid include own type (#8625)
This prevents the include of the type defined in the pyi,
otherwise this leads to error message like this:
error: Name XYZ already defined (possibly by an import)  [no-redef]
2025-07-15 11:20:09 -07:00
Gio
4c9079e31b Update logo path (#8602) 2025-07-14 16:09:05 -07:00
Felix
64e5252b4e Fix typo in code comment (#8549) 2025-07-07 12:03:14 -07:00
Dylan Gallagher
00c30807ff Fixed typo in quick_start.md (#8592) 2025-07-07 12:02:40 -07:00
Felix
c15fe421ba Use correct default type for str (#8623)
* [Python] Use correct type for str with None

Otherwise mypy will correctly flag code like this

def __init__(self):
  self.fooBar = None  # type: Optional[str]

error: Incompatible types in assignment (expression has type "None", variable has type "str")

* [Python] Make list type optional as they can contain None
2025-07-04 23:47:36 +00:00
Felix
6b251aa1cf Bugfix/new decode flag (#8634)
* Add docs for new python-decode-obj-api-strings flag

* Fix generate_code by adding missing s to flag
2025-07-04 16:46:28 -07:00
mustiikhalil
6fe8afb3b6 [CI] Moves swift actions to use next (#8632)
* Moves to use swift-actions@next until final release is out

* Migrates to vapor that uses swiftly actions

* Trying to use windows 2022
2025-07-01 13:46:06 -07:00
Truman Mulholland
00eec2445b [TS] Fix relative paths for exports (#8517)
Fixes an issue where exports were using incorrect relative paths for
>=3 namespace levels. This is fixed by making the starting range of the
namespace components relative to the amount of components.

Co-authored-by: Björn Harrtell <bjornharrtell@users.noreply.github.com>
2025-07-01 08:38:02 -07:00
mustiikhalil
b8db3a9a6a Adds windows swift support (#8622)
Adding support for windows requires the code generations
to add a compiler statement to completely ignore GRPC code
generation on windows

Cleanup the project to use the main Package.swift to run tests
instead of having it separate and includes the imports for GRPC
within it.

Adds windows swift ci
2025-06-30 05:45:48 -07:00
Seth Raymond
75556437cc Decode bytes to strings in Python Object API (#8551) 2025-06-29 01:40:10 -07:00
Felix
31beb0fb2f Bugfix: grpc python code generation location and file suffix (#8359)
* clang-format

* [Python] Replace . with _ in grpc filename suffix

Having filenames with . like `file.fb.grcp`
is not great for Python. Since dots are used for namespaces.
Replacing all of them with _ eg suffix `foo.bar.baz` will become
`foo_bar_baz`.

Restoring the previous default `_fb` suffix.

* [Python] Use namespace in path

This fixes a regression introduced with:
fb9afbafc7
And generates the grpc file in the namespace folder again.

* Sync commandline docs with web docs
2025-06-24 22:52:40 -07:00
Aaron Barany
dfd92124aa Avoid outputting Python files for already generated types (#8500)
This may overwrite types that have already been generated and can create
unwanted empty files. Fixes #8490
2025-06-23 12:00:37 -07:00
Björn Harrtell
a2916d37e7 [TS] Upgrade deps (#8620) 2025-06-22 08:59:42 -07:00
mustiikhalil
5a95b7b6bc [Swift] Flexbuffers native swift port (#8577)
* Offical Swift port for FlexBuffers

This is the offical port for FlexBuffers within
swift, and it introcudes a Common Module where code
is shared between flatbuffers and flexbuffers.

Writing most supported values like maps, vectors,
nil and scalars into a flexbuffer buffer. And includes
tests to verify that its similar to cpp

* Reading a flexbuffer

Implementing reading from a flexbuffer, enabling
most of the buffers features, like most types, maps, vectors,
typedvectors, and fixedtypedvectors.

Currently, if an offset/object cant be read we default to a swift
nil instead of the default flexbuffers 'null' with all values.

* Fixes bazel breaking due to new project structure

Address warnings within the library

* Adds comment on why we added the code & properly enforce the amout of bytes needed
2025-06-22 08:36:38 +02:00
Björn Harrtell
595ac94a6a [TS] Enum value default null (#8619)
* [TS] Enum value default null

* Re-gen
2025-06-21 22:25:56 -07:00
Adam Oleksy
5822c1c8dd 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-17 22:01:09 -07:00
Maurice Sotzny
609c72ca1a [C++] Fixes #8446 (#8447)
Fixes access to union members when generating code with options "--cpp-field-case-style upper" and "--gen-object-api"

Co-authored-by: Wouter van Oortmerssen <aardappel@gmail.com>
2025-04-14 08:54:10 -07:00
mustiikhalil
bd1b2d0baf [Swift] Adds new API to reduce memory copying within swift (#8484)
* Adds new API to reduce memory copying within swift

Adds new storage container _InternalByteBuffer which
will be holding the data that will be created within the swift
lib, however reading data will be redirected to ByteBuffer, which
should be able to handle all types of data that swift provide without
the need to copy the data itself. This is due to holding a reference to
the data.

Replaces assumingMemoryBinding with bindMemory which is safer

Adds function that provides access to a UnsafeBufferPointer for
scalars and NativeStructs within swift

Updates docs

Suppress compilation warnings by replacing var with let

Using overflow operators within swift to improve performance

Adds tests for GRPC message creation from a retained _InternalByteBuffer
2025-03-18 07:48:39 +01:00
1234 changed files with 97762 additions and 67880 deletions

View File

@@ -10,7 +10,7 @@ tasks:
bazel: ${{ bazel }} bazel: ${{ bazel }}
environment: environment:
CC: clang CC: clang
SWIFT_VERSION: "5.9" SWIFT_VERSION: "5.10"
SWIFT_HOME: "$HOME/swift-$SWIFT_VERSION" SWIFT_HOME: "$HOME/swift-$SWIFT_VERSION"
PATH: "$PATH:$SWIFT_HOME/usr/bin" PATH: "$PATH:$SWIFT_HOME/usr/bin"
shell_commands: shell_commands:
@@ -26,7 +26,7 @@ tasks:
bazel: ${{ bazel }} bazel: ${{ bazel }}
environment: environment:
CC: clang CC: clang
SWIFT_VERSION: "5.9" SWIFT_VERSION: "5.10"
SWIFT_HOME: "$HOME/swift-$SWIFT_VERSION" SWIFT_HOME: "$HOME/swift-$SWIFT_VERSION"
PATH: "$PATH:$SWIFT_HOME/usr/bin" PATH: "$PATH:$SWIFT_HOME/usr/bin"
shell_commands: shell_commands:

View File

@@ -1,13 +1,5 @@
--- ---
Language: Cpp Language: Cpp
BasedOnStyle: Google BasedOnStyle: Google
DerivePointerAlignment: false
PointerAlignment: Right
IndentPPDirectives: AfterHash
Cpp11BracedListStyle: false
AlwaysBreakTemplateDeclarations: false
AllowShortCaseLabelsOnASingleLine: true
SpaceAfterTemplateKeyword: false
AllowShortBlocksOnASingleLine: true
... ...

View File

@@ -1,13 +0,0 @@
/* eslint-env node */
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
plugins: [
'@typescript-eslint',
],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
]
};

5
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1,5 @@
# Default owner
* @dbaileychess derekbailey@google.com
# Prevent modification of this file
.github/CODEOWNERS @dbaileychess derekbailey@google.com

6
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

146
.github/labeler.yml vendored
View File

@@ -5,93 +5,133 @@
# #
# See .github/workflows/label.yml for Github Action workflow script # See .github/workflows/label.yml for Github Action workflow script
c#: "c#":
- '**/*.cs' - changed-files:
- net/**/* - any-glob-to-any-file:
- tests/FlatBuffers.Test/**/* - '**/*.cs'
- tests/FlatBuffers.Benchmarks/**/* - 'net/**/*'
- src/idl_gen_csharp.cpp - 'tests/FlatBuffers.Test/**/*'
- 'tests/FlatBuffers.Benchmarks/**/*'
- 'src/idl_gen_csharp.cpp'
swift: swift:
- '**/*.swift' - changed-files:
- swift/**/* - any-glob-to-any-file:
- tests/swift/** - '**/*.swift'
- src/idl_gen_swift.cpp - 'swift/**/*'
- 'tests/swift/**'
- 'src/idl_gen_swift.cpp'
nim: nim:
- '**/*.nim' - changed-files:
- nim/**/* - any-glob-to-any-file:
- src/idl_gen_nim.cpp - '**/*.nim'
- src/bfbs_gen_nim.cpp - 'nim/**/*'
- 'src/idl_gen_nim.cpp'
- 'src/bfbs_gen_nim.cpp'
javascript: javascript:
- '**/*.js' - changed-files:
- src/idl_gen_ts.cpp - any-glob-to-any-file:
- '**/*.js'
- 'src/idl_gen_ts.cpp'
typescript: typescript:
- '**/*.ts' - changed-files:
- src/idl_gen_ts.cpp - any-glob-to-any-file:
- grpc/flatbuffers-js-grpc/**/*.ts - '**/*.ts'
- 'src/idl_gen_ts.cpp'
- 'grpc/flatbuffers-js-grpc/**/*.ts'
golang: golang:
- '**/*.go' - changed-files:
- src/idl_gen_go.cpp - any-glob-to-any-file:
- '**/*.go'
- 'src/idl_gen_go.cpp'
python: python:
- '**/*.py' - changed-files:
- src/idl_gen_python.cpp - any-glob-to-any-file:
- '**/*.py'
- 'src/idl_gen_python.cpp'
java: java:
- '**/*.java' - changed-files:
- src/idl_gen_java.cpp - any-glob-to-any-file:
- '**/*.java'
- 'src/idl_gen_java.cpp'
kotlin: kotlin:
- '**/*.kt' - changed-files:
- src/idl_gen_kotlin.cpp - any-glob-to-any-file:
- src/idl_gen_kotlin_kmp.cpp - '**/*.kt'
- 'src/idl_gen_kotlin.cpp'
- 'src/idl_gen_kotlin_kmp.cpp'
lua: lua:
- '**/*.lua' - changed-files:
- lua/**/* - any-glob-to-any-file:
- src/bfbs_gen_lua.cpp - '**/*.lua'
- 'lua/**/*'
- 'src/bfbs_gen_lua.cpp'
lobster: lobster:
- '**/*.lobster' - changed-files:
- src/idl_gen_lobster.cpp - any-glob-to-any-file:
- '**/*.lobster'
- 'src/idl_gen_lobster.cpp'
php: php:
- '**/*.php' - changed-files:
- src/idl_gen_php.cpp - any-glob-to-any-file:
- '**/*.php'
- 'src/idl_gen_php.cpp'
rust: rust:
- '**/*.rs' - changed-files:
- rust/**/* - any-glob-to-any-file:
- src/idl_gen_rust.cpp - '**/*.rs'
- 'rust/**/*'
- 'src/idl_gen_rust.cpp'
dart: dart:
- '**/*.dart' - changed-files:
- src/idl_gen_dart.cpp - any-glob-to-any-file:
- '**/*.dart'
- 'src/idl_gen_dart.cpp'
c++: "c++":
- '**/*.cc' - changed-files:
- '**/*.cpp' - any-glob-to-any-file:
- '**/*.h' - '**/*.cc'
- '**/*.cpp'
- '**/*.h'
json: json:
- '**/*.json' - changed-files:
- src/idl_gen_json_schema.cpp - any-glob-to-any-file:
- '**/*.json'
- 'src/idl_gen_json_schema.cpp'
codegen: codegen:
- src/**/* - changed-files:
- any-glob-to-any-file:
- 'src/**/*'
documentation: documentation:
- docs/**/* - changed-files:
- '**/*.md' - any-glob-to-any-file:
- 'docs/**/*'
- '**/*.md'
CI: CI:
- '.github/**/*' - changed-files:
- '.bazelci/**/*' - any-glob-to-any-file:
- '.github/**/*'
- '.bazelci/**/*'
grpc: grpc:
- grpc/**/* - changed-files:
- src/idl_gen_grpc.cpp - any-glob-to-any-file:
- 'grpc/**/*'
- 'src/idl_gen_grpc.cpp'

View File

@@ -30,7 +30,7 @@ jobs:
cxx: [g++-13, clang++-18] cxx: [g++-13, clang++-18]
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: cmake - name: cmake
run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON -DFLATBUFFERS_STATIC_FLATC=ON . run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON -DFLATBUFFERS_STATIC_FLATC=ON .
- name: build - name: build
@@ -42,7 +42,7 @@ jobs:
chmod +x flatc chmod +x flatc
./flatc --version ./flatc --version
- name: upload build artifacts - name: upload build artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: Linux flatc binary ${{ matrix.cxx }} name: Linux flatc binary ${{ matrix.cxx }}
path: flatc path: flatc
@@ -51,7 +51,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
run: zip Linux.flatc.binary.${{ matrix.cxx }}.zip flatc run: zip Linux.flatc.binary.${{ matrix.cxx }}.zip flatc
- name: Release zip file - name: Release zip file
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
with: with:
files: Linux.flatc.binary.${{ matrix.cxx }}.zip files: Linux.flatc.binary.${{ matrix.cxx }}.zip
@@ -68,7 +68,7 @@ jobs:
name: Build Linux with -DFLATBUFFERS_NO_FILE_TESTS name: Build Linux with -DFLATBUFFERS_NO_FILE_TESTS
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: cmake - name: cmake
run: CXX=clang++-18 cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON -DFLATBUFFERS_CXX_FLAGS="-DFLATBUFFERS_NO_FILE_TESTS" . run: CXX=clang++-18 cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON -DFLATBUFFERS_CXX_FLAGS="-DFLATBUFFERS_NO_FILE_TESTS" .
- name: build - name: build
@@ -80,7 +80,7 @@ jobs:
name: Build Linux with out-of-source build location name: Build Linux with out-of-source build location
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: make build directory - name: make build directory
run: mkdir build run: mkdir build
- name: cmake - name: cmake
@@ -112,7 +112,7 @@ jobs:
std: 23 std: 23
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: cmake - name: cmake
run: > run: >
CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles"
@@ -129,18 +129,18 @@ jobs:
build-cpp-std: build-cpp-std:
name: Build Windows C++ name: Build Windows C++
runs-on: windows-2019 runs-on: windows-2022
strategy: strategy:
matrix: matrix:
std: [11, 14, 17, 20, 23] std: [11, 14, 17, 20, 23]
fail-fast: false fail-fast: false
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v2
- name: cmake - name: cmake
run: > run: >
cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release
-DFLATBUFFERS_STRICT_MODE=ON -DFLATBUFFERS_STRICT_MODE=ON
-DFLATBUFFERS_CPP_STD=${{ matrix.std }} -DFLATBUFFERS_CPP_STD=${{ matrix.std }}
-DFLATBUFFERS_BUILD_CPP17=${{ matrix.std >= 17 && 'On' || 'Off'}} -DFLATBUFFERS_BUILD_CPP17=${{ matrix.std >= 17 && 'On' || 'Off'}}
@@ -157,20 +157,20 @@ jobs:
contents: write contents: write
outputs: outputs:
digests: ${{ steps.hash.outputs.hashes }} digests: ${{ steps.hash.outputs.hashes }}
name: Build Windows 2019 name: Build Windows 2022
runs-on: windows-2019 runs-on: windows-2022
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v2
- name: cmake - name: cmake
run: cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON . run: cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON .
- name: build - name: build
run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64 run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64
- name: test - name: test
run: Release\flattests.exe run: Release\flattests.exe
- name: upload build artifacts - name: upload build artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: Windows flatc binary name: Windows flatc binary
path: Release\flatc.exe path: Release\flatc.exe
@@ -179,7 +179,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
run: move Release/flatc.exe . && Compress-Archive flatc.exe Windows.flatc.binary.zip run: move Release/flatc.exe . && Compress-Archive flatc.exe Windows.flatc.binary.zip
- name: Release binary - name: Release binary
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
with: with:
files: Windows.flatc.binary.zip files: Windows.flatc.binary.zip
@@ -191,25 +191,24 @@ jobs:
build-dotnet-windows: build-dotnet-windows:
name: Build .NET Windows name: Build .NET Windows
runs-on: windows-2022-64core runs-on: windows-2022
strategy: strategy:
matrix: matrix:
configuration: [ configuration: [
'', '',
'-p:UnsafeByteBuffer=true', '-p:UnsafeByteBuffer=true',
# Fails two tests currently. '-p:EnableSpanT=true,UnsafeByteBuffer=true'
#'-p:EnableSpanT=true,UnsafeByteBuffer=true'
] ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: Setup .NET Core SDK - name: Setup .NET Core SDK
uses: actions/setup-dotnet@v4.2.0 uses: actions/setup-dotnet@v5
with: with:
dotnet-version: '8.0.x' dotnet-version: '8.0.x'
- name: Build - name: Build
run: | run: |
cd tests\FlatBuffers.Test cd tests\FlatBuffers.Test
dotnet new sln --force --name FlatBuffers.Test dotnet new sln --force --name FlatBuffers.Test --format sln
dotnet sln FlatBuffers.Test.sln add FlatBuffers.Test.csproj dotnet sln FlatBuffers.Test.sln add FlatBuffers.Test.csproj
dotnet build -c Release ${{matrix.configuration}} FlatBuffers.Test.sln dotnet build -c Release ${{matrix.configuration}} FlatBuffers.Test.sln
- name: Run net6.0 - name: Run net6.0
@@ -228,9 +227,9 @@ jobs:
outputs: outputs:
digests: ${{ steps.hash.outputs.hashes }} digests: ${{ steps.hash.outputs.hashes }}
name: Build Mac (for Intel) name: Build Mac (for Intel)
runs-on: macos-latest-large runs-on: macos-15-intel
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: cmake - name: cmake
run: cmake -G "Xcode" -DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON . run: cmake -G "Xcode" -DCMAKE_OSX_ARCHITECTURES="x86_64" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON .
- name: build - name: build
@@ -247,7 +246,7 @@ jobs:
chmod +x Release/flatc chmod +x Release/flatc
Release/flatc --version Release/flatc --version
- name: upload build artifacts - name: upload build artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: Mac flatc binary Intel name: Mac flatc binary Intel
path: Release/flatc path: Release/flatc
@@ -256,7 +255,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
run: mv Release/flatc . && zip MacIntel.flatc.binary.zip flatc run: mv Release/flatc . && zip MacIntel.flatc.binary.zip flatc
- name: Release binary - name: Release binary
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
with: with:
files: MacIntel.flatc.binary.zip files: MacIntel.flatc.binary.zip
@@ -273,7 +272,7 @@ jobs:
name: Build Mac (universal build) name: Build Mac (universal build)
runs-on: macos-latest runs-on: macos-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: cmake - name: cmake
run: cmake -G "Xcode" -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON . run: cmake -G "Xcode" -DCMAKE_OSX_ARCHITECTURES="arm64;x86_64" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON .
- name: build - name: build
@@ -290,7 +289,7 @@ jobs:
chmod +x Release/flatc chmod +x Release/flatc
Release/flatc --version Release/flatc --version
- name: upload build artifacts - name: upload build artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: Mac flatc binary Universal name: Mac flatc binary Universal
path: Release/flatc path: Release/flatc
@@ -299,7 +298,7 @@ jobs:
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
run: mv Release/flatc . && zip Mac.flatc.binary.zip flatc run: mv Release/flatc . && zip Mac.flatc.binary.zip flatc
- name: Release binary - name: Release binary
uses: softprops/action-gh-release@v1 uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
with: with:
files: Mac.flatc.binary.zip files: Mac.flatc.binary.zip
@@ -310,14 +309,17 @@ jobs:
build-android: build-android:
name: Build Android (on Linux) name: Build Android (on Linux)
if: false #disabled due to continual failure
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: set up Java - name: set up Java
uses: actions/setup-java@v3 uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: temurin
java-version: '11' java-version: 17
- name: set up Gradle
uses: gradle/actions/setup-gradle@v5
- name: set up flatc - name: set up flatc
run: | run: |
cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON . cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON .
@@ -334,7 +336,7 @@ jobs:
matrix: matrix:
cxx: [g++-13, clang++-18] cxx: [g++-13, clang++-18]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: cmake - name: cmake
run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DFLATBUFFERS_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON . && make -j run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DFLATBUFFERS_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON . && make -j
- name: Generate - name: Generate
@@ -344,13 +346,13 @@ jobs:
build-generator-windows: build-generator-windows:
name: Check Generated Code on Windows name: Check Generated Code on Windows
runs-on: windows-2019 runs-on: windows-2022
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1 uses: microsoft/setup-msbuild@v2
- name: cmake - name: cmake
run: cmake -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON . run: cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_STRICT_MODE=ON .
- name: build - name: build
run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64 run: msbuild.exe FlatBuffers.sln /p:Configuration=Release /p:Platform=x64
- name: Generate - name: Generate
@@ -365,13 +367,13 @@ jobs:
matrix: matrix:
cxx: [g++-13] cxx: [g++-13]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: cmake - name: cmake
run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DFLATBUFFERS_CXX_FLAGS="-Wno-unused-parameter -fno-aligned-new" -DFLATBUFFERS_BUILD_BENCHMARKS=ON -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON . && make -j run: CXX=${{ matrix.cxx }} cmake -G "Unix Makefiles" -DFLATBUFFERS_CXX_FLAGS="-Wno-unused-parameter -fno-aligned-new" -DFLATBUFFERS_BUILD_BENCHMARKS=ON -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_STRICT_MODE=ON . && make -j
- name: Run benchmarks - name: Run benchmarks
run: ./flatbenchmark --benchmark_repetitions=5 --benchmark_display_aggregates_only=true --benchmark_out_format=console --benchmark_out=benchmarks/results_${{matrix.cxx}} run: ./flatbenchmark --benchmark_repetitions=5 --benchmark_display_aggregates_only=true --benchmark_out_format=console --benchmark_out=benchmarks/results_${{matrix.cxx}}
- name: Upload benchmarks results - name: Upload benchmarks results
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
with: with:
name: Linux flatbenchmark results ${{matrix.cxx}} name: Linux flatbenchmark results ${{matrix.cxx}}
path: benchmarks/results_${{matrix.cxx}} path: benchmarks/results_${{matrix.cxx}}
@@ -380,29 +382,24 @@ jobs:
name: Build Java name: Build Java
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: test - name: test
working-directory: java working-directory: java
run: mvn test run: mvn test
build-kotlin-macos: build-kotlin-macos:
name: Build Kotlin MacOS name: Build Kotlin MacOS
runs-on: macos-13 runs-on: macos-15
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v6
# Force Xcode 14.3 since Xcode 15 doesnt support older versions of - name: set up Java
# kotlin. For Xcode 15, kotlin should be bumpped to 1.9.10 uses: actions/setup-java@v5
# https://stackoverflow.com/a/77150623
# For now, run with macos-13 which has this 14.3 installed:
# https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md#xcode
- name: Set up Xcode version
run: sudo xcode-select -s /Applications/Xcode_14.3.app/Contents/Developer
- uses: gradle/wrapper-validation-action@v1.0.5
- uses: actions/setup-java@v3
with: with:
distribution: 'temurin' distribution: temurin
java-version: '11' java-version: 17
- name: set up Gradle
uses: gradle/actions/setup-gradle@v5
- name: Build flatc - name: Build flatc
run: | run: |
cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF .
@@ -414,15 +411,18 @@ jobs:
build-kotlin-linux: build-kotlin-linux:
name: Build Kotlin Linux name: Build Kotlin Linux
if: false #disabled due to continual failure
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@v6
- uses: actions/setup-java@v3 - name: set up Java
uses: actions/setup-java@v5
with: with:
distribution: 'temurin' distribution: temurin
java-version: '11' java-version: 17
- uses: gradle/wrapper-validation-action@v1.0.5 - name: set up Gradle
uses: gradle/actions/setup-gradle@v5
- name: Build flatc - name: Build flatc
run: | run: |
cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF .
@@ -439,16 +439,16 @@ jobs:
name: Build Rust Linux name: Build Rust Linux
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: test - name: test
working-directory: tests working-directory: tests
run: bash RustTest.sh run: bash RustTest.sh
build-rust-windows: build-rust-windows:
name: Build Rust Windows name: Build Rust Windows
runs-on: windows-2022-64core runs-on: windows-2022
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: test - name: test
working-directory: tests working-directory: tests
run: ./RustTest.bat run: ./RustTest.bat
@@ -457,7 +457,7 @@ jobs:
name: Build Python name: Build Python
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: flatc - name: flatc
# FIXME: make test script not rely on flatc # FIXME: make test script not rely on flatc
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON . && make -j run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON . && make -j
@@ -469,7 +469,7 @@ jobs:
name: Build Go name: Build Go
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: flatc - name: flatc
# FIXME: make test script not rely on flatc # FIXME: make test script not rely on flatc
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON . && make -j run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON . && make -j
@@ -481,7 +481,7 @@ jobs:
name: Build PHP name: Build PHP
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: flatc - name: flatc
# FIXME: make test script not rely on flatc # FIXME: make test script not rely on flatc
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON . && make -j run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON . && make -j
@@ -492,63 +492,74 @@ jobs:
sh phpUnionVectorTest.sh sh phpUnionVectorTest.sh
build-swift: build-swift:
name: Build Swift name: Test Swift Linux
strategy: strategy:
matrix: matrix:
swift: ["5.9", "5.10", "6.0"] swift: ["6.0", "6.1", "6.2"]
# Only 22.04 has swift at the moment https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2204-Readme.md?plain=1#L30 runs-on: ubuntu-24.04
runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: swift-actions/setup-swift@v2 - uses: swift-actions/setup-swift@v2
with: with:
swift-version: ${{ matrix.swift }} swift-version: ${{ matrix.swift }}
- name: Get swift version - name: Get swift version
run: swift --version run: swift --version
- name: test - name: test
working-directory: tests/swift/tests run: swift test
run: |
swift build --build-tests build-swift-windows:
swift test name: Test swift windows
runs-on: windows-latest
steps:
- uses: actions/checkout@v6
- uses: SwiftyLab/setup-swift@latest
with:
swift-version: '6.1'
- run: swift build
- run: swift test
build-swift-wasm: build-swift-wasm:
name: Build Swift Wasm name: Test Swift Wasm
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
container:
image: ghcr.io/swiftwasm/carton:0.20.1
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: bytecodealliance/actions/wasmtime/setup@v1 - uses: swift-actions/setup-swift@v2
- uses: swiftwasm/setup-swiftwasm@v1
with: with:
swift-version: "wasm-6.0.2-RELEASE" swift-version: 6.2.1
- uses: bytecodealliance/actions/wasmtime/setup@v1
- name: Install Swift SDK
run: swift sdk install https://download.swift.org/swift-6.2.1-release/wasm-sdk/swift-6.2.1-RELEASE/swift-6.2.1-RELEASE_wasm.artifactbundle.tar.gz --checksum 482b9f95462b87bedfafca94a092cf9ec4496671ca13b43745097122d20f18af
- name: Test - name: Test
working-directory: tests/swift/Wasm.tests working-directory: tests/swift/Wasm.tests
run: swift run carton test run: |
swift sdk list
swift build --build-tests --swift-sdk swift-6.2.1-RELEASE_wasm
wasmtime --dir . .build/wasm32-unknown-wasip1/debug/FlatBuffers.Test.Swift.WasmPackageTests.xctest --testing-library swift-testing
build-ts: build-ts:
name: Build TS name: Build TS
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: flatc - name: flatc
# FIXME: make test script not rely on flatc # FIXME: make test script not rely on flatc
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . && make -j run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . && make -j
- name: pnpm
run: npm install -g pnpm
- name: deps - name: deps
run: yarn run: pnpm i
- name: compile - name: compile
run: yarn compile run: pnpm compile
- name: test - name: test
working-directory: tests/ts working-directory: tests/ts
run: | run: |
yarn global add esbuild
python3 TypeScriptTest.py python3 TypeScriptTest.py
build-dart: build-dart:
name: Build Dart name: Build Dart
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: dart-lang/setup-dart@v1 - uses: dart-lang/setup-dart@v1
with: with:
sdk: stable sdk: stable
@@ -563,11 +574,11 @@ jobs:
name: Build Nim name: Build Nim
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: flatc - name: flatc
# FIXME: make test script not rely on flatc # FIXME: make test script not rely on flatc
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . && make -j run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF . && make -j
- uses: jiro4989/setup-nim-action@v1 - uses: jiro4989/setup-nim-action@v2
- name: install library - name: install library
working-directory: nim working-directory: nim
run: nimble -y develop && nimble install run: nimble -y develop && nimble install
@@ -579,15 +590,20 @@ jobs:
name: Bazel name: Bazel
runs-on: ubuntu-24.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
# Explicitly use 8.5.1 until we can update or https://github.com/actions/runner-images/issues/13564 is fixed.
- name: Set env
run: >
echo "USE_BAZEL_VERSION=8.5.1" >> $GITHUB_ENV
- name: bazel build - name: bazel build
run: > run: >
bazel build bazel build
//:flatc //:flatc
//:flatbuffers //:flatbuffers
//tests:flatbuffers_test
- name: bazel test - name: bazel test
run: > run: >
bazel test bazel test
//tests:flatbuffers_test //tests:flatbuffers_test
release-digests: release-digests:
@@ -621,8 +637,7 @@ jobs:
actions: read # To read the workflow path. actions: read # To read the workflow path.
id-token: write # To sign the provenance. id-token: write # To sign the provenance.
contents: write # To add assets to a release. contents: write # To add assets to a release.
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.2.1 uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
with: with:
base64-subjects: "${{ needs.release-digests.outputs.digests }}" base64-subjects: "${{ needs.release-digests.outputs.digests }}"
upload-assets: true # Optional: Upload to a new release upload-assets: true # Optional: Upload to a new release
compile-generator: true # Workaround for https://github.com/slsa-framework/slsa-github-generator/issues/1163

View File

@@ -16,16 +16,16 @@ jobs:
deploy: deploy:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v6
- name: Configure Git Credentials - name: Configure Git Credentials
run: | run: |
git config user.name github-actions[bot] git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com git config user.email 41898282+github-actions[bot]@users.noreply.github.com
- uses: actions/setup-python@v5 - uses: actions/setup-python@v6
with: with:
python-version: 3.x python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v4 - uses: actions/cache@v5
with: with:
key: mkdocs-material-${{ env.cache_id }} key: mkdocs-material-${{ env.cache_id }}
path: .cache path: .cache

View File

@@ -19,6 +19,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/labeler@ee18d5d34efd9b4f7dafdb0e363cb688eb438044 # 4.1.0 - uses: actions/labeler@v6
with: with:
repo-token: "${{ secrets.GITHUB_TOKEN }}" repo-token: "${{ secrets.GITHUB_TOKEN }}"

View File

@@ -27,7 +27,7 @@ jobs:
language: c++ language: c++
fuzz-seconds: 60 fuzz-seconds: 60
- name: Upload Crash - name: Upload Crash
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v7
if: failure() && steps.build.outcome == 'success' if: failure() && steps.build.outcome == 'success'
with: with:
name: artifacts name: artifacts

View File

@@ -12,8 +12,8 @@ jobs:
name: Publish NPM name: Publish NPM
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: actions/setup-node@v3 - uses: actions/setup-node@v6
with: with:
node-version: '20.x' node-version: '20.x'
registry-url: 'https://registry.npmjs.org' registry-url: 'https://registry.npmjs.org'
@@ -29,19 +29,19 @@ jobs:
run: run:
working-directory: ./python working-directory: ./python
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: actions/setup-python@v4 - uses: actions/setup-python@v6
with: with:
python-version: '3.10' python-version: '3.10'
- name: Install Dependencies - name: Install Dependencies
run: | run: |
python3 -m pip install --upgrade pip python3 -m pip install --upgrade pip
python3 -m pip install setuptools wheel twine python3 -m pip install build twine
- name: Build - name: Build
run: | run: |
python3 setup.py sdist bdist_wheel python3 -m build .
- name: Upload to PyPi - name: Upload to PyPi
run: | run: |
@@ -57,8 +57,8 @@ jobs:
run: run:
working-directory: ./net/flatbuffers working-directory: ./net/flatbuffers
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: actions/setup-dotnet@v3 - uses: actions/setup-dotnet@v5
with: with:
dotnet-version: '8.0.x' dotnet-version: '8.0.x'
- name: Build - name: Build
@@ -80,10 +80,10 @@ jobs:
run: run:
working-directory: ./java working-directory: ./java
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: Set up Maven Central Repository - name: Set up Maven Central Repository
uses: actions/setup-java@v3 uses: actions/setup-java@v5
with: with:
java-version: '11' java-version: '11'
distribution: 'adopt' distribution: 'adopt'
@@ -108,9 +108,9 @@ jobs:
run: run:
working-directory: ./kotlin working-directory: ./kotlin
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- name: Set up Maven Central Repository - name: Set up Maven Central Repository
uses: actions/setup-java@v3 uses: actions/setup-java@v5
with: with:
java-version: '11' java-version: '11'
distribution: 'adopt' distribution: 'adopt'
@@ -133,7 +133,7 @@ jobs:
name: Publish crates.io name: Publish crates.io
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v6
- uses: actions-rs/toolchain@v1 - uses: actions-rs/toolchain@v1
with: with:
toolchain: stable toolchain: stable

View File

@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/stale@v7.0.0 - uses: actions/stale@v10
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
operations-per-run: 500 operations-per-run: 500

5
.gitignore vendored
View File

@@ -156,4 +156,7 @@ kotlin/**/generated
MODULE.bazel.lock MODULE.bazel.lock
# Ignore the generated docs # Ignore the generated docs
docs/site docs/site
# Ignore generated files
*.fbs.h

View File

@@ -4,6 +4,23 @@ All major or breaking changes will be documented in this file, as well as any
new features that should be highlighted. Minor fixes or improvements are not new features that should be highlighted. Minor fixes or improvements are not
necessarily listed. necessarily listed.
## [25.12.19] (December 19 2025)(https://github.com/google/flatbuffers/releases/tag/v25.12.19)
* [C++] Default emptry vector support (#8870)
* [C++] Add --gen-absl-hash option (#8868)
* [Kotlin] Upgrade to MacOS 15 (#8845)
* [C++] Fix vector of table with naked ptrs (#8830)
* [Python] Optimize Offset/Pad/Prep (#8808)
* Implement `--file-names-only` (#8788)
* [C++] Fix size verifer (#8740)
## [25.9.23] (September 23 2025)(https://github.com/google/flatbuffers/releases/tag/v25.9.23)
* flatc: `--grpc-callback-api` flag generates C++ gRPC Callback API server `CallbackService` skeletons AND client native callback/async stubs (unary + all streaming reactor forms) (opt-in, non-breaking, issue #8596).
* Swift - Adds new API to reduce memory copying within swift (#8484)
* Rust - Support Rust edition 2024 (#8638)
* [C++] - Use the Google Style for clang-format without exceptions (#8706)
## [25.2.10] (February 10 2025)(https://github.com/google/flatbuffers/releases/tag/v25.2.10) ## [25.2.10] (February 10 2025)(https://github.com/google/flatbuffers/releases/tag/v25.2.10)
* Removed the old documentation pages. The new one is live at https://flatbuffers.dev * Removed the old documentation pages. The new one is live at https://flatbuffers.dev

View File

@@ -305,8 +305,7 @@ function(flatbuffers_generate_headers)
${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS}) ${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
add_dependencies( add_dependencies(
${FLATBUFFERS_GENERATE_HEADERS_TARGET} ${FLATBUFFERS_GENERATE_HEADERS_TARGET}
${FLATC} ${FLATC_TARGET})
${FLATBUFFERS_GENERATE_HEADERS_SCHEMAS})
target_include_directories( target_include_directories(
${FLATBUFFERS_GENERATE_HEADERS_TARGET} ${FLATBUFFERS_GENERATE_HEADERS_TARGET}
INTERFACE ${generated_target_dir}) INTERFACE ${generated_target_dir})

View File

@@ -1,6 +1,6 @@
set(VERSION_MAJOR 25) set(VERSION_MAJOR 25)
set(VERSION_MINOR 2) set(VERSION_MINOR 12)
set(VERSION_PATCH 10) set(VERSION_PATCH 19)
set(VERSION_COMMIT 0) set(VERSION_COMMIT 0)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")

View File

@@ -112,6 +112,7 @@ endif()
add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=$<BOOL:${FLATBUFFERS_LOCALE_INDEPENDENT}>) add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=$<BOOL:${FLATBUFFERS_LOCALE_INDEPENDENT}>)
if(NOT WIN32) if(NOT WIN32)
include(CheckSymbolExists)
check_symbol_exists(realpath "stdlib.h" HAVE_REALPATH) check_symbol_exists(realpath "stdlib.h" HAVE_REALPATH)
if(NOT HAVE_REALPATH) if(NOT HAVE_REALPATH)
add_definitions(-DFLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION) add_definitions(-DFLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION)
@@ -146,6 +147,8 @@ set(FlatBuffers_Library_SRCS
include/flatbuffers/vector.h include/flatbuffers/vector.h
include/flatbuffers/vector_downward.h include/flatbuffers/vector_downward.h
include/flatbuffers/verifier.h include/flatbuffers/verifier.h
src/file_manager.cpp
src/file_name_manager.cpp
src/idl_parser.cpp src/idl_parser.cpp
src/idl_gen_text.cpp src/idl_gen_text.cpp
src/reflection.cpp src/reflection.cpp
@@ -172,9 +175,6 @@ set(FlatBuffers_Compiler_SRCS
src/idl_gen_grpc.cpp src/idl_gen_grpc.cpp
src/idl_gen_json_schema.cpp src/idl_gen_json_schema.cpp
src/idl_gen_swift.cpp src/idl_gen_swift.cpp
src/file_name_saving_file_manager.cpp
src/file_binary_writer.cpp
src/file_writer.cpp
src/idl_namer.h src/idl_namer.h
src/namer.h src/namer.h
src/flatc.cpp src/flatc.cpp
@@ -218,6 +218,8 @@ set(FlatHash_SRCS
set(FlatBuffers_Tests_SRCS set(FlatBuffers_Tests_SRCS
${FlatBuffers_Library_SRCS} ${FlatBuffers_Library_SRCS}
src/idl_gen_fbs.cpp src/idl_gen_fbs.cpp
tests/default_vectors_strings_test.cpp
tests/default_vectors_strings_test.h
tests/evolution_test.cpp tests/evolution_test.cpp
tests/flexbuffers_test.cpp tests/flexbuffers_test.cpp
tests/fuzz_test.cpp tests/fuzz_test.cpp
@@ -234,6 +236,8 @@ set(FlatBuffers_Tests_SRCS
tests/test_builder.h tests/test_builder.h
tests/test_builder.cpp tests/test_builder.cpp
tests/util_test.cpp tests/util_test.cpp
tests/vector_table_naked_ptr_test.h
tests/vector_table_naked_ptr_test.cpp
tests/native_type_test_impl.h tests/native_type_test_impl.h
tests/native_type_test_impl.cpp tests/native_type_test_impl.cpp
tests/alignment_test.h tests/alignment_test.h
@@ -278,6 +282,8 @@ set(FlatBuffers_GRPCTest_SRCS
tests/test_builder.cpp tests/test_builder.cpp
grpc/tests/grpctest.cpp grpc/tests/grpctest.cpp
grpc/tests/message_builder_test.cpp grpc/tests/message_builder_test.cpp
grpc/tests/grpctest_callback_compile.cpp
grpc/tests/grpctest_callback_client_compile.cpp
) )
# TODO(dbaileychess): Figure out how this would now work. I posted a question on # TODO(dbaileychess): Figure out how this would now work. I posted a question on
@@ -492,28 +498,34 @@ if(FLATBUFFERS_BUILD_SHAREDLIB)
endif() endif()
endif() endif()
function(compile_schema SRC_FBS OPT OUT_GEN_FILE) function(compile_schema SRC_FBS OPT SUFFIX OUT_GEN_FILE)
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH) get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS}) string(REGEX REPLACE "\\.fbs$" "${SUFFIX}.h" GEN_HEADER ${SRC_FBS})
add_custom_command( add_custom_command(
OUTPUT ${GEN_HEADER} OUTPUT ${GEN_HEADER}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
${OPT} ${OPT}
--filename-suffix ${SUFFIX}
-o "${SRC_FBS_DIR}" -o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}" "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
DEPENDS flatc ${SRC_FBS} DEPENDS flatc ${SRC_FBS}
COMMENT "flatc generation: `${SRC_FBS}` -> `${GEN_HEADER}`" COMMENT "flatc generation: `${SRC_FBS}` -> `${GEN_HEADER}`"
) )
set(${OUT_GEN_FILE} ${GEN_HEADER} PARENT_SCOPE) set(${OUT_GEN_FILE} ${GEN_HEADER} PARENT_SCOPE)
endfunction() endfunction()
function(compile_schema_for_test SRC_FBS OPT) function(compile_schema_for_test SRC_FBS OPT)
compile_schema("${SRC_FBS}" "${OPT}" GEN_FILE) compile_schema("${SRC_FBS}" "${OPT}" "_generated" GEN_FILE)
target_sources(flattests PRIVATE ${GEN_FILE})
endfunction()
function(compile_schema_for_test_fbsh SRC_FBS OPT)
compile_schema("${SRC_FBS}" "${OPT}" ".fbs" GEN_FILE)
target_sources(flattests PRIVATE ${GEN_FILE}) target_sources(flattests PRIVATE ${GEN_FILE})
endfunction() endfunction()
function(compile_schema_for_samples SRC_FBS OPT) function(compile_schema_for_samples SRC_FBS OPT)
compile_schema("${SRC_FBS}" "${OPT}" GEN_FILE) compile_schema("${SRC_FBS}" "${OPT}" "_generated" GEN_FILE)
target_sources(flatsample PRIVATE ${GEN_FILE}) target_sources(flatsample PRIVATE ${GEN_FILE})
endfunction() endfunction()
@@ -534,19 +546,20 @@ if(FLATBUFFERS_BUILD_TESTS)
add_definitions(-DFLATBUFFERS_TEST_PATH_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/) add_definitions(-DFLATBUFFERS_TEST_PATH_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/)
# The flattest target needs some generated files # The flattest target needs some generated files
SET(FLATC_OPT --cpp --gen-mutable --gen-object-api --reflect-names) SET(FLATC_OPT_COMP --cpp --gen-compare --gen-mutable --gen-object-api --reflect-names)
SET(FLATC_OPT_COMP ${FLATC_OPT};--gen-compare)
SET(FLATC_OPT_SCOPED_ENUMS ${FLATC_OPT_COMP};--scoped-enums) SET(FLATC_OPT_SCOPED_ENUMS ${FLATC_OPT_COMP};--scoped-enums)
compile_schema_for_test(tests/alignment_test.fbs "${FLATC_OPT_COMP}") compile_schema_for_test(tests/alignment_test.fbs "${FLATC_OPT_COMP}")
compile_schema_for_test_fbsh(tests/default_vectors_strings_test.fbs "${FLATC_OPT_COMP}")
compile_schema_for_test(tests/arrays_test.fbs "${FLATC_OPT_SCOPED_ENUMS}") compile_schema_for_test(tests/arrays_test.fbs "${FLATC_OPT_SCOPED_ENUMS}")
compile_schema_for_test(tests/native_inline_table_test.fbs "${FLATC_OPT_COMP}") compile_schema_for_test(tests/native_inline_table_test.fbs "${FLATC_OPT_COMP}")
compile_schema_for_test(tests/native_type_test.fbs "${FLATC_OPT}") compile_schema_for_test(tests/native_type_test.fbs "${FLATC_OPT_COMP}")
compile_schema_for_test(tests/key_field/key_field_sample.fbs "${FLATC_OPT_COMP}") compile_schema_for_test(tests/key_field/key_field_sample.fbs "${FLATC_OPT_COMP}")
compile_schema_for_test(tests/64bit/test_64bit.fbs "${FLATC_OPT_COMP};--bfbs-gen-embed") compile_schema_for_test(tests/64bit/test_64bit.fbs "${FLATC_OPT_COMP};--bfbs-gen-embed")
compile_schema_for_test(tests/64bit/evolution/v1.fbs "${FLATC_OPT_COMP}") compile_schema_for_test(tests/64bit/evolution/v1.fbs "${FLATC_OPT_COMP}")
compile_schema_for_test(tests/64bit/evolution/v2.fbs "${FLATC_OPT_COMP}") compile_schema_for_test(tests/64bit/evolution/v2.fbs "${FLATC_OPT_COMP}")
compile_schema_for_test(tests/union_underlying_type_test.fbs "${FLATC_OPT_SCOPED_ENUMS}") compile_schema_for_test(tests/union_underlying_type_test.fbs "${FLATC_OPT_SCOPED_ENUMS}")
compile_schema_for_test(tests/cross_namespace_pack_test.fbs "${FLATC_OPT_COMP}")
if(FLATBUFFERS_CODE_SANITIZE) if(FLATBUFFERS_CODE_SANITIZE)
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE}) add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
@@ -568,8 +581,6 @@ if(FLATBUFFERS_BUILD_TESTS)
# Since flatsample has no sources, we have to explicitly set the linker lang. # Since flatsample has no sources, we have to explicitly set the linker lang.
set_target_properties(flatsample PROPERTIES LINKER_LANGUAGE CXX) set_target_properties(flatsample PROPERTIES LINKER_LANGUAGE CXX)
compile_schema_for_samples(samples/monster.fbs "${FLATC_OPT_COMP}")
target_link_libraries(flatsamplebinary PRIVATE $<BUILD_INTERFACE:ProjectConfig> flatsample) target_link_libraries(flatsamplebinary PRIVATE $<BUILD_INTERFACE:ProjectConfig> flatsample)
target_link_libraries(flatsampletext PRIVATE $<BUILD_INTERFACE:ProjectConfig> flatsample) target_link_libraries(flatsampletext PRIVATE $<BUILD_INTERFACE:ProjectConfig> flatsample)

View File

@@ -30,7 +30,7 @@ Some tips for good pull requests:
* Write a descriptive commit message. What problem are you solving and what * Write a descriptive commit message. What problem are you solving and what
are the consequences? Where and what did you test? Some good tips: are the consequences? Where and what did you test? Some good tips:
[here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message) [here](http://robots.thoughtbot.com/5-useful-tips-for-a-better-commit-message)
and [here](https://www.kernel.org/doc/Documentation/SubmittingPatches). and [here](https://www.kernel.org/doc/Documentation/process/submitting-patches.rst).
* If your PR consists of multiple commits which are successive improvements / * If your PR consists of multiple commits which are successive improvements /
fixes to your first commit, consider squashing them into a single commit fixes to your first commit, consider squashing them into a single commit
(`git rebase -i`) such that your PR is a single commit on top of the current (`git rebase -i`) such that your PR is a single commit on top of the current
@@ -40,3 +40,26 @@ Some tips for good pull requests:
# The small print # The small print
Contributions made by corporations are covered by a different agreement than Contributions made by corporations are covered by a different agreement than
the one above, the Software Grant and Corporate Contributor License Agreement. the one above, the Software Grant and Corporate Contributor License Agreement.
# Code
TL/DR
See [how to build flatc](https://flatbuffers.dev/building/).
When making changes, build `flatc` and then re-generate the goldens files to see the effect of your changes:
```
$ cp build/flatc .
$ goldens/generate_goldens.py
```
Re-generate other code files to see the effects of the changes:
```
$ scripts/generate_code.py
```
Run tests with [TestAll.sh](tests/TestAll.sh) in [tests](tests), or directly any of the sub-scripts run by it.
[Format the code](Formatters.md) before submitting a PR.

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'FlatBuffers' s.name = 'FlatBuffers'
s.version = '25.2.10' s.version = '25.12.19'
s.summary = 'FlatBuffers: Memory Efficient Serialization Library' s.summary = 'FlatBuffers: Memory Efficient Serialization Library'
s.description = "FlatBuffers is a cross platform serialization library architected for s.description = "FlatBuffers is a cross platform serialization library architected for
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
s.ios.deployment_target = '11.0' s.ios.deployment_target = '11.0'
s.osx.deployment_target = '10.14' s.osx.deployment_target = '10.14'
s.swift_version = '5.0' s.swift_version = '5.10'
s.source_files = 'swift/Sources/Flatbuffers/*.swift' s.source_files = 'swift/Sources/Flatbuffers/*.swift'
s.pod_target_xcconfig = { s.pod_target_xcconfig = {
'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES' 'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES'

View File

@@ -19,4 +19,4 @@ Swift uses swiftformat as it's formatter. Take a look at [how to install here](h
## Typescript ## Typescript
Typescript uses eslint as it's linter. Take a look at [how to install here](https://eslint.org/docs/user-guide/getting-started). Run the following command `eslint ts/** --ext .ts` in the root directory of the project Typescript uses eslint as it's linter. Take a look at [how to install here](https://eslint.org/docs/user-guide/getting-started). Run the following command `eslint ts/** --ext .ts` in the root directory of the project

View File

@@ -1,13 +1,13 @@
module( module(
name = "flatbuffers", name = "flatbuffers",
version = "25.2.10", version = "25.12.19",
compatibility_level = 1, compatibility_level = 1,
repo_name = "com_github_google_flatbuffers", repo_name = "com_github_google_flatbuffers",
) )
bazel_dep( bazel_dep(
name = "aspect_bazel_lib", name = "aspect_bazel_lib",
version = "2.11.0", version = "2.14.0",
) )
bazel_dep( bazel_dep(
name = "aspect_rules_esbuild", name = "aspect_rules_esbuild",
@@ -15,24 +15,24 @@ bazel_dep(
) )
bazel_dep( bazel_dep(
name = "aspect_rules_js", name = "aspect_rules_js",
version = "2.1.3", version = "2.3.8",
) )
bazel_dep( bazel_dep(
name = "aspect_rules_ts", name = "aspect_rules_ts",
version = "3.4.0", version = "3.6.0",
) )
bazel_dep( bazel_dep(
name = "grpc", name = "grpc",
version = "1.70.1", version = "1.76.0",
repo_name = "com_github_grpc_grpc", repo_name = "com_github_grpc_grpc",
) )
bazel_dep( bazel_dep(
name = "platforms", name = "platforms",
version = "0.0.10", version = "0.0.11",
) )
bazel_dep( bazel_dep(
name = "rules_cc", name = "rules_cc",
version = "0.0.16", version = "0.1.1",
) )
bazel_dep( bazel_dep(
name = "rules_go", name = "rules_go",
@@ -49,7 +49,8 @@ bazel_dep(
) )
bazel_dep( bazel_dep(
name = "rules_swift", name = "rules_swift",
version = "2.1.1", version = "3.1.2",
max_compatibility_level = 3,
repo_name = "build_bazel_rules_swift", repo_name = "build_bazel_rules_swift",
) )
bazel_dep( bazel_dep(
@@ -62,9 +63,6 @@ npm.npm_translate_lock(
name = "flatbuffers_npm", name = "flatbuffers_npm",
npmrc = "//:.npmrc", npmrc = "//:.npmrc",
pnpm_lock = "//ts:pnpm-lock.yaml", pnpm_lock = "//ts:pnpm-lock.yaml",
# Override the Bazel package where pnpm-lock.yaml is located and link
# to the specified package instead.
root_package = "ts",
verify_node_modules_ignored = "//:.bazelignore", verify_node_modules_ignored = "//:.bazelignore",
) )
use_repo(npm, "flatbuffers_npm") use_repo(npm, "flatbuffers_npm")
@@ -72,6 +70,6 @@ use_repo(npm, "flatbuffers_npm")
node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node")
use_repo(node, "nodejs_linux_amd64") use_repo(node, "nodejs_linux_amd64")
rules_ts_ext = use_extension("@aspect_rules_ts//ts:extensions.bzl", "ext") rules_ts_ext = use_extension("@aspect_rules_ts//ts:extensions.bzl", "ext", dev_dependency = True)
rules_ts_ext.deps() rules_ts_ext.deps()
use_repo(rules_ts_ext, "npm_typescript") use_repo(rules_ts_ext, "npm_typescript")

View File

@@ -1,4 +1,4 @@
// swift-tools-version:5.9 // swift-tools-version:6.0
/* /*
* Copyright 2020 Google Inc. All rights reserved. * Copyright 2020 Google Inc. All rights reserved.
* *
@@ -20,17 +20,79 @@ import PackageDescription
let package = Package( let package = Package(
name: "FlatBuffers", name: "FlatBuffers",
platforms: [ platforms: [
.iOS(.v11), .iOS(.v12),
.macOS(.v10_14), .macOS(.v10_14),
], ],
products: [ products: [
.library( .library(
name: "FlatBuffers", name: "FlatBuffers",
targets: ["FlatBuffers"]), targets: ["FlatBuffers"]),
.library(
name: "FlexBuffers",
targets: ["FlexBuffers"]),
], ],
dependencies: .dependencies,
targets: [ targets: [
.target( .target(
name: "FlatBuffers", name: "FlatBuffers",
dependencies: [], dependencies: ["Common"],
path: "swift/Sources"), path: "swift/Sources/FlatBuffers",
]) swiftSettings: .settings),
.target(
name: "FlexBuffers",
dependencies: ["Common"],
path: "swift/Sources/FlexBuffers",
swiftSettings: .settings),
.target(
name: "Common",
path: "swift/Sources/Common",
swiftSettings: .settings),
.testTarget(
name: "FlatbuffersTests",
dependencies: .dependencies,
path: "tests/swift/Tests/Flatbuffers"),
.testTarget(
name: "FlexbuffersTests",
dependencies: ["FlexBuffers"],
path: "tests/swift/Tests/Flexbuffers"),
],
swiftLanguageModes: [.v6])
extension Array where Element == SwiftSetting {
static var settings: [SwiftSetting] {
[.enableUpcomingFeature("ExistentialAny")]
}
}
extension Array where Element == Package.Dependency {
static var dependencies: [Package.Dependency] {
#if os(Windows)
[]
#else
// Test only Dependency
[
.package(url: "https://github.com/grpc/grpc-swift-2.git", from: "2.0.0"),
.package(
url: "https://github.com/grpc/grpc-swift-nio-transport.git",
from: "2.0.0"),
]
#endif
}
}
extension Array where Element == PackageDescription.Target.Dependency {
static var dependencies: [PackageDescription.Target.Dependency] {
#if os(Windows)
["FlatBuffers"]
#else
// Test only Dependency
[
.product(name: "GRPCCore", package: "grpc-swift-2"),
.product(
name: "GRPCNIOTransportHTTP2",
package: "grpc-swift-nio-transport"),
"FlatBuffers",
]
#endif
}
}

View File

@@ -1,4 +1,4 @@
![logo](http://google.github.io/flatbuffers/fpl_logo_small.png) FlatBuffers ![logo](https://flatbuffers.dev/assets/flatbuffers_logo.svg) FlatBuffers
=========== ===========
![Build status](https://github.com/google/flatbuffers/actions/workflows/build.yml/badge.svg?branch=master) ![Build status](https://github.com/google/flatbuffers/actions/workflows/build.yml/badge.svg?branch=master)
@@ -34,7 +34,7 @@ maximum memory efficiency. It allows you to directly access serialized data with
``` ```
./flatc --cpp --rust monster.fbs ./flatc --cpp --rust monster.fbs
``` ```
Which generates `monster_generated.h` and `monster_generated.rs` files. Which generates `monster_generated.h` and `monster_generated.rs` files.
4. Serialize data 4. Serialize data
@@ -48,7 +48,7 @@ maximum memory efficiency. It allows you to directly access serialized data with
6. Read the data 6. Read the data
Use the generated accessors to read the data from the serialized buffer. Use the generated accessors to read the data from the serialized buffer.
It doesn't need to be the same language/schema version, FlatBuffers ensures the data is readable across languages and schema versions. See the [`Rust` example](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs#L92-L106) reading the data written by `C++`. It doesn't need to be the same language/schema version, FlatBuffers ensures the data is readable across languages and schema versions. See the [`Rust` example](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs#L92-L106) reading the data written by `C++`.
## Documentation ## Documentation

View File

@@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -15,25 +15,27 @@
*/ */
#include <jni.h> #include <jni.h>
#include <string>
#include <search.h> #include <search.h>
#include <string>
#include "generated/animal_generated.h" #include "generated/animal_generated.h"
using namespace com::fbs::app; using namespace com::fbs::app;
using namespace flatbuffers; using namespace flatbuffers;
extern "C" JNIEXPORT jbyteArray JNICALL Java_com_flatbuffers_app_MainActivity_createAnimalFromJNI( extern "C" JNIEXPORT jbyteArray JNICALL
JNIEnv* env, Java_com_flatbuffers_app_MainActivity_createAnimalFromJNI(JNIEnv* env,
jobject /* this */) { jobject /* this */) {
// create a new animal flatbuffers // create a new animal flatbuffers
auto fb = FlatBufferBuilder(1024); auto fb = FlatBufferBuilder(1024);
auto tiger = CreateAnimalDirect(fb, "Tiger", "Roar", 300); auto tiger = CreateAnimalDirect(fb, "Tiger", "Roar", 300);
fb.Finish(tiger); fb.Finish(tiger);
// copies it to a Java byte array. // copies it to a Java byte array.
auto buf = reinterpret_cast<jbyte*>(fb.GetBufferPointer()); auto buf = reinterpret_cast<jbyte*>(fb.GetBufferPointer());
int size = fb.GetSize(); int size = fb.GetSize();
auto ret = env->NewByteArray(size); auto ret = env->NewByteArray(size);
env->SetByteArrayRegion (ret, 0, fb.GetSize(), buf); env->SetByteArrayRegion(ret, 0, fb.GetSize(), buf);
return ret; return ret;
} }

View File

@@ -1,6 +1,5 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_ANIMAL_COM_FBS_APP_H_ #ifndef FLATBUFFERS_GENERATED_ANIMAL_COM_FBS_APP_H_
#define FLATBUFFERS_GENERATED_ANIMAL_COM_FBS_APP_H_ #define FLATBUFFERS_GENERATED_ANIMAL_COM_FBS_APP_H_
@@ -9,9 +8,9 @@
// Ensure the included flatbuffers.h is the same version as when this file was // Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible. // generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && static_assert(FLATBUFFERS_VERSION_MAJOR == 24 &&
FLATBUFFERS_VERSION_MINOR == 12 && FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 23, FLATBUFFERS_VERSION_REVISION == 23,
"Non-compatible flatbuffers version included"); "Non-compatible flatbuffers version included");
namespace com { namespace com {
namespace fbs { namespace fbs {
@@ -27,29 +26,24 @@ struct Animal FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
VT_SOUND = 6, VT_SOUND = 6,
VT_WEIGHT = 8 VT_WEIGHT = 8
}; };
const ::flatbuffers::String *name() const { const ::flatbuffers::String* name() const {
return GetPointer<const ::flatbuffers::String *>(VT_NAME); return GetPointer<const ::flatbuffers::String*>(VT_NAME);
} }
const ::flatbuffers::String *sound() const { const ::flatbuffers::String* sound() const {
return GetPointer<const ::flatbuffers::String *>(VT_SOUND); return GetPointer<const ::flatbuffers::String*>(VT_SOUND);
} }
uint16_t weight() const { uint16_t weight() const { return GetField<uint16_t>(VT_WEIGHT, 0); }
return GetField<uint16_t>(VT_WEIGHT, 0); bool Verify(::flatbuffers::Verifier& verifier) const {
} return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_NAME) &&
bool Verify(::flatbuffers::Verifier &verifier) const { verifier.VerifyString(name()) && VerifyOffset(verifier, VT_SOUND) &&
return VerifyTableStart(verifier) &&
VerifyOffset(verifier, VT_NAME) &&
verifier.VerifyString(name()) &&
VerifyOffset(verifier, VT_SOUND) &&
verifier.VerifyString(sound()) && verifier.VerifyString(sound()) &&
VerifyField<uint16_t>(verifier, VT_WEIGHT, 2) && VerifyField<uint16_t>(verifier, VT_WEIGHT, 2) && verifier.EndTable();
verifier.EndTable();
} }
}; };
struct AnimalBuilder { struct AnimalBuilder {
typedef Animal Table; typedef Animal Table;
::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::FlatBufferBuilder& fbb_;
::flatbuffers::uoffset_t start_; ::flatbuffers::uoffset_t start_;
void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { void add_name(::flatbuffers::Offset<::flatbuffers::String> name) {
fbb_.AddOffset(Animal::VT_NAME, name); fbb_.AddOffset(Animal::VT_NAME, name);
@@ -60,8 +54,7 @@ struct AnimalBuilder {
void add_weight(uint16_t weight) { void add_weight(uint16_t weight) {
fbb_.AddElement<uint16_t>(Animal::VT_WEIGHT, weight, 0); fbb_.AddElement<uint16_t>(Animal::VT_WEIGHT, weight, 0);
} }
explicit AnimalBuilder(::flatbuffers::FlatBufferBuilder &_fbb) explicit AnimalBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) {
: fbb_(_fbb) {
start_ = fbb_.StartTable(); start_ = fbb_.StartTable();
} }
::flatbuffers::Offset<Animal> Finish() { ::flatbuffers::Offset<Animal> Finish() {
@@ -72,7 +65,7 @@ struct AnimalBuilder {
}; };
inline ::flatbuffers::Offset<Animal> CreateAnimal( inline ::flatbuffers::Offset<Animal> CreateAnimal(
::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder& _fbb,
::flatbuffers::Offset<::flatbuffers::String> name = 0, ::flatbuffers::Offset<::flatbuffers::String> name = 0,
::flatbuffers::Offset<::flatbuffers::String> sound = 0, ::flatbuffers::Offset<::flatbuffers::String> sound = 0,
uint16_t weight = 0) { uint16_t weight = 0) {
@@ -84,45 +77,37 @@ inline ::flatbuffers::Offset<Animal> CreateAnimal(
} }
inline ::flatbuffers::Offset<Animal> CreateAnimalDirect( inline ::flatbuffers::Offset<Animal> CreateAnimalDirect(
::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::FlatBufferBuilder& _fbb, const char* name = nullptr,
const char *name = nullptr, const char* sound = nullptr, uint16_t weight = 0) {
const char *sound = nullptr,
uint16_t weight = 0) {
auto name__ = name ? _fbb.CreateString(name) : 0; auto name__ = name ? _fbb.CreateString(name) : 0;
auto sound__ = sound ? _fbb.CreateString(sound) : 0; auto sound__ = sound ? _fbb.CreateString(sound) : 0;
return com::fbs::app::CreateAnimal( return com::fbs::app::CreateAnimal(_fbb, name__, sound__, weight);
_fbb,
name__,
sound__,
weight);
} }
inline const com::fbs::app::Animal *GetAnimal(const void *buf) { inline const com::fbs::app::Animal* GetAnimal(const void* buf) {
return ::flatbuffers::GetRoot<com::fbs::app::Animal>(buf); return ::flatbuffers::GetRoot<com::fbs::app::Animal>(buf);
} }
inline const com::fbs::app::Animal *GetSizePrefixedAnimal(const void *buf) { inline const com::fbs::app::Animal* GetSizePrefixedAnimal(const void* buf) {
return ::flatbuffers::GetSizePrefixedRoot<com::fbs::app::Animal>(buf); return ::flatbuffers::GetSizePrefixedRoot<com::fbs::app::Animal>(buf);
} }
inline bool VerifyAnimalBuffer( inline bool VerifyAnimalBuffer(::flatbuffers::Verifier& verifier) {
::flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<com::fbs::app::Animal>(nullptr); return verifier.VerifyBuffer<com::fbs::app::Animal>(nullptr);
} }
inline bool VerifySizePrefixedAnimalBuffer( inline bool VerifySizePrefixedAnimalBuffer(::flatbuffers::Verifier& verifier) {
::flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<com::fbs::app::Animal>(nullptr); return verifier.VerifySizePrefixedBuffer<com::fbs::app::Animal>(nullptr);
} }
inline void FinishAnimalBuffer( inline void FinishAnimalBuffer(
::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder& fbb,
::flatbuffers::Offset<com::fbs::app::Animal> root) { ::flatbuffers::Offset<com::fbs::app::Animal> root) {
fbb.Finish(root); fbb.Finish(root);
} }
inline void FinishSizePrefixedAnimalBuffer( inline void FinishSizePrefixedAnimalBuffer(
::flatbuffers::FlatBufferBuilder &fbb, ::flatbuffers::FlatBufferBuilder& fbb,
::flatbuffers::Offset<com::fbs::app::Animal> root) { ::flatbuffers::Offset<com::fbs::app::Animal> root) {
fbb.FinishSizePrefixed(root); fbb.FinishSizePrefixed(root);
} }

View File

@@ -1,9 +1,9 @@
package com.flatbuffers.app package com.flatbuffers.app
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle import android.os.Bundle
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import com.fbs.app.Animal import com.fbs.app.Animal
import com.google.flatbuffers.FlatBufferBuilder import com.google.flatbuffers.FlatBufferBuilder
import java.nio.ByteBuffer import java.nio.ByteBuffer
@@ -27,14 +27,15 @@ class MainActivity : AppCompatActivity() {
private external fun createAnimalFromJNI(): ByteArray private external fun createAnimalFromJNI(): ByteArray
// Create a "Cow" Animal flatbuffers from Kotlin // Create a "Cow" Animal flatbuffers from Kotlin
private fun createAnimalFromKotlin():Animal { private fun createAnimalFromKotlin(): Animal {
val fb = FlatBufferBuilder(100) val fb = FlatBufferBuilder(100)
val cowOffset = Animal.createAnimal( val cowOffset =
builder = fb, Animal.createAnimal(
nameOffset = fb.createString("Cow"), builder = fb,
soundOffset = fb.createString("Moo"), nameOffset = fb.createString("Cow"),
weight = 720u soundOffset = fb.createString("Moo"),
) weight = 720u,
)
fb.finish(cowOffset) fb.finish(cowOffset)
return Animal.getRootAsAnimal(fb.dataBuffer()) return Animal.getRootAsAnimal(fb.dataBuffer())
} }

View File

@@ -2,83 +2,101 @@
package com.fbs.app package com.fbs.app
import com.google.flatbuffers.BaseVector
import com.google.flatbuffers.BooleanVector
import com.google.flatbuffers.ByteVector
import com.google.flatbuffers.Constants import com.google.flatbuffers.Constants
import com.google.flatbuffers.DoubleVector
import com.google.flatbuffers.FlatBufferBuilder import com.google.flatbuffers.FlatBufferBuilder
import com.google.flatbuffers.FloatVector
import com.google.flatbuffers.LongVector
import com.google.flatbuffers.StringVector
import com.google.flatbuffers.Struct
import com.google.flatbuffers.Table import com.google.flatbuffers.Table
import com.google.flatbuffers.UnionVector
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.nio.ByteOrder import java.nio.ByteOrder
import kotlin.math.sign
@Suppress("unused") @Suppress("unused")
@kotlin.ExperimentalUnsignedTypes @kotlin.ExperimentalUnsignedTypes
class Animal : Table() { class Animal : Table() {
fun __init(_i: Int, _bb: ByteBuffer) { fun __init(_i: Int, _bb: ByteBuffer) {
__reset(_i, _bb) __reset(_i, _bb)
}
fun __assign(_i: Int, _bb: ByteBuffer): Animal {
__init(_i, _bb)
return this
}
val name: String?
get() {
val o = __offset(4)
return if (o != 0) {
__string(o + bb_pos)
} else {
null
}
} }
fun __assign(_i: Int, _bb: ByteBuffer) : Animal {
__init(_i, _bb) val nameAsByteBuffer: ByteBuffer
return this get() = __vector_as_bytebuffer(4, 1)
fun nameInByteBuffer(_bb: ByteBuffer): ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
val sound: String?
get() {
val o = __offset(6)
return if (o != 0) {
__string(o + bb_pos)
} else {
null
}
} }
val name : String?
get() { val soundAsByteBuffer: ByteBuffer
val o = __offset(4) get() = __vector_as_bytebuffer(6, 1)
return if (o != 0) {
__string(o + bb_pos) fun soundInByteBuffer(_bb: ByteBuffer): ByteBuffer = __vector_in_bytebuffer(_bb, 6, 1)
} else {
null val weight: UShort
} get() {
} val o = __offset(8)
val nameAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(4, 1) return if (o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
fun nameInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 4, 1)
val sound : String?
get() {
val o = __offset(6)
return if (o != 0) {
__string(o + bb_pos)
} else {
null
}
}
val soundAsByteBuffer : ByteBuffer get() = __vector_as_bytebuffer(6, 1)
fun soundInByteBuffer(_bb: ByteBuffer) : ByteBuffer = __vector_in_bytebuffer(_bb, 6, 1)
val weight : UShort
get() {
val o = __offset(8)
return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
}
companion object {
fun validateVersion() = Constants.FLATBUFFERS_25_2_10()
fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal())
fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal {
_bb.order(ByteOrder.LITTLE_ENDIAN)
return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
}
fun createAnimal(builder: FlatBufferBuilder, nameOffset: Int, soundOffset: Int, weight: UShort) : Int {
builder.startTable(3)
addSound(builder, soundOffset)
addName(builder, nameOffset)
addWeight(builder, weight)
return endAnimal(builder)
}
fun startAnimal(builder: FlatBufferBuilder) = builder.startTable(3)
fun addName(builder: FlatBufferBuilder, name: Int) = builder.addOffset(0, name, 0)
fun addSound(builder: FlatBufferBuilder, sound: Int) = builder.addOffset(1, sound, 0)
fun addWeight(builder: FlatBufferBuilder, weight: UShort) = builder.addShort(2, weight.toShort(), 0)
fun endAnimal(builder: FlatBufferBuilder) : Int {
val o = builder.endTable()
return o
}
fun finishAnimalBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset)
fun finishSizePrefixedAnimalBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset)
} }
companion object {
fun validateVersion() = Constants.FLATBUFFERS_25_12_19()
fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal())
fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal {
_bb.order(ByteOrder.LITTLE_ENDIAN)
return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
}
fun createAnimal(
builder: FlatBufferBuilder,
nameOffset: Int,
soundOffset: Int,
weight: UShort,
): Int {
builder.startTable(3)
addSound(builder, soundOffset)
addName(builder, nameOffset)
addWeight(builder, weight)
return endAnimal(builder)
}
fun startAnimal(builder: FlatBufferBuilder) = builder.startTable(3)
fun addName(builder: FlatBufferBuilder, name: Int) = builder.addOffset(0, name, 0)
fun addSound(builder: FlatBufferBuilder, sound: Int) = builder.addOffset(1, sound, 0)
fun addWeight(builder: FlatBufferBuilder, weight: UShort) =
builder.addShort(2, weight.toShort(), 0)
fun endAnimal(builder: FlatBufferBuilder): Int {
val o = builder.endTable()
return o
}
fun finishAnimalBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset)
fun finishSizePrefixedAnimalBuffer(builder: FlatBufferBuilder, offset: Int) =
builder.finishSizePrefixed(offset)
}
} }

View File

@@ -8,12 +8,12 @@ struct Bench {
inline void Add(int64_t value) { sum += value; } inline void Add(int64_t value) { sum += value; }
virtual uint8_t *Encode(void *buf, int64_t &len) = 0; virtual uint8_t* Encode(void* buf, int64_t& len) = 0;
virtual void *Decode(void *buf, int64_t len) = 0; virtual void* Decode(void* buf, int64_t len) = 0;
virtual int64_t Use(void *decoded) = 0; virtual int64_t Use(void* decoded) = 0;
virtual void Dealloc(void *decoded) = 0; virtual void Dealloc(void* decoded) = 0;
int64_t sum = 0; int64_t sum = 0;
}; };
#endif // BENCHMARKS_CPP_BENCH_H_ #endif // BENCHMARKS_CPP_BENCH_H_

View File

@@ -5,8 +5,8 @@
#include "benchmarks/cpp/flatbuffers/fb_bench.h" #include "benchmarks/cpp/flatbuffers/fb_bench.h"
#include "benchmarks/cpp/raw/raw_bench.h" #include "benchmarks/cpp/raw/raw_bench.h"
static inline void Encode(benchmark::State &state, static inline void Encode(benchmark::State& state,
std::unique_ptr<Bench> &bench, uint8_t *buffer) { std::unique_ptr<Bench>& bench, uint8_t* buffer) {
int64_t length; int64_t length;
for (auto _ : state) { for (auto _ : state) {
bench->Encode(buffer, length); bench->Encode(buffer, length);
@@ -14,31 +14,33 @@ static inline void Encode(benchmark::State &state,
} }
} }
static inline void Decode(benchmark::State &state, static inline void Decode(benchmark::State& state,
std::unique_ptr<Bench> &bench, uint8_t *buffer) { std::unique_ptr<Bench>& bench, uint8_t* buffer) {
int64_t length; int64_t length;
uint8_t *encoded = bench->Encode(buffer, length); uint8_t* encoded = bench->Encode(buffer, length);
for (auto _ : state) { for (auto _ : state) {
void *decoded = bench->Decode(encoded, length); void* decoded = bench->Decode(encoded, length);
benchmark::DoNotOptimize(decoded); benchmark::DoNotOptimize(decoded);
} }
} }
static inline void Use(benchmark::State &state, std::unique_ptr<Bench> &bench, static inline void Use(benchmark::State& state, std::unique_ptr<Bench>& bench,
uint8_t *buffer, int64_t check_sum) { uint8_t* buffer, int64_t check_sum) {
int64_t length; int64_t length;
uint8_t *encoded = bench->Encode(buffer, length); uint8_t* encoded = bench->Encode(buffer, length);
void *decoded = bench->Decode(encoded, length); void* decoded = bench->Decode(encoded, length);
int64_t sum = 0; int64_t sum = 0;
for (auto _ : state) { sum = bench->Use(decoded); } for (auto _ : state) {
sum = bench->Use(decoded);
}
EXPECT_EQ(sum, check_sum); EXPECT_EQ(sum, check_sum);
} }
static void BM_Flatbuffers_Encode(benchmark::State &state) { static void BM_Flatbuffers_Encode(benchmark::State& state) {
const int64_t kBufferLength = 1024; const int64_t kBufferLength = 1024;
uint8_t buffer[kBufferLength]; uint8_t buffer[kBufferLength];
@@ -48,7 +50,7 @@ static void BM_Flatbuffers_Encode(benchmark::State &state) {
} }
BENCHMARK(BM_Flatbuffers_Encode); BENCHMARK(BM_Flatbuffers_Encode);
static void BM_Flatbuffers_Decode(benchmark::State &state) { static void BM_Flatbuffers_Decode(benchmark::State& state) {
const int64_t kBufferLength = 1024; const int64_t kBufferLength = 1024;
uint8_t buffer[kBufferLength]; uint8_t buffer[kBufferLength];
@@ -58,7 +60,7 @@ static void BM_Flatbuffers_Decode(benchmark::State &state) {
} }
BENCHMARK(BM_Flatbuffers_Decode); BENCHMARK(BM_Flatbuffers_Decode);
static void BM_Flatbuffers_Use(benchmark::State &state) { static void BM_Flatbuffers_Use(benchmark::State& state) {
const int64_t kBufferLength = 1024; const int64_t kBufferLength = 1024;
uint8_t buffer[kBufferLength]; uint8_t buffer[kBufferLength];
@@ -68,7 +70,7 @@ static void BM_Flatbuffers_Use(benchmark::State &state) {
} }
BENCHMARK(BM_Flatbuffers_Use); BENCHMARK(BM_Flatbuffers_Use);
static void BM_Raw_Encode(benchmark::State &state) { static void BM_Raw_Encode(benchmark::State& state) {
const int64_t kBufferLength = 1024; const int64_t kBufferLength = 1024;
uint8_t buffer[kBufferLength]; uint8_t buffer[kBufferLength];
@@ -77,7 +79,7 @@ static void BM_Raw_Encode(benchmark::State &state) {
} }
BENCHMARK(BM_Raw_Encode); BENCHMARK(BM_Raw_Encode);
static void BM_Raw_Decode(benchmark::State &state) { static void BM_Raw_Decode(benchmark::State& state) {
const int64_t kBufferLength = 1024; const int64_t kBufferLength = 1024;
uint8_t buffer[kBufferLength]; uint8_t buffer[kBufferLength];
@@ -86,7 +88,7 @@ static void BM_Raw_Decode(benchmark::State &state) {
} }
BENCHMARK(BM_Raw_Decode); BENCHMARK(BM_Raw_Decode);
static void BM_Raw_Use(benchmark::State &state) { static void BM_Raw_Use(benchmark::State& state) {
const int64_t kBufferLength = 1024; const int64_t kBufferLength = 1024;
uint8_t buffer[kBufferLength]; uint8_t buffer[kBufferLength];

View File

@@ -1,6 +1,5 @@
// automatically generated by the FlatBuffers compiler, do not modify // automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_BENCH_BENCHMARKS_FLATBUFFERS_H_ #ifndef FLATBUFFERS_GENERATED_BENCH_BENCHMARKS_FLATBUFFERS_H_
#define FLATBUFFERS_GENERATED_BENCH_BENCHMARKS_FLATBUFFERS_H_ #define FLATBUFFERS_GENERATED_BENCH_BENCHMARKS_FLATBUFFERS_H_
@@ -9,9 +8,9 @@
// Ensure the included flatbuffers.h is the same version as when this file was // Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible. // generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && static_assert(FLATBUFFERS_VERSION_MAJOR == 24 &&
FLATBUFFERS_VERSION_MINOR == 12 && FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 23, FLATBUFFERS_VERSION_REVISION == 23,
"Non-compatible flatbuffers version included"); "Non-compatible flatbuffers version included");
namespace benchmarks_flatbuffers { namespace benchmarks_flatbuffers {
@@ -34,25 +33,16 @@ enum Enum : int16_t {
}; };
inline const Enum (&EnumValuesEnum())[3] { inline const Enum (&EnumValuesEnum())[3] {
static const Enum values[] = { static const Enum values[] = {Enum_Apples, Enum_Pears, Enum_Bananas};
Enum_Apples,
Enum_Pears,
Enum_Bananas
};
return values; return values;
} }
inline const char * const *EnumNamesEnum() { inline const char* const* EnumNamesEnum() {
static const char * const names[4] = { static const char* const names[4] = {"Apples", "Pears", "Bananas", nullptr};
"Apples",
"Pears",
"Bananas",
nullptr
};
return names; return names;
} }
inline const char *EnumNameEnum(Enum e) { inline const char* EnumNameEnum(Enum e) {
if (flatbuffers::IsOutRange(e, Enum_Apples, Enum_Bananas)) return ""; if (flatbuffers::IsOutRange(e, Enum_Apples, Enum_Bananas)) return "";
const size_t index = static_cast<size_t>(e); const size_t index = static_cast<size_t>(e);
return EnumNamesEnum()[index]; return EnumNamesEnum()[index];
@@ -67,12 +57,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Foo FLATBUFFERS_FINAL_CLASS {
uint32_t length_; uint32_t length_;
public: public:
Foo() Foo() : id_(0), count_(0), prefix_(0), padding0__(0), length_(0) {
: id_(0),
count_(0),
prefix_(0),
padding0__(0),
length_(0) {
(void)padding0__; (void)padding0__;
} }
Foo(uint64_t _id, int16_t _count, int8_t _prefix, uint32_t _length) Foo(uint64_t _id, int16_t _count, int8_t _prefix, uint32_t _length)
@@ -83,18 +68,10 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Foo FLATBUFFERS_FINAL_CLASS {
length_(flatbuffers::EndianScalar(_length)) { length_(flatbuffers::EndianScalar(_length)) {
(void)padding0__; (void)padding0__;
} }
uint64_t id() const { uint64_t id() const { return flatbuffers::EndianScalar(id_); }
return flatbuffers::EndianScalar(id_); int16_t count() const { return flatbuffers::EndianScalar(count_); }
} int8_t prefix() const { return flatbuffers::EndianScalar(prefix_); }
int16_t count() const { uint32_t length() const { return flatbuffers::EndianScalar(length_); }
return flatbuffers::EndianScalar(count_);
}
int8_t prefix() const {
return flatbuffers::EndianScalar(prefix_);
}
uint32_t length() const {
return flatbuffers::EndianScalar(length_);
}
}; };
FLATBUFFERS_STRUCT_END(Foo, 16); FLATBUFFERS_STRUCT_END(Foo, 16);
@@ -104,20 +81,17 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Bar FLATBUFFERS_FINAL_CLASS {
int32_t time_; int32_t time_;
float ratio_; float ratio_;
uint16_t size_; uint16_t size_;
int16_t padding0__; int32_t padding1__; int16_t padding0__;
int32_t padding1__;
public: public:
Bar() Bar()
: parent_(), : parent_(), time_(0), ratio_(0), size_(0), padding0__(0), padding1__(0) {
time_(0),
ratio_(0),
size_(0),
padding0__(0),
padding1__(0) {
(void)padding0__; (void)padding0__;
(void)padding1__; (void)padding1__;
} }
Bar(const benchmarks_flatbuffers::Foo &_parent, int32_t _time, float _ratio, uint16_t _size) Bar(const benchmarks_flatbuffers::Foo& _parent, int32_t _time, float _ratio,
uint16_t _size)
: parent_(_parent), : parent_(_parent),
time_(flatbuffers::EndianScalar(_time)), time_(flatbuffers::EndianScalar(_time)),
ratio_(flatbuffers::EndianScalar(_ratio)), ratio_(flatbuffers::EndianScalar(_ratio)),
@@ -127,18 +101,10 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Bar FLATBUFFERS_FINAL_CLASS {
(void)padding0__; (void)padding0__;
(void)padding1__; (void)padding1__;
} }
const benchmarks_flatbuffers::Foo &parent() const { const benchmarks_flatbuffers::Foo& parent() const { return parent_; }
return parent_; int32_t time() const { return flatbuffers::EndianScalar(time_); }
} float ratio() const { return flatbuffers::EndianScalar(ratio_); }
int32_t time() const { uint16_t size() const { return flatbuffers::EndianScalar(size_); }
return flatbuffers::EndianScalar(time_);
}
float ratio() const {
return flatbuffers::EndianScalar(ratio_);
}
uint16_t size() const {
return flatbuffers::EndianScalar(size_);
}
}; };
FLATBUFFERS_STRUCT_END(Bar, 32); FLATBUFFERS_STRUCT_END(Bar, 32);
@@ -150,34 +116,28 @@ struct FooBar FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_RATING = 8, VT_RATING = 8,
VT_POSTFIX = 10 VT_POSTFIX = 10
}; };
const benchmarks_flatbuffers::Bar *sibling() const { const benchmarks_flatbuffers::Bar* sibling() const {
return GetStruct<const benchmarks_flatbuffers::Bar *>(VT_SIBLING); return GetStruct<const benchmarks_flatbuffers::Bar*>(VT_SIBLING);
} }
const flatbuffers::String *name() const { const flatbuffers::String* name() const {
return GetPointer<const flatbuffers::String *>(VT_NAME); return GetPointer<const flatbuffers::String*>(VT_NAME);
} }
double rating() const { double rating() const { return GetField<double>(VT_RATING, 0.0); }
return GetField<double>(VT_RATING, 0.0); uint8_t postfix() const { return GetField<uint8_t>(VT_POSTFIX, 0); }
} bool Verify(flatbuffers::Verifier& verifier) const {
uint8_t postfix() const {
return GetField<uint8_t>(VT_POSTFIX, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
VerifyField<benchmarks_flatbuffers::Bar>(verifier, VT_SIBLING, 8) && VerifyField<benchmarks_flatbuffers::Bar>(verifier, VT_SIBLING, 8) &&
VerifyOffset(verifier, VT_NAME) && VerifyOffset(verifier, VT_NAME) && verifier.VerifyString(name()) &&
verifier.VerifyString(name()) &&
VerifyField<double>(verifier, VT_RATING, 8) && VerifyField<double>(verifier, VT_RATING, 8) &&
VerifyField<uint8_t>(verifier, VT_POSTFIX, 1) && VerifyField<uint8_t>(verifier, VT_POSTFIX, 1) && verifier.EndTable();
verifier.EndTable();
} }
}; };
struct FooBarBuilder { struct FooBarBuilder {
typedef FooBar Table; typedef FooBar Table;
flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::FlatBufferBuilder& fbb_;
flatbuffers::uoffset_t start_; flatbuffers::uoffset_t start_;
void add_sibling(const benchmarks_flatbuffers::Bar *sibling) { void add_sibling(const benchmarks_flatbuffers::Bar* sibling) {
fbb_.AddStruct(FooBar::VT_SIBLING, sibling); fbb_.AddStruct(FooBar::VT_SIBLING, sibling);
} }
void add_name(flatbuffers::Offset<flatbuffers::String> name) { void add_name(flatbuffers::Offset<flatbuffers::String> name) {
@@ -189,8 +149,7 @@ struct FooBarBuilder {
void add_postfix(uint8_t postfix) { void add_postfix(uint8_t postfix) {
fbb_.AddElement<uint8_t>(FooBar::VT_POSTFIX, postfix, 0); fbb_.AddElement<uint8_t>(FooBar::VT_POSTFIX, postfix, 0);
} }
explicit FooBarBuilder(flatbuffers::FlatBufferBuilder &_fbb) explicit FooBarBuilder(flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) {
: fbb_(_fbb) {
start_ = fbb_.StartTable(); start_ = fbb_.StartTable();
} }
flatbuffers::Offset<FooBar> Finish() { flatbuffers::Offset<FooBar> Finish() {
@@ -201,10 +160,9 @@ struct FooBarBuilder {
}; };
inline flatbuffers::Offset<FooBar> CreateFooBar( inline flatbuffers::Offset<FooBar> CreateFooBar(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder& _fbb,
const benchmarks_flatbuffers::Bar *sibling = nullptr, const benchmarks_flatbuffers::Bar* sibling = nullptr,
flatbuffers::Offset<flatbuffers::String> name = 0, flatbuffers::Offset<flatbuffers::String> name = 0, double rating = 0.0,
double rating = 0.0,
uint8_t postfix = 0) { uint8_t postfix = 0) {
FooBarBuilder builder_(_fbb); FooBarBuilder builder_(_fbb);
builder_.add_rating(rating); builder_.add_rating(rating);
@@ -215,18 +173,12 @@ inline flatbuffers::Offset<FooBar> CreateFooBar(
} }
inline flatbuffers::Offset<FooBar> CreateFooBarDirect( inline flatbuffers::Offset<FooBar> CreateFooBarDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder& _fbb,
const benchmarks_flatbuffers::Bar *sibling = nullptr, const benchmarks_flatbuffers::Bar* sibling = nullptr,
const char *name = nullptr, const char* name = nullptr, double rating = 0.0, uint8_t postfix = 0) {
double rating = 0.0,
uint8_t postfix = 0) {
auto name__ = name ? _fbb.CreateString(name) : 0; auto name__ = name ? _fbb.CreateString(name) : 0;
return benchmarks_flatbuffers::CreateFooBar( return benchmarks_flatbuffers::CreateFooBar(_fbb, sibling, name__, rating,
_fbb, postfix);
sibling,
name__,
rating,
postfix);
} }
struct FooBarContainer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { struct FooBarContainer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
@@ -237,49 +189,53 @@ struct FooBarContainer FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_FRUIT = 8, VT_FRUIT = 8,
VT_LOCATION = 10 VT_LOCATION = 10
}; };
const flatbuffers::Vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>> *list() const { const flatbuffers::Vector<
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>> *>(VT_LIST); flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>*
} list() const {
bool initialized() const { return GetPointer<const flatbuffers::Vector<
return GetField<uint8_t>(VT_INITIALIZED, 0) != 0; flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>*>(VT_LIST);
} }
bool initialized() const { return GetField<uint8_t>(VT_INITIALIZED, 0) != 0; }
benchmarks_flatbuffers::Enum fruit() const { benchmarks_flatbuffers::Enum fruit() const {
return static_cast<benchmarks_flatbuffers::Enum>(GetField<int16_t>(VT_FRUIT, 0)); return static_cast<benchmarks_flatbuffers::Enum>(
GetField<int16_t>(VT_FRUIT, 0));
} }
const flatbuffers::String *location() const { const flatbuffers::String* location() const {
return GetPointer<const flatbuffers::String *>(VT_LOCATION); return GetPointer<const flatbuffers::String*>(VT_LOCATION);
} }
bool Verify(flatbuffers::Verifier &verifier) const { bool Verify(flatbuffers::Verifier& verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_LIST) &&
VerifyOffset(verifier, VT_LIST) &&
verifier.VerifyVector(list()) && verifier.VerifyVector(list()) &&
verifier.VerifyVectorOfTables(list()) && verifier.VerifyVectorOfTables(list()) &&
VerifyField<uint8_t>(verifier, VT_INITIALIZED, 1) && VerifyField<uint8_t>(verifier, VT_INITIALIZED, 1) &&
VerifyField<int16_t>(verifier, VT_FRUIT, 2) && VerifyField<int16_t>(verifier, VT_FRUIT, 2) &&
VerifyOffset(verifier, VT_LOCATION) && VerifyOffset(verifier, VT_LOCATION) &&
verifier.VerifyString(location()) && verifier.VerifyString(location()) && verifier.EndTable();
verifier.EndTable();
} }
}; };
struct FooBarContainerBuilder { struct FooBarContainerBuilder {
typedef FooBarContainer Table; typedef FooBarContainer Table;
flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::FlatBufferBuilder& fbb_;
flatbuffers::uoffset_t start_; flatbuffers::uoffset_t start_;
void add_list(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>> list) { void add_list(flatbuffers::Offset<flatbuffers::Vector<
flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>>
list) {
fbb_.AddOffset(FooBarContainer::VT_LIST, list); fbb_.AddOffset(FooBarContainer::VT_LIST, list);
} }
void add_initialized(bool initialized) { void add_initialized(bool initialized) {
fbb_.AddElement<uint8_t>(FooBarContainer::VT_INITIALIZED, static_cast<uint8_t>(initialized), 0); fbb_.AddElement<uint8_t>(FooBarContainer::VT_INITIALIZED,
static_cast<uint8_t>(initialized), 0);
} }
void add_fruit(benchmarks_flatbuffers::Enum fruit) { void add_fruit(benchmarks_flatbuffers::Enum fruit) {
fbb_.AddElement<int16_t>(FooBarContainer::VT_FRUIT, static_cast<int16_t>(fruit), 0); fbb_.AddElement<int16_t>(FooBarContainer::VT_FRUIT,
static_cast<int16_t>(fruit), 0);
} }
void add_location(flatbuffers::Offset<flatbuffers::String> location) { void add_location(flatbuffers::Offset<flatbuffers::String> location) {
fbb_.AddOffset(FooBarContainer::VT_LOCATION, location); fbb_.AddOffset(FooBarContainer::VT_LOCATION, location);
} }
explicit FooBarContainerBuilder(flatbuffers::FlatBufferBuilder &_fbb) explicit FooBarContainerBuilder(flatbuffers::FlatBufferBuilder& _fbb)
: fbb_(_fbb) { : fbb_(_fbb) {
start_ = fbb_.StartTable(); start_ = fbb_.StartTable();
} }
flatbuffers::Offset<FooBarContainer> Finish() { flatbuffers::Offset<FooBarContainer> Finish() {
@@ -290,8 +246,10 @@ struct FooBarContainerBuilder {
}; };
inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainer( inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainer(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder& _fbb,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>> list = 0, flatbuffers::Offset<flatbuffers::Vector<
flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>>
list = 0,
bool initialized = false, bool initialized = false,
benchmarks_flatbuffers::Enum fruit = benchmarks_flatbuffers::Enum_Apples, benchmarks_flatbuffers::Enum fruit = benchmarks_flatbuffers::Enum_Apples,
flatbuffers::Offset<flatbuffers::String> location = 0) { flatbuffers::Offset<flatbuffers::String> location = 0) {
@@ -304,47 +262,52 @@ inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainer(
} }
inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainerDirect( inline flatbuffers::Offset<FooBarContainer> CreateFooBarContainerDirect(
flatbuffers::FlatBufferBuilder &_fbb, flatbuffers::FlatBufferBuilder& _fbb,
const std::vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>> *list = nullptr, const std::vector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>*
list = nullptr,
bool initialized = false, bool initialized = false,
benchmarks_flatbuffers::Enum fruit = benchmarks_flatbuffers::Enum_Apples, benchmarks_flatbuffers::Enum fruit = benchmarks_flatbuffers::Enum_Apples,
const char *location = nullptr) { const char* location = nullptr) {
auto list__ = list ? _fbb.CreateVector<flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>(*list) : 0; auto list__ =
list ? _fbb.CreateVector<
flatbuffers::Offset<benchmarks_flatbuffers::FooBar>>(*list)
: 0;
auto location__ = location ? _fbb.CreateString(location) : 0; auto location__ = location ? _fbb.CreateString(location) : 0;
return benchmarks_flatbuffers::CreateFooBarContainer( return benchmarks_flatbuffers::CreateFooBarContainer(
_fbb, _fbb, list__, initialized, fruit, location__);
list__,
initialized,
fruit,
location__);
} }
inline const benchmarks_flatbuffers::FooBarContainer *GetFooBarContainer(const void *buf) { inline const benchmarks_flatbuffers::FooBarContainer* GetFooBarContainer(
const void* buf) {
return flatbuffers::GetRoot<benchmarks_flatbuffers::FooBarContainer>(buf); return flatbuffers::GetRoot<benchmarks_flatbuffers::FooBarContainer>(buf);
} }
inline const benchmarks_flatbuffers::FooBarContainer *GetSizePrefixedFooBarContainer(const void *buf) { inline const benchmarks_flatbuffers::FooBarContainer*
return flatbuffers::GetSizePrefixedRoot<benchmarks_flatbuffers::FooBarContainer>(buf); GetSizePrefixedFooBarContainer(const void* buf) {
return flatbuffers::GetSizePrefixedRoot<
benchmarks_flatbuffers::FooBarContainer>(buf);
} }
inline bool VerifyFooBarContainerBuffer( inline bool VerifyFooBarContainerBuffer(flatbuffers::Verifier& verifier) {
flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<benchmarks_flatbuffers::FooBarContainer>(
return verifier.VerifyBuffer<benchmarks_flatbuffers::FooBarContainer>(nullptr); nullptr);
} }
inline bool VerifySizePrefixedFooBarContainerBuffer( inline bool VerifySizePrefixedFooBarContainerBuffer(
flatbuffers::Verifier &verifier) { flatbuffers::Verifier& verifier) {
return verifier.VerifySizePrefixedBuffer<benchmarks_flatbuffers::FooBarContainer>(nullptr); return verifier
.VerifySizePrefixedBuffer<benchmarks_flatbuffers::FooBarContainer>(
nullptr);
} }
inline void FinishFooBarContainerBuffer( inline void FinishFooBarContainerBuffer(
flatbuffers::FlatBufferBuilder &fbb, flatbuffers::FlatBufferBuilder& fbb,
flatbuffers::Offset<benchmarks_flatbuffers::FooBarContainer> root) { flatbuffers::Offset<benchmarks_flatbuffers::FooBarContainer> root) {
fbb.Finish(root); fbb.Finish(root);
} }
inline void FinishSizePrefixedFooBarContainerBuffer( inline void FinishSizePrefixedFooBarContainerBuffer(
flatbuffers::FlatBufferBuilder &fbb, flatbuffers::FlatBufferBuilder& fbb,
flatbuffers::Offset<benchmarks_flatbuffers::FooBarContainer> root) { flatbuffers::Offset<benchmarks_flatbuffers::FooBarContainer> root) {
fbb.FinishSizePrefixed(root); fbb.FinishSizePrefixed(root);
} }

View File

@@ -13,10 +13,10 @@ using namespace benchmarks_flatbuffers;
namespace { namespace {
struct FlatBufferBench : Bench { struct FlatBufferBench : Bench {
explicit FlatBufferBench(int64_t initial_size, Allocator *allocator) explicit FlatBufferBench(int64_t initial_size, Allocator* allocator)
: fbb(initial_size, allocator, false) {} : fbb(initial_size, allocator, false) {}
uint8_t *Encode(void *, int64_t &len) override { uint8_t* Encode(void*, int64_t& len) override {
fbb.Clear(); fbb.Clear();
const int kVectorLength = 3; const int kVectorLength = 3;
@@ -40,7 +40,7 @@ struct FlatBufferBench : Bench {
return fbb.GetBufferPointer(); return fbb.GetBufferPointer();
} }
int64_t Use(void *decoded) override { int64_t Use(void* decoded) override {
sum = 0; sum = 0;
auto foobarcontainer = GetFooBarContainer(decoded); auto foobarcontainer = GetFooBarContainer(decoded);
sum = 0; sum = 0;
@@ -56,7 +56,7 @@ struct FlatBufferBench : Bench {
Add(static_cast<int64_t>(bar->ratio())); Add(static_cast<int64_t>(bar->ratio()));
Add(bar->size()); Add(bar->size());
Add(bar->time()); Add(bar->time());
auto &foo = bar->parent(); auto& foo = bar->parent();
Add(foo.count()); Add(foo.count());
Add(foo.id()); Add(foo.id());
Add(foo.length()); Add(foo.length());
@@ -65,8 +65,8 @@ struct FlatBufferBench : Bench {
return sum; return sum;
} }
void *Decode(void *buffer, int64_t) override { return buffer; } void* Decode(void* buffer, int64_t) override { return buffer; }
void Dealloc(void *) override {}; void Dealloc(void*) override {};
FlatBufferBuilder fbb; FlatBufferBuilder fbb;
}; };
@@ -74,7 +74,7 @@ struct FlatBufferBench : Bench {
} // namespace } // namespace
std::unique_ptr<Bench> NewFlatBuffersBench(int64_t initial_size, std::unique_ptr<Bench> NewFlatBuffersBench(int64_t initial_size,
Allocator *allocator) { Allocator* allocator) {
return std::unique_ptr<FlatBufferBench>( return std::unique_ptr<FlatBufferBench>(
new FlatBufferBench(initial_size, allocator)); new FlatBufferBench(initial_size, allocator));
} }

View File

@@ -8,16 +8,16 @@
#include "include/flatbuffers/flatbuffers.h" #include "include/flatbuffers/flatbuffers.h"
struct StaticAllocator : public flatbuffers::Allocator { struct StaticAllocator : public flatbuffers::Allocator {
explicit StaticAllocator(uint8_t *buffer) : buffer_(buffer) {} explicit StaticAllocator(uint8_t* buffer) : buffer_(buffer) {}
uint8_t *allocate(size_t) override { return buffer_; } uint8_t* allocate(size_t) override { return buffer_; }
void deallocate(uint8_t *, size_t) override {} void deallocate(uint8_t*, size_t) override {}
uint8_t *buffer_; uint8_t* buffer_;
}; };
std::unique_ptr<Bench> NewFlatBuffersBench( std::unique_ptr<Bench> NewFlatBuffersBench(
int64_t initial_size = 1024, flatbuffers::Allocator *allocator = nullptr); int64_t initial_size = 1024, flatbuffers::Allocator* allocator = nullptr);
#endif // BENCHMARKS_CPP_FLATBUFFERS_FB_BENCH_H_ #endif // BENCHMARKS_CPP_FLATBUFFERS_FB_BENCH_H_

View File

@@ -45,8 +45,8 @@ struct FooBarContainer {
}; };
struct RawBench : Bench { struct RawBench : Bench {
uint8_t *Encode(void *buf, int64_t &len) override { uint8_t* Encode(void* buf, int64_t& len) override {
FooBarContainer *fbc = new (buf) FooBarContainer; FooBarContainer* fbc = new (buf) FooBarContainer;
strcpy(fbc->location, "http://google.com/flatbuffers/"); // Unsafe eek! strcpy(fbc->location, "http://google.com/flatbuffers/"); // Unsafe eek!
fbc->location_len = (int)strlen(fbc->location); fbc->location_len = (int)strlen(fbc->location);
fbc->fruit = Bananas; fbc->fruit = Bananas;
@@ -54,16 +54,16 @@ struct RawBench : Bench {
for (int i = 0; i < kVectorLength; i++) { for (int i = 0; i < kVectorLength; i++) {
// We add + i to not make these identical copies for a more realistic // We add + i to not make these identical copies for a more realistic
// compression test. // compression test.
auto &foobar = fbc->list[i]; auto& foobar = fbc->list[i];
foobar.rating = 3.1415432432445543543 + i; foobar.rating = 3.1415432432445543543 + i;
foobar.postfix = '!' + i; foobar.postfix = '!' + i;
strcpy(foobar.name, "Hello, World!"); strcpy(foobar.name, "Hello, World!");
foobar.name_len = (int)strlen(foobar.name); foobar.name_len = (int)strlen(foobar.name);
auto &bar = foobar.sibling; auto& bar = foobar.sibling;
bar.ratio = 3.14159f + i; bar.ratio = 3.14159f + i;
bar.size = 10000 + i; bar.size = 10000 + i;
bar.time = 123456 + i; bar.time = 123456 + i;
auto &foo = bar.parent; auto& foo = bar.parent;
foo.id = 0xABADCAFEABADCAFE + i; foo.id = 0xABADCAFEABADCAFE + i;
foo.count = 10000 + i; foo.count = 10000 + i;
foo.length = 1000000 + i; foo.length = 1000000 + i;
@@ -71,11 +71,11 @@ struct RawBench : Bench {
} }
len = sizeof(FooBarContainer); len = sizeof(FooBarContainer);
return reinterpret_cast<uint8_t *>(fbc); return reinterpret_cast<uint8_t*>(fbc);
}; };
int64_t Use(void *decoded) override { int64_t Use(void* decoded) override {
auto foobarcontainer = reinterpret_cast<FooBarContainer *>(decoded); auto foobarcontainer = reinterpret_cast<FooBarContainer*>(decoded);
sum = 0; sum = 0;
Add(foobarcontainer->initialized); Add(foobarcontainer->initialized);
Add(foobarcontainer->location_len); Add(foobarcontainer->location_len);
@@ -89,7 +89,7 @@ struct RawBench : Bench {
Add(static_cast<int64_t>(bar->ratio)); Add(static_cast<int64_t>(bar->ratio));
Add(bar->size); Add(bar->size);
Add(bar->time); Add(bar->time);
auto &foo = bar->parent; auto& foo = bar->parent;
Add(foo.count); Add(foo.count);
Add(foo.id); Add(foo.id);
Add(foo.length); Add(foo.length);
@@ -98,8 +98,8 @@ struct RawBench : Bench {
return sum; return sum;
} }
void *Decode(void *buf, int64_t) override { return buf; } void* Decode(void* buf, int64_t) override { return buf; }
void Dealloc(void *) override{}; void Dealloc(void*) override {};
}; };
} // namespace } // namespace

View File

@@ -15,8 +15,8 @@
*/ */
import Benchmark import Benchmark
import CoreFoundation
import FlatBuffers import FlatBuffers
import Foundation
@usableFromInline @usableFromInline
struct AA: NativeStruct { struct AA: NativeStruct {
@@ -29,6 +29,15 @@ struct AA: NativeStruct {
} }
let benchmarks = { let benchmarks = {
let oneGB: Int32 = 1_024_000_000
let data = {
var array = [8888.88, 8888.88]
var data = Data()
array.withUnsafeBytes { ptr in
data.append(contentsOf: ptr)
}
return data
}()
let ints: [Int] = Array(repeating: 42, count: 100) let ints: [Int] = Array(repeating: 42, count: 100)
let bytes: [UInt8] = Array(repeating: 42, count: 100) let bytes: [UInt8] = Array(repeating: 42, count: 100)
let str10 = (0...9).map { _ -> String in "x" }.joined() let str10 = (0...9).map { _ -> String in "x" }.joined()
@@ -73,12 +82,25 @@ let benchmarks = {
Benchmark("Allocating 1GB", configuration: singleConfiguration) { benchmark in Benchmark("Allocating 1GB", configuration: singleConfiguration) { benchmark in
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(FlatBufferBuilder(initialSize: 1_024_000_000)) blackHole(FlatBufferBuilder(initialSize: oneGB))
}
}
Benchmark(
"Allocating ByteBuffer 1GB",
configuration: singleConfiguration)
{ benchmark in
let memory = UnsafeMutableRawPointer.allocate(
byteCount: 1_024_000_000,
alignment: 1)
benchmark.startMeasurement()
for _ in benchmark.scaledIterations {
blackHole(ByteBuffer(assumingMemoryBound: memory, capacity: Int(oneGB)))
} }
} }
Benchmark("Clearing 1GB", configuration: singleConfiguration) { benchmark in Benchmark("Clearing 1GB", configuration: singleConfiguration) { benchmark in
var fb = FlatBufferBuilder(initialSize: 1_024_000_000) var fb = FlatBufferBuilder(initialSize: oneGB)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.clear()) blackHole(fb.clear())
@@ -86,7 +108,7 @@ let benchmarks = {
} }
Benchmark("Strings 10") { benchmark in Benchmark("Strings 10") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.create(string: str10)) blackHole(fb.create(string: str10))
@@ -94,7 +116,7 @@ let benchmarks = {
} }
Benchmark("Strings 100") { benchmark in Benchmark("Strings 100") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.create(string: str100)) blackHole(fb.create(string: str100))
@@ -102,7 +124,7 @@ let benchmarks = {
} }
Benchmark("Vector 1 Bytes") { benchmark in Benchmark("Vector 1 Bytes") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.createVector(bytes: bytes)) blackHole(fb.createVector(bytes: bytes))
@@ -110,7 +132,7 @@ let benchmarks = {
} }
Benchmark("Vector 1 Ints") { benchmark in Benchmark("Vector 1 Ints") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for _ in benchmark.scaledIterations { for _ in benchmark.scaledIterations {
blackHole(fb.createVector(ints)) blackHole(fb.createVector(ints))
@@ -118,7 +140,7 @@ let benchmarks = {
} }
Benchmark("Vector 100 Ints") { benchmark in Benchmark("Vector 100 Ints") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for i in benchmark.scaledIterations { for i in benchmark.scaledIterations {
blackHole(fb.createVector(ints)) blackHole(fb.createVector(ints))
@@ -126,7 +148,7 @@ let benchmarks = {
} }
Benchmark("Vector 100 Bytes") { benchmark in Benchmark("Vector 100 Bytes") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for i in benchmark.scaledIterations { for i in benchmark.scaledIterations {
blackHole(fb.createVector(bytes)) blackHole(fb.createVector(bytes))
@@ -134,7 +156,7 @@ let benchmarks = {
} }
Benchmark("Vector 100 ContiguousBytes") { benchmark in Benchmark("Vector 100 ContiguousBytes") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1<<20) var fb = FlatBufferBuilder(initialSize: 1 << 20)
benchmark.startMeasurement() benchmark.startMeasurement()
for i in benchmark.scaledIterations { for i in benchmark.scaledIterations {
blackHole(fb.createVector(bytes: bytes)) blackHole(fb.createVector(bytes: bytes))
@@ -158,6 +180,26 @@ let benchmarks = {
} }
} }
Benchmark(
"FlatBufferBuilder Start table",
configuration: kiloConfiguration)
{ benchmark in
var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
benchmark.startMeasurement()
for _ in benchmark.scaledIterations {
let s = fb.startTable(with: 4)
blackHole(fb.endTable(at: s))
}
}
Benchmark("Struct") { benchmark in
var fb = FlatBufferBuilder(initialSize: 1024 * 1024 * 32)
benchmark.startMeasurement()
for _ in benchmark.scaledIterations {
blackHole(fb.create(struct: array.first!))
}
}
Benchmark("Structs") { benchmark in Benchmark("Structs") { benchmark in
let rawSize = ((16 * 5) * benchmark.scaledIterations.count) / 1024 let rawSize = ((16 * 5) * benchmark.scaledIterations.count) / 1024
var fb = FlatBufferBuilder(initialSize: Int32(rawSize * 1600)) var fb = FlatBufferBuilder(initialSize: Int32(rawSize * 1600))
@@ -176,7 +218,7 @@ let benchmarks = {
let start = fb.startTable(with: 1) let start = fb.startTable(with: 1)
fb.add(offset: vector, at: 4) fb.add(offset: vector, at: 4)
let root = Offset(offset: fb.endTable(at: start)) let root = Offset(offset: fb.endTable(at: start))
fb.finish(offset: root) blackHole(fb.finish(offset: root))
} }
Benchmark("Vector of Offsets") { benchmark in Benchmark("Vector of Offsets") { benchmark in
@@ -198,4 +240,11 @@ let benchmarks = {
blackHole(fb.endTable(at: s)) blackHole(fb.endTable(at: s))
} }
} }
Benchmark("Reading Doubles") { benchmark in
let byteBuffer = ByteBuffer(data: data)
for _ in benchmark.scaledIterations {
blackHole(byteBuffer.read(def: Double.self, position: 0))
}
}
} }

View File

@@ -1,4 +1,4 @@
// swift-tools-version:5.9 // swift-tools-version:5.10
/* /*
* Copyright 2020 Google Inc. All rights reserved. * Copyright 2020 Google Inc. All rights reserved.
* *

View File

@@ -6,4 +6,4 @@ To open the benchmarks in xcode use:
or running them directly within terminal using: or running them directly within terminal using:
`swift package benchmark` `swift package benchmark`

View File

@@ -187,6 +187,7 @@ def flatbuffer_cc_library(
visibility = None, visibility = None,
compatible_with = None, compatible_with = None,
restricted_to = None, restricted_to = None,
filename_suffix = "_generated",
target_compatible_with = None, target_compatible_with = None,
srcs_filegroup_visibility = None, srcs_filegroup_visibility = None,
gen_reflections = False): gen_reflections = False):
@@ -230,10 +231,13 @@ def flatbuffer_cc_library(
Fileset([name]_reflection): (Optional) all generated reflection binaries. Fileset([name]_reflection): (Optional) all generated reflection binaries.
cc_library([name]): library with sources and flatbuffers deps. cc_library([name]): library with sources and flatbuffers deps.
""" """
output_headers = [
(out_prefix + "%s_generated.h") % (s.replace(".fbs", "").split("/")[-1].split(":")[-1]) output_headers = []
for s in srcs for s in srcs:
] base_name = s.split("/")[-1].split(":")[-1].replace(".fbs", "")
header = out_prefix + base_name + filename_suffix + ".h"
output_headers.append(header)
if deps and includes: if deps and includes:
# There is no inherent reason we couldn't support both, but this discourages # There is no inherent reason we couldn't support both, but this discourages
# use of includes without good reason. # use of includes without good reason.

View File

@@ -1,12 +0,0 @@
cmake_minimum_required(VERSION 2.8)
message(STATUS "Conan FlatBuffers Wrapper")
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
if (WIN32 AND MSVC_LIKE AND FLATBUFFERS_BUILD_SHAREDLIB)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif(WIN32 AND MSVC_LIKE AND FLATBUFFERS_BUILD_SHAREDLIB)
include(${CMAKE_SOURCE_DIR}/CMakeListsOriginal.txt)

View File

@@ -1,50 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import re
import subprocess
from cpt.packager import ConanMultiPackager
def get_branch():
try:
for line in subprocess.check_output("git branch", shell=True).decode().splitlines():
line = line.strip()
if line.startswith("*") and " (HEAD detached" not in line:
return line.replace("*", "", 1).strip()
return ""
except Exception:
pass
return ""
def get_version():
version = get_branch()
match = re.search(r"v(\d+\.\d+\.\d+.*)", version)
if match:
return match.group(1)
return version
def get_reference(username):
return "flatbuffers/{}@google/stable".format(get_version())
if __name__ == "__main__":
login_username = os.getenv("CONAN_LOGIN_USERNAME", "aardappel")
username = os.getenv("CONAN_USERNAME", "google")
upload = os.getenv("CONAN_UPLOAD", "https://api.bintray.com/conan/aardappel/flatbuffers")
stable_branch_pattern = os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+.*")
test_folder = os.getenv("CPT_TEST_FOLDER", os.path.join("conan", "test_package"))
upload_only_when_stable = os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", True)
builder = ConanMultiPackager(reference=get_reference(username),
username=username,
login_username=login_username,
upload=upload,
stable_branch_pattern=stable_branch_pattern,
upload_only_when_stable=upload_only_when_stable,
test_folder=test_folder)
builder.add_common_builds(pure_c=False)
builder.run()

View File

@@ -1,9 +0,0 @@
project(test_package CXX)
cmake_minimum_required(VERSION 2.8.11)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
add_executable(${PROJECT_NAME} test_package.cpp)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)

View File

@@ -1,21 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from conans import ConanFile, CMake
import os
class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()
def test(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
self.run("flatc --version", run_environment=True)
self.run("flathash fnv1_16 conan", run_environment=True)

View File

@@ -1,75 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Conan recipe package for Google FlatBuffers
"""
import os
import shutil
from conans import ConanFile, CMake, tools
class FlatbuffersConan(ConanFile):
name = "flatbuffers"
license = "Apache-2.0"
url = "https://github.com/google/flatbuffers"
homepage = "http://google.github.io/flatbuffers/"
author = "Wouter van Oortmerssen"
topics = ("conan", "flatbuffers", "serialization", "rpc", "json-parser")
description = "Memory Efficient Serialization Library"
settings = "os", "compiler", "build_type", "arch"
options = {"shared": [True, False], "fPIC": [True, False]}
default_options = {"shared": False, "fPIC": True}
generators = "cmake"
exports = "LICENSE"
exports_sources = ["CMake/*", "include/*", "src/*", "grpc/*", "CMakeLists.txt", "conan/CMakeLists.txt"]
def source(self):
"""Wrap the original CMake file to call conan_basic_setup
"""
shutil.move("CMakeLists.txt", "CMakeListsOriginal.txt")
shutil.move(os.path.join("conan", "CMakeLists.txt"), "CMakeLists.txt")
def config_options(self):
"""Remove fPIC option on Windows platform
"""
if self.settings.os == "Windows":
self.options.remove("fPIC")
def configure_cmake(self):
"""Create CMake instance and execute configure step
"""
cmake = CMake(self)
cmake.definitions["FLATBUFFERS_BUILD_TESTS"] = False
cmake.definitions["FLATBUFFERS_BUILD_SHAREDLIB"] = self.options.shared
cmake.definitions["FLATBUFFERS_BUILD_FLATLIB"] = not self.options.shared
cmake.configure()
return cmake
def build(self):
"""Configure, build and install FlatBuffers using CMake.
"""
cmake = self.configure_cmake()
cmake.build()
def package(self):
"""Copy Flatbuffers' artifacts to package folder
"""
cmake = self.configure_cmake()
cmake.install()
self.copy(pattern="LICENSE", dst="licenses")
self.copy(pattern="FindFlatBuffers.cmake", dst=os.path.join("lib", "cmake", "flatbuffers"), src="CMake")
self.copy(pattern="flathash*", dst="bin", src="bin")
self.copy(pattern="flatc*", dst="bin", src="bin")
if self.settings.os == "Windows" and self.options.shared:
if self.settings.compiler == "Visual Studio":
shutil.move(os.path.join(self.package_folder, "lib", "%s.dll" % self.name),
os.path.join(self.package_folder, "bin", "%s.dll" % self.name))
elif self.settings.compiler == "gcc":
shutil.move(os.path.join(self.package_folder, "lib", "lib%s.dll" % self.name),
os.path.join(self.package_folder, "bin", "lib%s.dll" % self.name))
def package_info(self):
"""Collect built libraries names and solve flatc path.
"""
self.cpp_info.libs = tools.collect_libs(self)
self.user_info.flatc = os.path.join(self.package_folder, "bin", "flatc")

View File

@@ -1,5 +1,11 @@
# Changelog # Changelog
## 25.9.23
- use enhanced enums (#8313)
- fix incorrect write in Float64 write method (#8290)
- code format improvements (#8707)
## 23.5.26 ## 23.5.26
- omit type annotationes for local variables (#7067, #7069, #7070) - omit type annotationes for local variables (#7067, #7069, #7070)

View File

@@ -15,6 +15,7 @@
*/ */
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
import './monster_my_game.sample_generated.dart' as my_game; import './monster_my_game.sample_generated.dart' as my_game;
// Example how to use FlatBuffers to create and read binary buffers. // Example how to use FlatBuffers to create and read binary buffers.
@@ -78,7 +79,8 @@ void builderTest() {
builder.finish(monsteroff); builder.finish(monsteroff);
if (verify(builder.buffer)) { if (verify(builder.buffer)) {
print( print(
"The FlatBuffer was successfully created with a builder and verified!"); "The FlatBuffer was successfully created with a builder and verified!",
);
} }
} }
@@ -94,7 +96,10 @@ void objectBuilderTest() {
name: 'Orc', name: 'Orc',
inventory: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], inventory: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
color: my_game.Color.Red, color: my_game.Color.Red,
weapons: [my_game.WeaponObjectBuilder(name: 'Sword', damage: 3), axe], weapons: [
my_game.WeaponObjectBuilder(name: 'Sword', damage: 3),
axe,
],
equippedType: my_game.EquipmentTypeId.Weapon, equippedType: my_game.EquipmentTypeId.Weapon,
equipped: axe, equipped: axe,
); );
@@ -108,7 +113,8 @@ void objectBuilderTest() {
// Instead, we're going to access it right away (as if we just received it). // Instead, we're going to access it right away (as if we just received it).
if (verify(buffer)) { if (verify(buffer)) {
print( print(
"The FlatBuffer was successfully created with an object builder and verified!"); "The FlatBuffer was successfully created with an object builder and verified!",
);
} }
} }

View File

@@ -4,8 +4,8 @@
library my_game.sample; library my_game.sample;
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flat_buffers/flat_buffers.dart' as fb;
class Color { class Color {
final int value; final int value;
@@ -19,7 +19,7 @@ class Color {
return result; return result;
} }
static Color? _createOrNull(int? value) => static Color? _createOrNull(int? value) =>
value == null ? null : Color.fromValue(value); value == null ? null : Color.fromValue(value);
static const int minValue = 0; static const int minValue = 0;
@@ -29,10 +29,7 @@ class Color {
static const Color Red = Color._(0); static const Color Red = Color._(0);
static const Color Green = Color._(1); static const Color Green = Color._(1);
static const Color Blue = Color._(2); static const Color Blue = Color._(2);
static const Map<int, Color> values = { static const Map<int, Color> values = {0: Red, 1: Green, 2: Blue};
0: Red,
1: Green,
2: Blue};
static const fb.Reader<Color> reader = _ColorReader(); static const fb.Reader<Color> reader = _ColorReader();
@@ -60,12 +57,14 @@ class EquipmentTypeId {
factory EquipmentTypeId.fromValue(int value) { factory EquipmentTypeId.fromValue(int value) {
final result = values[value]; final result = values[value];
if (result == null) { if (result == null) {
throw StateError('Invalid value $value for bit flag enum EquipmentTypeId'); throw StateError(
'Invalid value $value for bit flag enum EquipmentTypeId',
);
} }
return result; return result;
} }
static EquipmentTypeId? _createOrNull(int? value) => static EquipmentTypeId? _createOrNull(int? value) =>
value == null ? null : EquipmentTypeId.fromValue(value); value == null ? null : EquipmentTypeId.fromValue(value);
static const int minValue = 0; static const int minValue = 0;
@@ -74,9 +73,7 @@ class EquipmentTypeId {
static const EquipmentTypeId NONE = EquipmentTypeId._(0); static const EquipmentTypeId NONE = EquipmentTypeId._(0);
static const EquipmentTypeId Weapon = EquipmentTypeId._(1); static const EquipmentTypeId Weapon = EquipmentTypeId._(1);
static const Map<int, EquipmentTypeId> values = { static const Map<int, EquipmentTypeId> values = {0: NONE, 1: Weapon};
0: NONE,
1: Weapon};
static const fb.Reader<EquipmentTypeId> reader = _EquipmentTypeIdReader(); static const fb.Reader<EquipmentTypeId> reader = _EquipmentTypeIdReader();
@@ -122,8 +119,7 @@ class _Vec3Reader extends fb.StructReader<Vec3> {
int get size => 12; int get size => 12;
@override @override
Vec3 createObject(fb.BufferContext bc, int offset) => Vec3 createObject(fb.BufferContext bc, int offset) => Vec3._(bc, offset);
Vec3._(bc, offset);
} }
class Vec3Builder { class Vec3Builder {
@@ -137,7 +133,6 @@ class Vec3Builder {
fbBuilder.putFloat32(x); fbBuilder.putFloat32(x);
return fbBuilder.offset; return fbBuilder.offset;
} }
} }
class Vec3ObjectBuilder extends fb.ObjectBuilder { class Vec3ObjectBuilder extends fb.ObjectBuilder {
@@ -145,14 +140,10 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder {
final double _y; final double _y;
final double _z; final double _z;
Vec3ObjectBuilder({ Vec3ObjectBuilder({required double x, required double y, required double z})
required double x, : _x = x,
required double y, _y = y,
required double z, _z = z;
})
: _x = x,
_y = y,
_z = z;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
@@ -171,6 +162,7 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class Monster { class Monster {
Monster._(this._bc, this._bcOffset); Monster._(this._bc, this._bcOffset);
factory Monster(List<int> bytes) { factory Monster(List<int> bytes) {
@@ -186,18 +178,30 @@ class Monster {
Vec3? get pos => Vec3.reader.vTableGetNullable(_bc, _bcOffset, 4); Vec3? get pos => Vec3.reader.vTableGetNullable(_bc, _bcOffset, 4);
int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150); int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100); int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
String? get name => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 10); String? get name =>
List<int>? get inventory => const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 14); const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 10);
Color get color => Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 2)); List<int>? get inventory =>
List<Weapon>? get weapons => const fb.ListReader<Weapon>(Weapon.reader).vTableGetNullable(_bc, _bcOffset, 18); const fb.Uint8ListReader().vTableGetNullable(_bc, _bcOffset, 14);
EquipmentTypeId? get equippedType => EquipmentTypeId._createOrNull(const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 20)); Color get color =>
Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 2));
List<Weapon>? get weapons => const fb.ListReader<Weapon>(
Weapon.reader,
).vTableGetNullable(_bc, _bcOffset, 18);
EquipmentTypeId? get equippedType => EquipmentTypeId._createOrNull(
const fb.Uint8Reader().vTableGetNullable(_bc, _bcOffset, 20),
);
dynamic get equipped { dynamic get equipped {
switch (equippedType?.value) { switch (equippedType?.value) {
case 1: return Weapon.reader.vTableGetNullable(_bc, _bcOffset, 22); case 1:
default: return null; return Weapon.reader.vTableGetNullable(_bc, _bcOffset, 22);
default:
return null;
} }
} }
List<Vec3>? get path => const fb.ListReader<Vec3>(Vec3.reader).vTableGetNullable(_bc, _bcOffset, 24);
List<Vec3>? get path => const fb.ListReader<Vec3>(
Vec3.reader,
).vTableGetNullable(_bc, _bcOffset, 24);
@override @override
String toString() { String toString() {
@@ -209,8 +213,8 @@ class _MonsterReader extends fb.TableReader<Monster> {
const _MonsterReader(); const _MonsterReader();
@override @override
Monster createObject(fb.BufferContext bc, int offset) => Monster createObject(fb.BufferContext bc, int offset) =>
Monster._(bc, offset); Monster._(bc, offset);
} }
class MonsterBuilder { class MonsterBuilder {
@@ -226,38 +230,47 @@ class MonsterBuilder {
fbBuilder.addStruct(0, offset); fbBuilder.addStruct(0, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addMana(int? mana) { int addMana(int? mana) {
fbBuilder.addInt16(1, mana); fbBuilder.addInt16(1, mana);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addHp(int? hp) { int addHp(int? hp) {
fbBuilder.addInt16(2, hp); fbBuilder.addInt16(2, hp);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addNameOffset(int? offset) { int addNameOffset(int? offset) {
fbBuilder.addOffset(3, offset); fbBuilder.addOffset(3, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addInventoryOffset(int? offset) { int addInventoryOffset(int? offset) {
fbBuilder.addOffset(5, offset); fbBuilder.addOffset(5, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addColor(Color? color) { int addColor(Color? color) {
fbBuilder.addInt8(6, color?.value); fbBuilder.addInt8(6, color?.value);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addWeaponsOffset(int? offset) { int addWeaponsOffset(int? offset) {
fbBuilder.addOffset(7, offset); fbBuilder.addOffset(7, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addEquippedType(EquipmentTypeId? equippedType) { int addEquippedType(EquipmentTypeId? equippedType) {
fbBuilder.addUint8(8, equippedType?.value); fbBuilder.addUint8(8, equippedType?.value);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addEquippedOffset(int? offset) { int addEquippedOffset(int? offset) {
fbBuilder.addOffset(9, offset); fbBuilder.addOffset(9, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addPathOffset(int? offset) { int addPathOffset(int? offset) {
fbBuilder.addOffset(10, offset); fbBuilder.addOffset(10, offset);
return fbBuilder.offset; return fbBuilder.offset;
@@ -291,29 +304,34 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
EquipmentTypeId? equippedType, EquipmentTypeId? equippedType,
dynamic equipped, dynamic equipped,
List<Vec3ObjectBuilder>? path, List<Vec3ObjectBuilder>? path,
}) }) : _pos = pos,
: _pos = pos, _mana = mana,
_mana = mana, _hp = hp,
_hp = hp, _name = name,
_name = name, _inventory = inventory,
_inventory = inventory, _color = color,
_color = color, _weapons = weapons,
_weapons = weapons, _equippedType = equippedType,
_equippedType = equippedType, _equipped = equipped,
_equipped = equipped, _path = path;
_path = path;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
int finish(fb.Builder fbBuilder) { int finish(fb.Builder fbBuilder) {
final int? nameOffset = _name == null ? null final int? nameOffset = _name == null
? null
: fbBuilder.writeString(_name!); : fbBuilder.writeString(_name!);
final int? inventoryOffset = _inventory == null ? null final int? inventoryOffset = _inventory == null
? null
: fbBuilder.writeListUint8(_inventory!); : fbBuilder.writeListUint8(_inventory!);
final int? weaponsOffset = _weapons == null ? null final int? weaponsOffset = _weapons == null
: fbBuilder.writeList(_weapons!.map((b) => b.getOrCreateOffset(fbBuilder)).toList()); ? null
: fbBuilder.writeList(
_weapons!.map((b) => b.getOrCreateOffset(fbBuilder)).toList(),
);
final int? equippedOffset = _equipped?.getOrCreateOffset(fbBuilder); final int? equippedOffset = _equipped?.getOrCreateOffset(fbBuilder);
final int? pathOffset = _path == null ? null final int? pathOffset = _path == null
? null
: fbBuilder.writeListOfStructs(_path!); : fbBuilder.writeListOfStructs(_path!);
fbBuilder.startTable(10); fbBuilder.startTable(10);
if (_pos != null) { if (_pos != null) {
@@ -339,6 +357,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class Weapon { class Weapon {
Weapon._(this._bc, this._bcOffset); Weapon._(this._bc, this._bcOffset);
factory Weapon(List<int> bytes) { factory Weapon(List<int> bytes) {
@@ -351,7 +370,8 @@ class Weapon {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
String? get name => const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 4); String? get name =>
const fb.StringReader().vTableGetNullable(_bc, _bcOffset, 4);
int get damage => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 0); int get damage => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 0);
@override @override
@@ -364,8 +384,7 @@ class _WeaponReader extends fb.TableReader<Weapon> {
const _WeaponReader(); const _WeaponReader();
@override @override
Weapon createObject(fb.BufferContext bc, int offset) => Weapon createObject(fb.BufferContext bc, int offset) => Weapon._(bc, offset);
Weapon._(bc, offset);
} }
class WeaponBuilder { class WeaponBuilder {
@@ -381,6 +400,7 @@ class WeaponBuilder {
fbBuilder.addOffset(0, offset); fbBuilder.addOffset(0, offset);
return fbBuilder.offset; return fbBuilder.offset;
} }
int addDamage(int? damage) { int addDamage(int? damage) {
fbBuilder.addInt16(1, damage); fbBuilder.addInt16(1, damage);
return fbBuilder.offset; return fbBuilder.offset;
@@ -395,17 +415,15 @@ class WeaponObjectBuilder extends fb.ObjectBuilder {
final String? _name; final String? _name;
final int? _damage; final int? _damage;
WeaponObjectBuilder({ WeaponObjectBuilder({String? name, int? damage})
String? name, : _name = name,
int? damage, _damage = damage;
})
: _name = name,
_damage = damage;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
int finish(fb.Builder fbBuilder) { int finish(fb.Builder fbBuilder) {
final int? nameOffset = _name == null ? null final int? nameOffset = _name == null
? null
: fbBuilder.writeString(_name!); : fbBuilder.writeString(_name!);
fbBuilder.startTable(2); fbBuilder.startTable(2);
fbBuilder.addOffset(0, nameOffset); fbBuilder.addOffset(0, nameOffset);

View File

@@ -27,10 +27,11 @@ class BufferContext {
ByteData get buffer => _buffer; ByteData get buffer => _buffer;
/// Create from a FlatBuffer represented by a list of bytes (uint8). /// Create from a FlatBuffer represented by a list of bytes (uint8).
factory BufferContext.fromBytes(List<int> byteList) => factory BufferContext.fromBytes(List<int> byteList) => BufferContext(
BufferContext(byteList is Uint8List byteList is Uint8List
? byteList.buffer.asByteData(byteList.offsetInBytes) ? byteList.buffer.asByteData(byteList.offsetInBytes)
: ByteData.view(Uint8List.fromList(byteList).buffer)); : ByteData.view(Uint8List.fromList(byteList).buffer),
);
/// Create from a FlatBuffer represented by ByteData. /// Create from a FlatBuffer represented by ByteData.
BufferContext(this._buffer); BufferContext(this._buffer);
@@ -149,9 +150,9 @@ class Builder {
bool internStrings = false, bool internStrings = false,
Allocator allocator = const DefaultAllocator(), Allocator allocator = const DefaultAllocator(),
this.deduplicateTables = true, this.deduplicateTables = true,
}) : _allocator = allocator, }) : _allocator = allocator,
_buf = allocator.allocate(initialSize), _buf = allocator.allocate(initialSize),
_vTables = deduplicateTables ? [] : const [] { _vTables = deduplicateTables ? [] : const [] {
if (internStrings) { if (internStrings) {
_strings = <String, int>{}; _strings = <String, int>{};
} }
@@ -350,8 +351,10 @@ class Builder {
Uint8List get buffer { Uint8List get buffer {
assert(_finished); assert(_finished);
final finishedSize = size(); final finishedSize = size();
return _buf.buffer return _buf.buffer.asUint8List(
.asUint8List(_buf.lengthInBytes - finishedSize, finishedSize); _buf.lengthInBytes - finishedSize,
finishedSize,
);
} }
/// Finish off the creation of the buffer. The given [offset] is used as the /// Finish off the creation of the buffer. The given [offset] is used as the
@@ -368,14 +371,18 @@ class Builder {
if (fileIdentifier != null) { if (fileIdentifier != null) {
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
_setUint8AtTail( _setUint8AtTail(
finishedSize - _sizeofUint32 - i, fileIdentifier.codeUnitAt(i)); finishedSize - _sizeofUint32 - i,
fileIdentifier.codeUnitAt(i),
);
} }
} }
// zero out the added padding // zero out the added padding
for (var i = sizeBeforePadding + 1; for (
i <= finishedSize - requiredBytes; var i = sizeBeforePadding + 1;
i++) { i <= finishedSize - requiredBytes;
i++
) {
_setUint8AtTail(i, 0); _setUint8AtTail(i, 0);
} }
_finished = true; _finished = true;
@@ -687,8 +694,10 @@ class Builder {
int writeString(String value, {bool asciiOptimization = false}) { int writeString(String value, {bool asciiOptimization = false}) {
assert(!_inVTable); assert(!_inVTable);
if (_strings != null) { if (_strings != null) {
return _strings! return _strings!.putIfAbsent(
.putIfAbsent(value, () => _writeString(value, asciiOptimization)); value,
() => _writeString(value, asciiOptimization),
);
} else { } else {
return _writeString(value, asciiOptimization); return _writeString(value, asciiOptimization);
} }
@@ -1005,8 +1014,11 @@ class ListReader<E> extends Reader<List<E>> {
: List<E>.generate( : List<E>.generate(
bc.buffer.getUint32(listOffset, Endian.little), bc.buffer.getUint32(listOffset, Endian.little),
(int index) => _elementReader.read( (int index) => _elementReader.read(
bc, listOffset + size + _elementReader.size * index), bc,
growable: true); listOffset + size + _elementReader.size * index,
),
growable: true,
);
} }
} }
@@ -1284,7 +1296,7 @@ class _FbGenericList<E> extends _FbList<E> {
List<E?>? _items; List<E?>? _items;
_FbGenericList(this.elementReader, BufferContext bp, int offset) _FbGenericList(this.elementReader, BufferContext bp, int offset)
: super(bp, offset); : super(bp, offset);
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@@ -1454,7 +1466,11 @@ abstract class Allocator {
/// Params [inUseBack] and [inUseFront] indicate how much of [oldData] is /// Params [inUseBack] and [inUseFront] indicate how much of [oldData] is
/// actually in use at each end, and needs to be copied. /// actually in use at each end, and needs to be copied.
ByteData resize( ByteData resize(
ByteData oldData, int newSize, int inUseBack, int inUseFront) { ByteData oldData,
int newSize,
int inUseBack,
int inUseFront,
) {
final newData = allocate(newSize); final newData = allocate(newSize);
_copyDownward(oldData, newData, inUseBack, inUseFront); _copyDownward(oldData, newData, inUseBack, inUseFront);
deallocate(oldData); deallocate(oldData);
@@ -1465,17 +1481,25 @@ abstract class Allocator {
/// memory of size [inUseFront] and [inUseBack] will be copied from the front /// memory of size [inUseFront] and [inUseBack] will be copied from the front
/// and back of the old memory allocation. /// and back of the old memory allocation.
void _copyDownward( void _copyDownward(
ByteData oldData, ByteData newData, int inUseBack, int inUseFront) { ByteData oldData,
ByteData newData,
int inUseBack,
int inUseFront,
) {
if (inUseBack != 0) { if (inUseBack != 0) {
newData.buffer.asUint8List().setAll( newData.buffer.asUint8List().setAll(
newData.lengthInBytes - inUseBack, newData.lengthInBytes - inUseBack,
oldData.buffer.asUint8List().getRange( oldData.buffer.asUint8List().getRange(
oldData.lengthInBytes - inUseBack, oldData.lengthInBytes)); oldData.lengthInBytes - inUseBack,
oldData.lengthInBytes,
),
);
} }
if (inUseFront != 0) { if (inUseFront != 0) {
newData.buffer newData.buffer.asUint8List().setAll(
.asUint8List() 0,
.setAll(0, oldData.buffer.asUint8List().getRange(0, inUseFront)); oldData.buffer.asUint8List().getRange(0, inUseFront),
);
} }
} }
} }

View File

@@ -5,7 +5,7 @@ import 'types.dart';
/// The main builder class for creation of a FlexBuffer. /// The main builder class for creation of a FlexBuffer.
class Builder { class Builder {
final ByteData _buffer; ByteData _buffer;
List<_StackValue> _stack = []; List<_StackValue> _stack = [];
List<_StackPointer> _stackPointers = []; List<_StackPointer> _stackPointers = [];
int _offset = 0; int _offset = 0;
@@ -107,8 +107,11 @@ class Builder {
final newOffset = _newOffset(length + 1); final newOffset = _newOffset(length + 1);
_pushBuffer(utf8String); _pushBuffer(utf8String);
_offset = newOffset; _offset = newOffset;
final stackValue = final stackValue = _StackValue.withOffset(
_StackValue.withOffset(stringOffset, ValueType.String, bitWidth); stringOffset,
ValueType.String,
bitWidth,
);
_stack.add(stackValue); _stack.add(stackValue);
_stringCache[value] = stackValue; _stringCache[value] = stackValue;
} }
@@ -128,8 +131,11 @@ class Builder {
final newOffset = _newOffset(length + 1); final newOffset = _newOffset(length + 1);
_pushBuffer(utf8String); _pushBuffer(utf8String);
_offset = newOffset; _offset = newOffset;
final stackValue = final stackValue = _StackValue.withOffset(
_StackValue.withOffset(keyOffset, ValueType.Key, BitWidth.width8); keyOffset,
ValueType.Key,
BitWidth.width8,
);
_stack.add(stackValue); _stack.add(stackValue);
_keyCache[value] = stackValue; _keyCache[value] = stackValue;
} }
@@ -147,8 +153,11 @@ class Builder {
final newOffset = _newOffset(length); final newOffset = _newOffset(length);
_pushBuffer(value.asUint8List()); _pushBuffer(value.asUint8List());
_offset = newOffset; _offset = newOffset;
final stackValue = final stackValue = _StackValue.withOffset(
_StackValue.withOffset(blobOffset, ValueType.Blob, bitWidth); blobOffset,
ValueType.Blob,
bitWidth,
);
_stack.add(stackValue); _stack.add(stackValue);
} }
@@ -170,7 +179,10 @@ class Builder {
final valueOffset = _offset; final valueOffset = _offset;
_pushBuffer(stackValue.asU8List(stackValue.width)); _pushBuffer(stackValue.asU8List(stackValue.width));
final stackOffset = _StackValue.withOffset( final stackOffset = _StackValue.withOffset(
valueOffset, ValueType.IndirectInt, stackValue.width); valueOffset,
ValueType.IndirectInt,
stackValue.width,
);
_stack.add(stackOffset); _stack.add(stackOffset);
_offset = newOffset; _offset = newOffset;
if (cache) { if (cache) {
@@ -195,7 +207,10 @@ class Builder {
final valueOffset = _offset; final valueOffset = _offset;
_pushBuffer(stackValue.asU8List(stackValue.width)); _pushBuffer(stackValue.asU8List(stackValue.width));
final stackOffset = _StackValue.withOffset( final stackOffset = _StackValue.withOffset(
valueOffset, ValueType.IndirectFloat, stackValue.width); valueOffset,
ValueType.IndirectFloat,
stackValue.width,
);
_stack.add(stackOffset); _stack.add(stackOffset);
_offset = newOffset; _offset = newOffset;
if (cache) { if (cache) {
@@ -252,9 +267,10 @@ class Builder {
tmp._offset = _offset; tmp._offset = _offset;
tmp._stack = List.from(_stack); tmp._stack = List.from(_stack);
tmp._stackPointers = List.from(_stackPointers); tmp._stackPointers = List.from(_stackPointers);
tmp._buffer.buffer tmp._buffer.buffer.asUint8List().setAll(
.asUint8List() 0,
.setAll(0, _buffer.buffer.asUint8List(0, _offset)); _buffer.buffer.asUint8List(0, _offset),
);
for (var i = 0; i < tmp._stackPointers.length; i++) { for (var i = 0; i < tmp._stackPointers.length; i++) {
tmp.end(); tmp.end();
} }
@@ -271,7 +287,8 @@ class Builder {
if (_stackPointers.isNotEmpty && _stackPointers.last.isVector == false) { if (_stackPointers.isNotEmpty && _stackPointers.last.isVector == false) {
if (_stack.last.type != ValueType.Key) { if (_stack.last.type != ValueType.Key) {
throw StateError( throw StateError(
'Adding value to a map before adding a key is prohibited'); 'Adding value to a map before adding a key is prohibited',
);
} }
} }
} }
@@ -288,7 +305,8 @@ class Builder {
void _finish() { void _finish() {
if (_stack.length != 1) { if (_stack.length != 1) {
throw StateError( throw StateError(
'Stack has to be exactly 1, but is ${_stack.length}. You have to end all started vectors and maps, before calling [finish]'); 'Stack has to be exactly 1, but is ${_stack.length}. You have to end all started vectors and maps, before calling [finish]',
);
} }
final value = _stack[0]; final value = _stack[0];
final byteWidth = _align(value.elementWidth(_offset, 0)); final byteWidth = _align(value.elementWidth(_offset, 0));
@@ -298,8 +316,12 @@ class Builder {
_finished = true; _finished = true;
} }
_StackValue _createVector(int start, int vecLength, int step, _StackValue _createVector(
[_StackValue? keys]) { int start,
int vecLength,
int step, [
_StackValue? keys,
]) {
var bitWidth = BitWidthUtil.uwidth(vecLength); var bitWidth = BitWidthUtil.uwidth(vecLength);
var prefixElements = 1; var prefixElements = 1;
if (keys != null) { if (keys != null) {
@@ -326,7 +348,8 @@ class Builder {
} }
} }
final byteWidth = _align(bitWidth); final byteWidth = _align(bitWidth);
final fix = typed & ValueTypeUtils.isNumber(vectorType) && final fix =
typed & ValueTypeUtils.isNumber(vectorType) &&
vecLength >= 2 && vecLength >= 2 &&
vecLength <= 4; vecLength <= 4;
if (keys != null) { if (keys != null) {
@@ -349,8 +372,10 @@ class Builder {
return _StackValue.withOffset(vecOffset, ValueType.Map, bitWidth); return _StackValue.withOffset(vecOffset, ValueType.Map, bitWidth);
} }
if (typed) { if (typed) {
final vType = final vType = ValueTypeUtils.toTypedVector(
ValueTypeUtils.toTypedVector(vectorType, fix ? vecLength : 0); vectorType,
fix ? vecLength : 0,
);
return _StackValue.withOffset(vecOffset, vType, bitWidth); return _StackValue.withOffset(vecOffset, vType, bitWidth);
} }
return _StackValue.withOffset(vecOffset, ValueType.Vector, bitWidth); return _StackValue.withOffset(vecOffset, ValueType.Vector, bitWidth);
@@ -366,7 +391,8 @@ class Builder {
void _sortKeysAndEndMap(_StackPointer pointer) { void _sortKeysAndEndMap(_StackPointer pointer) {
if (((_stack.length - pointer.stackPosition) & 1) == 1) { if (((_stack.length - pointer.stackPosition) & 1) == 1) {
throw StateError( throw StateError(
'The stack needs to hold key value pairs (even number of elements). Check if you combined [addKey] with add... method calls properly.'); 'The stack needs to hold key value pairs (even number of elements). Check if you combined [addKey] with add... method calls properly.',
);
} }
var sorted = true; var sorted = true;
@@ -412,8 +438,12 @@ class Builder {
keysStackValue = _createVector(pointer.stackPosition, vecLength, 2); keysStackValue = _createVector(pointer.stackPosition, vecLength, 2);
_keyVectorCache[keysHash] = keysStackValue; _keyVectorCache[keysHash] = keysStackValue;
} }
final vec = final vec = _createVector(
_createVector(pointer.stackPosition + 1, vecLength, 2, keysStackValue); pointer.stackPosition + 1,
vecLength,
2,
keysStackValue,
);
_stack.removeRange(pointer.stackPosition, _stack.length); _stack.removeRange(pointer.stackPosition, _stack.length);
_stack.add(vec); _stack.add(vec);
} }
@@ -421,7 +451,8 @@ class Builder {
bool _shouldFlip(_StackValue v1, _StackValue v2) { bool _shouldFlip(_StackValue v1, _StackValue v2) {
if (v1.type != ValueType.Key || v2.type != ValueType.Key) { if (v1.type != ValueType.Key || v2.type != ValueType.Key) {
throw StateError( throw StateError(
'Stack values are not keys $v1 | $v2. Check if you combined [addKey] with add... method calls properly.'); 'Stack values are not keys $v1 | $v2. Check if you combined [addKey] with add... method calls properly.',
);
} }
late int c1, c2; late int c1, c2;
@@ -450,7 +481,8 @@ class Builder {
_writeUInt(relativeOffset, byteWidth); _writeUInt(relativeOffset, byteWidth);
} else { } else {
throw StateError( throw StateError(
'Unexpected size $byteWidth. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new'); 'Unexpected size $byteWidth. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new',
);
} }
} else { } else {
_pushBuffer(value.asU8List(BitWidthUtil.fromByteWidth(byteWidth))); _pushBuffer(value.asU8List(BitWidthUtil.fromByteWidth(byteWidth)));
@@ -474,6 +506,7 @@ class Builder {
if (prevSize < size) { if (prevSize < size) {
final newBuf = ByteData(size); final newBuf = ByteData(size);
newBuf.buffer.asUint8List().setAll(0, _buffer.buffer.asUint8List()); newBuf.buffer.asUint8List().setAll(0, _buffer.buffer.asUint8List());
_buffer = newBuf;
} }
return newOffset; return newOffset;
} }
@@ -523,29 +556,27 @@ class _StackValue {
final ValueType _type; final ValueType _type;
final BitWidth _width; final BitWidth _width;
_StackValue.withNull() _StackValue.withNull() : _type = ValueType.Null, _width = BitWidth.width8;
: _type = ValueType.Null,
_width = BitWidth.width8;
_StackValue.withInt(int value) _StackValue.withInt(int value)
: _type = ValueType.Int, : _type = ValueType.Int,
_width = BitWidthUtil.width(value), _width = BitWidthUtil.width(value),
_value = value; _value = value;
_StackValue.withBool(bool value) _StackValue.withBool(bool value)
: _type = ValueType.Bool, : _type = ValueType.Bool,
_width = BitWidth.width8, _width = BitWidth.width8,
_value = value; _value = value;
_StackValue.withDouble(double value) _StackValue.withDouble(double value)
: _type = ValueType.Float, : _type = ValueType.Float,
_width = BitWidthUtil.width(value), _width = BitWidthUtil.width(value),
_value = value; _value = value;
_StackValue.withOffset(int value, ValueType type, BitWidth width) _StackValue.withOffset(int value, ValueType type, BitWidth width)
: _offset = value, : _offset = value,
_type = type, _type = type,
_width = width; _width = width;
BitWidth storedWidth({BitWidth width = BitWidth.width8}) { BitWidth storedWidth({BitWidth width = BitWidth.width8}) {
return ValueTypeUtils.isInline(_type) return ValueTypeUtils.isInline(_type)
@@ -562,16 +593,16 @@ class _StackValue {
final offset = _offset!; final offset = _offset!;
for (var i = 0; i < 4; i++) { for (var i = 0; i < 4; i++) {
final width = 1 << i; final width = 1 << i;
final bitWidth = BitWidthUtil.uwidth(size + final bitWidth = BitWidthUtil.uwidth(
BitWidthUtil.paddingSize(size, width) + size + BitWidthUtil.paddingSize(size, width) + index * width - offset,
index * width - );
offset);
if (1 << bitWidth.index == width) { if (1 << bitWidth.index == width) {
return bitWidth; return bitWidth;
} }
} }
throw StateError( throw StateError(
'Element is of unknown. Size: $size at index: $index. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new'); 'Element is of unknown. Size: $size at index: $index. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new',
);
} }
List<int> asU8List(BitWidth width) { List<int> asU8List(BitWidth width) {
@@ -619,7 +650,8 @@ class _StackValue {
} }
throw StateError( throw StateError(
'Unexpected type: $_type. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new'); 'Unexpected type: $_type. This might be a bug. Please create an issue https://github.com/google/flatbuffers/issues/new',
);
} }
ValueType get type { ValueType get type {

View File

@@ -1,6 +1,7 @@
import 'dart:collection'; import 'dart:collection';
import 'dart:convert'; import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'types.dart'; import 'types.dart';
/// Main class to read a value out of a FlexBuffer. /// Main class to read a value out of a FlexBuffer.
@@ -16,10 +17,15 @@ class Reference {
int? _length; int? _length;
Reference._( Reference._(
this._buffer, this._offset, this._parentWidth, int packedType, this._path, this._buffer,
[int? byteWidth, ValueType? valueType]) this._offset,
: _byteWidth = byteWidth ?? 1 << (packedType & 3), this._parentWidth,
_valueType = valueType ?? ValueTypeUtils.fromInt(packedType >> 2); int packedType,
this._path, [
int? byteWidth,
ValueType? valueType,
]) : _byteWidth = byteWidth ?? 1 << (packedType & 3),
_valueType = valueType ?? ValueTypeUtils.fromInt(packedType >> 2);
/// Use this method to access the root value of a FlexBuffer. /// Use this method to access the root value of a FlexBuffer.
static Reference fromBuffer(ByteBuffer buffer) { static Reference fromBuffer(ByteBuffer buffer) {
@@ -31,8 +37,13 @@ class Reference {
final byteWidth = byteData.getUint8(len - 1); final byteWidth = byteData.getUint8(len - 1);
final packedType = byteData.getUint8(len - 2); final packedType = byteData.getUint8(len - 2);
final offset = len - byteWidth - 2; final offset = len - byteWidth - 2;
return Reference._(ByteData.view(buffer), offset, return Reference._(
BitWidthUtil.fromByteWidth(byteWidth), packedType, "/"); ByteData.view(buffer),
offset,
BitWidthUtil.fromByteWidth(byteWidth),
packedType,
"/",
);
} }
/// Returns true if the underlying value is null. /// Returns true if the underlying value is null.
@@ -138,7 +149,8 @@ class Reference {
final index = key; final index = key;
if (index >= length || index < 0) { if (index >= length || index < 0) {
throw ArgumentError( throw ArgumentError(
'Key: [$key] is not applicable on: $_path of: $_valueType length: $length'); 'Key: [$key] is not applicable on: $_path of: $_valueType length: $length',
);
} }
final elementOffset = _indirect + index * _byteWidth; final elementOffset = _indirect + index * _byteWidth;
int packedType = 0; int packedType = 0;
@@ -154,13 +166,14 @@ class Reference {
packedType = _buffer.getUint8(_indirect + length * _byteWidth + index); packedType = _buffer.getUint8(_indirect + length * _byteWidth + index);
} }
return Reference._( return Reference._(
_buffer, _buffer,
elementOffset, elementOffset,
BitWidthUtil.fromByteWidth(_byteWidth), BitWidthUtil.fromByteWidth(_byteWidth),
packedType, packedType,
"$_path[$index]", "$_path[$index]",
byteWidth, byteWidth,
valueType); valueType,
);
} }
if (key is String && _valueType == ValueType.Map) { if (key is String && _valueType == ValueType.Map) {
final index = _keyIndex(key); final index = _keyIndex(key);
@@ -169,7 +182,8 @@ class Reference {
} }
} }
throw ArgumentError( throw ArgumentError(
'Key: [$key] is not applicable on: $_path of: $_valueType'); 'Key: [$key] is not applicable on: $_path of: $_valueType',
);
} }
/// Get an iterable if the underlying flexBuffer value is a vector. /// Get an iterable if the underlying flexBuffer value is a vector.
@@ -213,18 +227,24 @@ class Reference {
ValueTypeUtils.isAVector(_valueType) || ValueTypeUtils.isAVector(_valueType) ||
_valueType == ValueType.Map) { _valueType == ValueType.Map) {
_length = _readUInt( _length = _readUInt(
_indirect - _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth)); _indirect - _byteWidth,
BitWidthUtil.fromByteWidth(_byteWidth),
);
} else if (_valueType == ValueType.Null) { } else if (_valueType == ValueType.Null) {
_length = 0; _length = 0;
} else if (_valueType == ValueType.String) { } else if (_valueType == ValueType.String) {
final indirect = _indirect; final indirect = _indirect;
var sizeByteWidth = _byteWidth; var sizeByteWidth = _byteWidth;
var size = _readUInt(indirect - sizeByteWidth, var size = _readUInt(
BitWidthUtil.fromByteWidth(sizeByteWidth)); indirect - sizeByteWidth,
BitWidthUtil.fromByteWidth(sizeByteWidth),
);
while (_buffer.getInt8(indirect + size) != 0) { while (_buffer.getInt8(indirect + size) != 0) {
sizeByteWidth <<= 1; sizeByteWidth <<= 1;
size = _readUInt(indirect - sizeByteWidth, size = _readUInt(
BitWidthUtil.fromByteWidth(sizeByteWidth)); indirect - sizeByteWidth,
BitWidthUtil.fromByteWidth(sizeByteWidth),
);
} }
_length = size; _length = size;
} else if (_valueType == ValueType.Key) { } else if (_valueType == ValueType.Key) {
@@ -289,7 +309,8 @@ class Reference {
return result.toString(); return result.toString();
} }
throw UnsupportedError( throw UnsupportedError(
'Type: $_valueType is not supported for JSON conversion'); 'Type: $_valueType is not supported for JSON conversion',
);
} }
/// Computes the indirect offset of the value. /// Computes the indirect offset of the value.
@@ -354,10 +375,13 @@ class Reference {
int? _keyIndex(String key) { int? _keyIndex(String key) {
final input = utf8.encode(key); final input = utf8.encode(key);
final keysVectorOffset = _indirect - _byteWidth * 3; final keysVectorOffset = _indirect - _byteWidth * 3;
final indirectOffset = keysVectorOffset - final indirectOffset =
keysVectorOffset -
_readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth)); _readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth));
final byteWidth = _readUInt( final byteWidth = _readUInt(
keysVectorOffset + _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth)); keysVectorOffset + _byteWidth,
BitWidthUtil.fromByteWidth(_byteWidth),
);
var low = 0; var low = 0;
var high = length - 1; var high = length - 1;
while (low <= high) { while (low <= high) {
@@ -390,24 +414,37 @@ class Reference {
final indirect = _indirect; final indirect = _indirect;
final elementOffset = indirect + index * _byteWidth; final elementOffset = indirect + index * _byteWidth;
final packedType = _buffer.getUint8(indirect + length * _byteWidth + index); final packedType = _buffer.getUint8(indirect + length * _byteWidth + index);
return Reference._(_buffer, elementOffset, return Reference._(
BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path/$key"); _buffer,
elementOffset,
BitWidthUtil.fromByteWidth(_byteWidth),
packedType,
"$_path/$key",
);
} }
Reference _valueForIndex(int index) { Reference _valueForIndex(int index) {
final indirect = _indirect; final indirect = _indirect;
final elementOffset = indirect + index * _byteWidth; final elementOffset = indirect + index * _byteWidth;
final packedType = _buffer.getUint8(indirect + length * _byteWidth + index); final packedType = _buffer.getUint8(indirect + length * _byteWidth + index);
return Reference._(_buffer, elementOffset, return Reference._(
BitWidthUtil.fromByteWidth(_byteWidth), packedType, "$_path/[$index]"); _buffer,
elementOffset,
BitWidthUtil.fromByteWidth(_byteWidth),
packedType,
"$_path/[$index]",
);
} }
String _keyForIndex(int index) { String _keyForIndex(int index) {
final keysVectorOffset = _indirect - _byteWidth * 3; final keysVectorOffset = _indirect - _byteWidth * 3;
final indirectOffset = keysVectorOffset - final indirectOffset =
keysVectorOffset -
_readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth)); _readUInt(keysVectorOffset, BitWidthUtil.fromByteWidth(_byteWidth));
final byteWidth = _readUInt( final byteWidth = _readUInt(
keysVectorOffset + _byteWidth, BitWidthUtil.fromByteWidth(_byteWidth)); keysVectorOffset + _byteWidth,
BitWidthUtil.fromByteWidth(_byteWidth),
);
final keyOffset = indirectOffset + index * byteWidth; final keyOffset = indirectOffset + index * byteWidth;
final keyIndirectOffset = final keyIndirectOffset =
keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth)); keyOffset - _readUInt(keyOffset, BitWidthUtil.fromByteWidth(byteWidth));

View File

@@ -86,7 +86,8 @@ enum ValueType {
VectorFloat, VectorFloat,
VectorKey, VectorKey,
@Deprecated( @Deprecated(
'VectorString is deprecated due to a flaw in the binary format (https://github.com/google/flatbuffers/issues/5627)') 'VectorString is deprecated due to a flaw in the binary format (https://github.com/google/flatbuffers/issues/5627)',
)
VectorString, VectorString,
VectorInt2, VectorInt2,
VectorUInt2, VectorUInt2,
@@ -99,7 +100,7 @@ enum ValueType {
VectorFloat4, VectorFloat4,
Blob, Blob,
Bool, Bool,
VectorBool VectorBool,
} }
class ValueTypeUtils { class ValueTypeUtils {
@@ -153,31 +154,37 @@ class ValueTypeUtils {
static ValueType toTypedVector(ValueType self, int length) { static ValueType toTypedVector(ValueType self, int length) {
if (length == 0) { if (length == 0) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt)); toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt),
);
} }
if (length == 2) { if (length == 2) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt2)); toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt2),
);
} }
if (length == 3) { if (length == 3) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt3)); toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt3),
);
} }
if (length == 4) { if (length == 4) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt4)); toInt(self) - toInt(ValueType.Int) + toInt(ValueType.VectorInt4),
);
} }
throw Exception('unexpected length ' + length.toString()); throw Exception('unexpected length ' + length.toString());
} }
static ValueType typedVectorElementType(ValueType self) { static ValueType typedVectorElementType(ValueType self) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
toInt(self) - toInt(ValueType.VectorInt) + toInt(ValueType.Int)); toInt(self) - toInt(ValueType.VectorInt) + toInt(ValueType.Int),
);
} }
static ValueType fixedTypedVectorElementType(ValueType self) { static ValueType fixedTypedVectorElementType(ValueType self) {
return ValueTypeUtils.fromInt( return ValueTypeUtils.fromInt(
(toInt(self) - toInt(ValueType.VectorInt2)) % 3 + toInt(ValueType.Int)); (toInt(self) - toInt(ValueType.VectorInt2)) % 3 + toInt(ValueType.Int),
);
} }
static int fixedTypedVectorElementSize(ValueType self) { static int fixedTypedVectorElementSize(ValueType self) {

View File

@@ -1,5 +1,5 @@
name: flat_buffers name: flat_buffers
version: 25.2.10 version: 25.12.19
description: FlatBuffers reading and writing library for Dart. Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team. description: FlatBuffers reading and writing library for Dart. Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team.
homepage: https://github.com/google/flatbuffers homepage: https://github.com/google/flatbuffers
documentation: https://google.github.io/flatbuffers/index.html documentation: https://google.github.io/flatbuffers/index.html

View File

@@ -2,8 +2,8 @@
// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names // ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flat_buffers/flat_buffers.dart' as fb;
class Foo { class Foo {
Foo._(this._bc, this._bcOffset); Foo._(this._bc, this._bcOffset);
@@ -17,15 +17,15 @@ class Foo {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
FooProperties? get myFoo => FooProperties.reader.vTableGetNullable(_bc, _bcOffset, 4); FooProperties? get myFoo =>
FooProperties.reader.vTableGetNullable(_bc, _bcOffset, 4);
@override @override
String toString() { String toString() {
return 'Foo{myFoo: ${myFoo}}'; return 'Foo{myFoo: ${myFoo}}';
} }
FooT unpack() => FooT( FooT unpack() => FooT(myFoo: myFoo?.unpack());
myFoo: myFoo?.unpack());
static int pack(fb.Builder fbBuilder, FooT? object) { static int pack(fb.Builder fbBuilder, FooT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -36,8 +36,7 @@ class Foo {
class FooT implements fb.Packable { class FooT implements fb.Packable {
FooPropertiesT? myFoo; FooPropertiesT? myFoo;
FooT({ FooT({this.myFoo});
this.myFoo});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -58,8 +57,7 @@ class _FooReader extends fb.TableReader<Foo> {
const _FooReader(); const _FooReader();
@override @override
Foo createObject(fb.BufferContext bc, int offset) => Foo createObject(fb.BufferContext bc, int offset) => Foo._(bc, offset);
Foo._(bc, offset);
} }
class FooBuilder { class FooBuilder {
@@ -84,10 +82,7 @@ class FooBuilder {
class FooObjectBuilder extends fb.ObjectBuilder { class FooObjectBuilder extends fb.ObjectBuilder {
final FooPropertiesObjectBuilder? _myFoo; final FooPropertiesObjectBuilder? _myFoo;
FooObjectBuilder({ FooObjectBuilder({FooPropertiesObjectBuilder? myFoo}) : _myFoo = myFoo;
FooPropertiesObjectBuilder? myFoo,
})
: _myFoo = myFoo;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
@@ -107,6 +102,7 @@ class FooObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class FooProperties { class FooProperties {
FooProperties._(this._bc, this._bcOffset); FooProperties._(this._bc, this._bcOffset);
@@ -123,9 +119,7 @@ class FooProperties {
return 'FooProperties{a: ${a}, b: ${b}}'; return 'FooProperties{a: ${a}, b: ${b}}';
} }
FooPropertiesT unpack() => FooPropertiesT( FooPropertiesT unpack() => FooPropertiesT(a: a, b: b);
a: a,
b: b);
static int pack(fb.Builder fbBuilder, FooPropertiesT? object) { static int pack(fb.Builder fbBuilder, FooPropertiesT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -137,9 +131,7 @@ class FooPropertiesT implements fb.Packable {
bool a; bool a;
bool b; bool b;
FooPropertiesT({ FooPropertiesT({required this.a, required this.b});
required this.a,
required this.b});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -161,8 +153,8 @@ class _FooPropertiesReader extends fb.StructReader<FooProperties> {
int get size => 2; int get size => 2;
@override @override
FooProperties createObject(fb.BufferContext bc, int offset) => FooProperties createObject(fb.BufferContext bc, int offset) =>
FooProperties._(bc, offset); FooProperties._(bc, offset);
} }
class FooPropertiesBuilder { class FooPropertiesBuilder {
@@ -175,19 +167,15 @@ class FooPropertiesBuilder {
fbBuilder.putBool(a); fbBuilder.putBool(a);
return fbBuilder.offset; return fbBuilder.offset;
} }
} }
class FooPropertiesObjectBuilder extends fb.ObjectBuilder { class FooPropertiesObjectBuilder extends fb.ObjectBuilder {
final bool _a; final bool _a;
final bool _b; final bool _b;
FooPropertiesObjectBuilder({ FooPropertiesObjectBuilder({required bool a, required bool b})
required bool a, : _a = a,
required bool b, _b = b;
})
: _a = a,
_b = b;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override

View File

@@ -2,8 +2,8 @@
// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names // ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flat_buffers/flat_buffers.dart' as fb;
enum OptionsEnum { enum OptionsEnum {
A(1), A(1),
@@ -15,10 +15,14 @@ enum OptionsEnum {
factory OptionsEnum.fromValue(int value) { factory OptionsEnum.fromValue(int value) {
switch (value) { switch (value) {
case 1: return OptionsEnum.A; case 1:
case 2: return OptionsEnum.B; return OptionsEnum.A;
case 3: return OptionsEnum.C; case 2:
default: throw StateError('Invalid value $value for bit flag enum'); return OptionsEnum.B;
case 3:
return OptionsEnum.C;
default:
throw StateError('Invalid value $value for bit flag enum');
} }
} }
@@ -53,7 +57,9 @@ class MyTable {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
List<OptionsEnum>? get options => const fb.ListReader<OptionsEnum>(OptionsEnum.reader).vTableGetNullable(_bc, _bcOffset, 4); List<OptionsEnum>? get options => const fb.ListReader<OptionsEnum>(
OptionsEnum.reader,
).vTableGetNullable(_bc, _bcOffset, 4);
@override @override
String toString() { String toString() {
@@ -61,7 +67,11 @@ class MyTable {
} }
MyTableT unpack() => MyTableT( MyTableT unpack() => MyTableT(
options: const fb.ListReader<OptionsEnum>(OptionsEnum.reader, lazy: false).vTableGetNullable(_bc, _bcOffset, 4)); options: const fb.ListReader<OptionsEnum>(
OptionsEnum.reader,
lazy: false,
).vTableGetNullable(_bc, _bcOffset, 4),
);
static int pack(fb.Builder fbBuilder, MyTableT? object) { static int pack(fb.Builder fbBuilder, MyTableT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -72,12 +82,12 @@ class MyTable {
class MyTableT implements fb.Packable { class MyTableT implements fb.Packable {
List<OptionsEnum>? options; List<OptionsEnum>? options;
MyTableT({ MyTableT({this.options});
this.options});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
final int? optionsOffset = options == null ? null final int? optionsOffset = options == null
? null
: fbBuilder.writeListUint32(options!.map((f) => f.value).toList()); : fbBuilder.writeListUint32(options!.map((f) => f.value).toList());
fbBuilder.startTable(1); fbBuilder.startTable(1);
fbBuilder.addOffset(0, optionsOffset); fbBuilder.addOffset(0, optionsOffset);
@@ -94,8 +104,8 @@ class _MyTableReader extends fb.TableReader<MyTable> {
const _MyTableReader(); const _MyTableReader();
@override @override
MyTable createObject(fb.BufferContext bc, int offset) => MyTable createObject(fb.BufferContext bc, int offset) =>
MyTable._(bc, offset); MyTable._(bc, offset);
} }
class MyTableBuilder { class MyTableBuilder {
@@ -120,15 +130,13 @@ class MyTableBuilder {
class MyTableObjectBuilder extends fb.ObjectBuilder { class MyTableObjectBuilder extends fb.ObjectBuilder {
final List<OptionsEnum>? _options; final List<OptionsEnum>? _options;
MyTableObjectBuilder({ MyTableObjectBuilder({List<OptionsEnum>? options}) : _options = options;
List<OptionsEnum>? options,
})
: _options = options;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
int finish(fb.Builder fbBuilder) { int finish(fb.Builder fbBuilder) {
final int? optionsOffset = _options == null ? null final int? optionsOffset = _options == null
? null
: fbBuilder.writeListUint32(_options!.map((f) => f.value).toList()); : fbBuilder.writeListUint32(_options!.map((f) => f.value).toList());
fbBuilder.startTable(1); fbBuilder.startTable(1);
fbBuilder.addOffset(0, optionsOffset); fbBuilder.addOffset(0, optionsOffset);

View File

@@ -1,16 +1,15 @@
import 'dart:typed_data';
import 'dart:io' as io; import 'dart:io' as io;
import 'dart:typed_data';
import 'package:path/path.dart' as path;
import 'package:flat_buffers/flat_buffers.dart'; import 'package:flat_buffers/flat_buffers.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart';
import './monster_test_my_game.example_generated.dart' as example;
import './monster_test_my_game.example2_generated.dart' as example2;
import 'enums_generated.dart' as example3;
import './bool_structs_generated.dart' as example4; import './bool_structs_generated.dart' as example4;
import './monster_test_my_game.example2_generated.dart' as example2;
import './monster_test_my_game.example_generated.dart' as example;
import 'enums_generated.dart' as example3;
main() { main() {
defineReflectiveSuite(() { defineReflectiveSuite(() {
@@ -29,11 +28,9 @@ int indexToField(int index) {
@reflectiveTest @reflectiveTest
class CheckOtherLangaugesData { class CheckOtherLangaugesData {
test_cppData() async { test_cppData() async {
List<int> data = await io.File(path.join( List<int> data = await io.File(
path.context.current, path.join(path.context.current, 'test', 'monsterdata_test.mon'),
'test', ).readAsBytes();
'monsterdata_test.mon',
)).readAsBytes();
example.Monster mon = example.Monster(data); example.Monster mon = example.Monster(data);
expect(mon.hp, 80); expect(mon.hp, 80);
expect(mon.mana, 150); expect(mon.mana, 150);
@@ -61,91 +58,92 @@ class CheckOtherLangaugesData {
// this will fail if accessing any field fails. // this will fail if accessing any field fails.
expect( expect(
mon.toString(), mon.toString(),
'Monster{' 'Monster{'
'pos: Vec3{x: 1.0, y: 2.0, z: 3.0, test1: 3.0, test2: Color.Green, test3: Test{a: 5, b: 6}}, ' 'pos: Vec3{x: 1.0, y: 2.0, z: 3.0, test1: 3.0, test2: Color.Green, test3: Test{a: 5, b: 6}}, '
'mana: 150, hp: 80, name: MyMonster, inventory: [0, 1, 2, 3, 4], ' 'mana: 150, hp: 80, name: MyMonster, inventory: [0, 1, 2, 3, 4], '
'color: Color.Blue, testType: AnyTypeId.Monster, ' 'color: Color.Blue, testType: AnyTypeId.Monster, '
'test: Monster{pos: null, mana: 150, hp: 100, name: Fred, ' 'test: Monster{pos: null, mana: 150, hp: 100, name: Fred, '
'inventory: null, color: Color.Blue, testType: null, ' 'inventory: null, color: Color.Blue, testType: null, '
'test: null, test4: null, testarrayofstring: null, ' 'test: null, test4: null, testarrayofstring: null, '
'testarrayoftables: null, enemy: null, testnestedflatbuffer: null, ' 'testarrayoftables: null, enemy: null, testnestedflatbuffer: null, '
'testempty: null, testbool: false, testhashs32Fnv1: 0, ' 'testempty: null, testbool: false, testhashs32Fnv1: 0, '
'testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, ' 'testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, '
'testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, ' 'testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, '
'testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, ' 'testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, '
'testf2: 3.0, testf3: 0.0, testarrayofstring2: null, ' 'testf2: 3.0, testf3: 0.0, testarrayofstring2: null, '
'testarrayofsortedstruct: null, flex: null, test5: null, ' 'testarrayofsortedstruct: null, flex: null, test5: null, '
'vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, ' 'vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, '
'vectorOfReferrables: null, singleWeakReference: 0, ' 'vectorOfReferrables: null, singleWeakReference: 0, '
'vectorOfWeakReferences: null, vectorOfStrongReferrables: null, ' 'vectorOfWeakReferences: null, vectorOfStrongReferrables: null, '
'coOwningReference: 0, vectorOfCoOwningReferences: null, ' 'coOwningReference: 0, vectorOfCoOwningReferences: null, '
'nonOwningReference: 0, vectorOfNonOwningReferences: null, ' 'nonOwningReference: 0, vectorOfNonOwningReferences: null, '
'anyUniqueType: null, anyUnique: null, anyAmbiguousType: null, ' 'anyUniqueType: null, anyUnique: null, anyAmbiguousType: null, '
'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race.None, ' 'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race.None, '
'testrequirednestedflatbuffer: null, scalarKeySortedTables: null, ' 'testrequirednestedflatbuffer: null, scalarKeySortedTables: null, '
'nativeInline: null, ' 'nativeInline: null, '
'longEnumNonEnumDefault: LongEnum._default, ' 'longEnumNonEnumDefault: LongEnum._default, '
'longEnumNormalDefault: LongEnum.LongOne, nanDefault: NaN, ' 'longEnumNormalDefault: LongEnum.LongOne, nanDefault: NaN, '
'infDefault: Infinity, positiveInfDefault: Infinity, infinityDefault: ' 'infDefault: Infinity, positiveInfDefault: Infinity, infinityDefault: '
'Infinity, positiveInfinityDefault: Infinity, negativeInfDefault: ' 'Infinity, positiveInfinityDefault: Infinity, negativeInfDefault: '
'-Infinity, negativeInfinityDefault: -Infinity, doubleInfDefault: Infinity}, ' '-Infinity, negativeInfinityDefault: -Infinity, doubleInfDefault: Infinity}, '
'test4: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], ' 'test4: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], '
'testarrayofstring: [test1, test2], testarrayoftables: null, ' 'testarrayofstring: [test1, test2], testarrayoftables: null, '
'enemy: Monster{pos: null, mana: 150, hp: 100, name: Fred, ' 'enemy: Monster{pos: null, mana: 150, hp: 100, name: Fred, '
'inventory: null, color: Color.Blue, testType: null, ' 'inventory: null, color: Color.Blue, testType: null, '
'test: null, test4: null, testarrayofstring: null, ' 'test: null, test4: null, testarrayofstring: null, '
'testarrayoftables: null, enemy: null, testnestedflatbuffer: null, ' 'testarrayoftables: null, enemy: null, testnestedflatbuffer: null, '
'testempty: null, testbool: false, testhashs32Fnv1: 0, ' 'testempty: null, testbool: false, testhashs32Fnv1: 0, '
'testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, ' 'testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, '
'testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, ' 'testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, '
'testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, ' 'testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, '
'testf2: 3.0, testf3: 0.0, testarrayofstring2: null, ' 'testf2: 3.0, testf3: 0.0, testarrayofstring2: null, '
'testarrayofsortedstruct: null, flex: null, test5: null, ' 'testarrayofsortedstruct: null, flex: null, test5: null, '
'vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, ' 'vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, '
'vectorOfReferrables: null, singleWeakReference: 0, ' 'vectorOfReferrables: null, singleWeakReference: 0, '
'vectorOfWeakReferences: null, vectorOfStrongReferrables: null, ' 'vectorOfWeakReferences: null, vectorOfStrongReferrables: null, '
'coOwningReference: 0, vectorOfCoOwningReferences: null, ' 'coOwningReference: 0, vectorOfCoOwningReferences: null, '
'nonOwningReference: 0, vectorOfNonOwningReferences: null, ' 'nonOwningReference: 0, vectorOfNonOwningReferences: null, '
'anyUniqueType: null, anyUnique: null, anyAmbiguousType: null, ' 'anyUniqueType: null, anyUnique: null, anyAmbiguousType: null, '
'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race.None, ' 'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race.None, '
'testrequirednestedflatbuffer: null, scalarKeySortedTables: null, ' 'testrequirednestedflatbuffer: null, scalarKeySortedTables: null, '
'nativeInline: null, ' 'nativeInline: null, '
'longEnumNonEnumDefault: LongEnum._default, ' 'longEnumNonEnumDefault: LongEnum._default, '
'longEnumNormalDefault: LongEnum.LongOne, nanDefault: NaN, ' 'longEnumNormalDefault: LongEnum.LongOne, nanDefault: NaN, '
'infDefault: Infinity, positiveInfDefault: Infinity, infinityDefault: ' 'infDefault: Infinity, positiveInfDefault: Infinity, infinityDefault: '
'Infinity, positiveInfinityDefault: Infinity, negativeInfDefault: ' 'Infinity, positiveInfinityDefault: Infinity, negativeInfDefault: '
'-Infinity, negativeInfinityDefault: -Infinity, doubleInfDefault: Infinity}, ' '-Infinity, negativeInfinityDefault: -Infinity, doubleInfDefault: Infinity}, '
'testnestedflatbuffer: null, testempty: null, testbool: true, ' 'testnestedflatbuffer: null, testempty: null, testbool: true, '
'testhashs32Fnv1: -579221183, testhashu32Fnv1: 3715746113, ' 'testhashs32Fnv1: -579221183, testhashu32Fnv1: 3715746113, '
'testhashs64Fnv1: 7930699090847568257, ' 'testhashs64Fnv1: 7930699090847568257, '
'testhashu64Fnv1: 7930699090847568257, ' 'testhashu64Fnv1: 7930699090847568257, '
'testhashs32Fnv1a: -1904106383, testhashu32Fnv1a: 2390860913, ' 'testhashs32Fnv1a: -1904106383, testhashu32Fnv1a: 2390860913, '
'testhashs64Fnv1a: 4898026182817603057, ' 'testhashs64Fnv1a: 4898026182817603057, '
'testhashu64Fnv1a: 4898026182817603057, ' 'testhashu64Fnv1a: 4898026182817603057, '
'testarrayofbools: [true, false, true], testf: 3.14159, testf2: 3.0, ' 'testarrayofbools: [true, false, true], testf: 3.14159, testf2: 3.0, '
'testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: [' 'testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: ['
'Ability{id: 0, distance: 45}, Ability{id: 1, distance: 21}, ' 'Ability{id: 0, distance: 45}, Ability{id: 1, distance: 21}, '
'Ability{id: 5, distance: 12}], ' 'Ability{id: 5, distance: 12}], '
'flex: null, test5: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], ' 'flex: null, test5: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], '
'vectorOfLongs: [1, 100, 10000, 1000000, 100000000], ' 'vectorOfLongs: [1, 100, 10000, 1000000, 100000000], '
'vectorOfDoubles: [-1.7976931348623157e+308, 0.0, 1.7976931348623157e+308], ' 'vectorOfDoubles: [-1.7976931348623157e+308, 0.0, 1.7976931348623157e+308], '
'parentNamespaceTest: null, vectorOfReferrables: null, ' 'parentNamespaceTest: null, vectorOfReferrables: null, '
'singleWeakReference: 0, vectorOfWeakReferences: null, ' 'singleWeakReference: 0, vectorOfWeakReferences: null, '
'vectorOfStrongReferrables: null, coOwningReference: 0, ' 'vectorOfStrongReferrables: null, coOwningReference: 0, '
'vectorOfCoOwningReferences: null, nonOwningReference: 0, ' 'vectorOfCoOwningReferences: null, nonOwningReference: 0, '
'vectorOfNonOwningReferences: null, ' 'vectorOfNonOwningReferences: null, '
'anyUniqueType: null, anyUnique: null, ' 'anyUniqueType: null, anyUnique: null, '
'anyAmbiguousType: null, ' 'anyAmbiguousType: null, '
'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race.None, ' 'anyAmbiguous: null, vectorOfEnums: null, signedEnum: Race.None, '
'testrequirednestedflatbuffer: null, scalarKeySortedTables: [Stat{id: ' 'testrequirednestedflatbuffer: null, scalarKeySortedTables: [Stat{id: '
'miss, val: 0, count: 0}, Stat{id: hit, val: 10, count: 1}], ' 'miss, val: 0, count: 0}, Stat{id: hit, val: 10, count: 1}], '
'nativeInline: Test{a: 1, b: 2}, ' 'nativeInline: Test{a: 1, b: 2}, '
'longEnumNonEnumDefault: LongEnum._default, ' 'longEnumNonEnumDefault: LongEnum._default, '
'longEnumNormalDefault: LongEnum.LongOne, nanDefault: NaN, ' 'longEnumNormalDefault: LongEnum.LongOne, nanDefault: NaN, '
'infDefault: Infinity, positiveInfDefault: Infinity, infinityDefault: ' 'infDefault: Infinity, positiveInfDefault: Infinity, infinityDefault: '
'Infinity, positiveInfinityDefault: Infinity, negativeInfDefault: ' 'Infinity, positiveInfinityDefault: Infinity, negativeInfDefault: '
'-Infinity, negativeInfinityDefault: -Infinity, doubleInfDefault: Infinity}'); '-Infinity, negativeInfinityDefault: -Infinity, doubleInfDefault: Infinity}',
);
} }
} }
@@ -298,20 +296,72 @@ class BuilderTest {
expect(allocator.buffer(builder.size()), [2, 0, 0, 0, 0, 0, 0, 1]); expect(allocator.buffer(builder.size()), [2, 0, 0, 0, 0, 0, 0, 1]);
builder.putUint8(3); builder.putUint8(3);
expect( expect(allocator.buffer(builder.size()), [
allocator.buffer(builder.size()), [0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]); 0,
0,
0,
3,
2,
0,
0,
0,
0,
0,
0,
1,
]);
builder.putUint8(4); builder.putUint8(4);
expect( expect(allocator.buffer(builder.size()), [
allocator.buffer(builder.size()), [0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); 0,
0,
4,
3,
2,
0,
0,
0,
0,
0,
0,
1,
]);
builder.putUint8(5); builder.putUint8(5);
expect( expect(allocator.buffer(builder.size()), [
allocator.buffer(builder.size()), [0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); 0,
5,
4,
3,
2,
0,
0,
0,
0,
0,
0,
1,
]);
builder.putUint32(6); builder.putUint32(6);
expect(allocator.buffer(builder.size()), expect(allocator.buffer(builder.size()), [
[6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]); 6,
0,
0,
0,
0,
5,
4,
3,
2,
0,
0,
0,
0,
0,
0,
1,
]);
} }
void test_table_default() { void test_table_default() {
@@ -331,14 +381,14 @@ class BuilderTest {
int objectOffset = buffer.derefObject(0); int objectOffset = buffer.derefObject(0);
// was not written, so uses the new default value // was not written, so uses the new default value
expect( expect(
const Int32Reader() const Int32Reader().vTableGet(buffer, objectOffset, indexToField(0), 15),
.vTableGet(buffer, objectOffset, indexToField(0), 15), 15,
15); );
// has the written value // has the written value
expect( expect(
const Int32Reader() const Int32Reader().vTableGet(buffer, objectOffset, indexToField(1), 15),
.vTableGet(buffer, objectOffset, indexToField(1), 15), 20,
20); );
} }
void test_table_format([Builder? builder]) { void test_table_format([Builder? builder]) {
@@ -370,7 +420,9 @@ class BuilderTest {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
int offset = byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little); int offset = byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little);
expect( expect(
byteData.getInt32(tableDataLoc + offset, Endian.little), 10 + 10 * i); byteData.getInt32(tableDataLoc + offset, Endian.little),
10 + 10 * i,
);
} }
} }
@@ -380,10 +432,14 @@ class BuilderTest {
List<int> byteList; List<int> byteList;
{ {
Builder builder = Builder(initialSize: 0); Builder builder = Builder(initialSize: 0);
int? latinStringOffset = int? latinStringOffset = builder.writeString(
builder.writeString(latinString, asciiOptimization: true); latinString,
int? unicodeStringOffset = asciiOptimization: true,
builder.writeString(unicodeString, asciiOptimization: true); );
int? unicodeStringOffset = builder.writeString(
unicodeString,
asciiOptimization: true,
);
builder.startTable(2); builder.startTable(2);
builder.addOffset(0, latinStringOffset); builder.addOffset(0, latinStringOffset);
builder.addOffset(1, unicodeStringOffset); builder.addOffset(1, unicodeStringOffset);
@@ -395,13 +451,19 @@ class BuilderTest {
BufferContext buf = BufferContext.fromBytes(byteList); BufferContext buf = BufferContext.fromBytes(byteList);
int objectOffset = buf.derefObject(0); int objectOffset = buf.derefObject(0);
expect( expect(
const StringReader() const StringReader().vTableGetNullable(
.vTableGetNullable(buf, objectOffset, indexToField(0)), buf,
latinString); objectOffset,
indexToField(0),
),
latinString,
);
expect( expect(
const StringReader(asciiOptimization: true) const StringReader(
.vTableGetNullable(buf, objectOffset, indexToField(1)), asciiOptimization: true,
unicodeString); ).vTableGetNullable(buf, objectOffset, indexToField(1)),
unicodeString,
);
} }
void test_table_types([Builder? builder]) { void test_table_types([Builder? builder]) {
@@ -425,33 +487,41 @@ class BuilderTest {
BufferContext buf = BufferContext.fromBytes(byteList); BufferContext buf = BufferContext.fromBytes(byteList);
int objectOffset = buf.derefObject(0); int objectOffset = buf.derefObject(0);
expect( expect(
const BoolReader() const BoolReader().vTableGetNullable(buf, objectOffset, indexToField(0)),
.vTableGetNullable(buf, objectOffset, indexToField(0)), true,
true); );
expect( expect(
const Int8Reader() const Int8Reader().vTableGetNullable(buf, objectOffset, indexToField(1)),
.vTableGetNullable(buf, objectOffset, indexToField(1)), 10,
10); );
expect( expect(
const Int32Reader() const Int32Reader().vTableGetNullable(buf, objectOffset, indexToField(2)),
.vTableGetNullable(buf, objectOffset, indexToField(2)), 20,
20); );
expect( expect(
const StringReader() const StringReader().vTableGetNullable(
.vTableGetNullable(buf, objectOffset, indexToField(3)), buf,
'12345'); objectOffset,
indexToField(3),
),
'12345',
);
expect( expect(
const Int32Reader() const Int32Reader().vTableGetNullable(buf, objectOffset, indexToField(4)),
.vTableGetNullable(buf, objectOffset, indexToField(4)), 40,
40); );
expect( expect(
const Uint32Reader() const Uint32Reader().vTableGetNullable(
.vTableGetNullable(buf, objectOffset, indexToField(5)), buf,
0x9ABCDEF0); objectOffset,
indexToField(5),
),
0x9ABCDEF0,
);
expect( expect(
const Uint8Reader() const Uint8Reader().vTableGetNullable(buf, objectOffset, indexToField(6)),
.vTableGetNullable(buf, objectOffset, indexToField(6)), 0x9A,
0x9A); );
} }
void test_writeList_of_Uint32() { void test_writeList_of_Uint32() {
@@ -596,8 +666,9 @@ class BuilderTest {
} }
// read and verify // read and verify
BufferContext buf = BufferContext.fromBytes(byteList); BufferContext buf = BufferContext.fromBytes(byteList);
List<TestPointImpl> items = List<TestPointImpl> items = const ListReader<TestPointImpl>(
const ListReader<TestPointImpl>(TestPointReader()).read(buf, 0); TestPointReader(),
).read(buf, 0);
expect(items, hasLength(2)); expect(items, hasLength(2));
expect(items[0].x, 10); expect(items[0].x, 10);
expect(items[0].y, 20); expect(items[0].y, 20);
@@ -627,8 +698,10 @@ class BuilderTest {
List<int> byteList; List<int> byteList;
{ {
builder ??= Builder(initialSize: 0); builder ??= Builder(initialSize: 0);
int listOffset = builder.writeList( int listOffset = builder.writeList([
[builder.writeString('12345'), builder.writeString('ABC')]); builder.writeString('12345'),
builder.writeString('ABC'),
]);
builder.startTable(1); builder.startTable(1);
builder.addOffset(0, listOffset); builder.addOffset(0, listOffset);
int offset = builder.endTable(); int offset = builder.endTable();
@@ -707,13 +780,14 @@ class BuilderTest {
test_table_format, test_table_format,
test_table_types, test_table_types,
test_writeList_ofObjects, test_writeList_ofObjects,
test_writeList_ofStrings_inObject test_writeList_ofStrings_inObject,
]; ];
// Execute all test cases in all permutations of their order. // Execute all test cases in all permutations of their order.
// To do that, we generate permutations of test case indexes. // To do that, we generate permutations of test case indexes.
final testCasesPermutations = final testCasesPermutations = _permutationsOf(
_permutationsOf(List.generate(testCases.length, (index) => index)); List.generate(testCases.length, (index) => index),
);
expect(testCasesPermutations.length, _factorial(testCases.length)); expect(testCasesPermutations.length, _factorial(testCases.length));
for (var indexes in testCasesPermutations) { for (var indexes in testCasesPermutations) {
@@ -783,28 +857,28 @@ class ObjectAPITest {
void test_tableMonster() { void test_tableMonster() {
final monster = example.MonsterT() final monster = example.MonsterT()
..pos = example.Vec3T( ..pos = example.Vec3T(
x: 1, x: 1,
y: 2, y: 2,
z: 3, z: 3,
test1: 4.0, test1: 4.0,
test2: example.Color.Red, test2: example.Color.Red,
test3: example.TestT(a: 1, b: 2)) test3: example.TestT(a: 1, b: 2),
)
..mana = 2 ..mana = 2
..name = 'Monstrous' ..name = 'Monstrous'
..inventory = [24, 42] ..inventory = [24, 42]
..color = example.Color.Green ..color = example.Color.Green
// TODO be smarter for unions and automatically set the `type` field?
..testType = example.AnyTypeId.MyGame_Example2_Monster ..testType = example.AnyTypeId.MyGame_Example2_Monster
..test = example2.MonsterT() ..test = example2.MonsterT()
..test4 = [example.TestT(a: 3, b: 4), example.TestT(a: 5, b: 6)] ..test4 = [example.TestT(a: 3, b: 4), example.TestT(a: 5, b: 6)]
..testarrayofstring = ["foo", "bar"] ..testarrayofstring = ["foo", "bar"]
..testarrayoftables = [example.MonsterT(name: 'Oof')] ..testarrayoftables = [example.MonsterT(name: 'Oof', testf: 2.75)]
..enemy = example.MonsterT(name: 'Enemy') ..enemy = example.MonsterT(name: 'Enemy', testf: 2.5)
..testarrayofbools = [false, true, false] ..testarrayofbools = [false, true, false]
..testf = 42.24 ..testf = 42.25
..testarrayofsortedstruct = [ ..testarrayofsortedstruct = [
example.AbilityT(id: 1, distance: 5), example.AbilityT(id: 1, distance: 5),
example.AbilityT(id: 3, distance: 7) example.AbilityT(id: 3, distance: 7),
] ]
..vectorOfLongs = [5, 6, 7] ..vectorOfLongs = [5, 6, 7]
..vectorOfDoubles = [8.9, 9.0, 10.1, 11.2] ..vectorOfDoubles = [8.9, 9.0, 10.1, 11.2]
@@ -819,16 +893,15 @@ class ObjectAPITest {
fbBuilder.finish(offset); fbBuilder.finish(offset);
final data = fbBuilder.buffer; final data = fbBuilder.buffer;
// TODO currently broken because of struct builder issue, see #6688 final monster2 = example.Monster(data); // Monster (reader)
// final monster2 = example.Monster(data); // Monster (reader) expect(
// expect( // map Monster => MonsterT, Vec3 => Vec3T, ...
// // map Monster => MonsterT, Vec3 => Vec3T, ... monster2.toString().replaceAllMapped(
// monster2.toString().replaceAllMapped( RegExp('([a-zA-z0-9]+){'), (match) => match.group(1)! + 'T{'),
// RegExp('([a-zA-z0-9]+){'), (match) => match.group(1) + 'T{'), monster.toString());
// monster.toString());
// final monster3 = monster2.unpack(); // MonsterT
// final monster3 = monster2.unpack(); // MonsterT expect(monster3.toString(), monster.toString());
// expect(monster3.toString(), monster.toString());
} }
void test_Lists() { void test_Lists() {
@@ -867,8 +940,9 @@ class StringListWrapperImpl {
StringListWrapperImpl(this.bp, this.offset); StringListWrapperImpl(this.bp, this.offset);
List<String>? get items => const ListReader<String>(StringReader()) List<String>? get items => const ListReader<String>(
.vTableGetNullable(bp, offset, indexToField(0)); StringReader(),
).vTableGetNullable(bp, offset, indexToField(0));
} }
class StringListWrapperReader extends TableReader<StringListWrapperImpl> { class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
@@ -906,10 +980,14 @@ class GeneratorTest {
expect(example.Color.values, same(example.Color.values)); expect(example.Color.values, same(example.Color.values));
expect(example.Race.values, same(example.Race.values)); expect(example.Race.values, same(example.Race.values));
expect(example.AnyTypeId.values, same(example.AnyTypeId.values)); expect(example.AnyTypeId.values, same(example.AnyTypeId.values));
expect(example.AnyUniqueAliasesTypeId.values, expect(
same(example.AnyUniqueAliasesTypeId.values)); example.AnyUniqueAliasesTypeId.values,
expect(example.AnyAmbiguousAliasesTypeId.values, same(example.AnyUniqueAliasesTypeId.values),
same(example.AnyAmbiguousAliasesTypeId.values)); );
expect(
example.AnyAmbiguousAliasesTypeId.values,
same(example.AnyAmbiguousAliasesTypeId.values),
);
} }
} }
@@ -917,11 +995,13 @@ class GeneratorTest {
@reflectiveTest @reflectiveTest
class ListOfEnumsTest { class ListOfEnumsTest {
void test_listOfEnums() async { void test_listOfEnums() async {
var mytable = example3.MyTableObjectBuilder(options: [ var mytable = example3.MyTableObjectBuilder(
example3.OptionsEnum.A, options: [
example3.OptionsEnum.B, example3.OptionsEnum.A,
example3.OptionsEnum.C example3.OptionsEnum.B,
]); example3.OptionsEnum.C,
],
);
var bytes = mytable.toBytes(); var bytes = mytable.toBytes();
var mytable_read = example3.MyTable(bytes); var mytable_read = example3.MyTable(bytes);
expect(mytable_read.options![0].value, example3.OptionsEnum.A.value); expect(mytable_read.options![0].value, example3.OptionsEnum.A.value);
@@ -934,7 +1014,8 @@ class ListOfEnumsTest {
class BoolInStructTest { class BoolInStructTest {
void test_boolInStruct() async { void test_boolInStruct() async {
var mystruct = example4.FooObjectBuilder( var mystruct = example4.FooObjectBuilder(
myFoo: example4.FooPropertiesObjectBuilder(a: true, b: false)); myFoo: example4.FooPropertiesObjectBuilder(a: true, b: false),
);
var bytes = mystruct.toBytes(); var bytes = mystruct.toBytes();
var mystruct_read = example4.Foo(bytes); var mystruct_read = example4.Foo(bytes);
expect(mystruct_read.myFoo!.a, true); expect(mystruct_read.myFoo!.a, true);

View File

@@ -62,8 +62,23 @@ void main() {
{ {
var flx = Builder(); var flx = Builder();
flx.addString('hello 😱'); flx.addString('hello 😱');
expect(flx.finish(), expect(flx.finish(), [
[10, 104, 101, 108, 108, 111, 32, 240, 159, 152, 177, 0, 11, 20, 1]); 10,
104,
101,
108,
108,
111,
32,
240,
159,
152,
177,
0,
11,
20,
1,
]);
} }
}); });
@@ -117,7 +132,7 @@ void main() {
192, 192,
16, 16,
75, 75,
1 1,
]); ]);
} }
{ {
@@ -177,7 +192,7 @@ void main() {
7, 7,
3, 3,
60, 60,
1 1,
]); ]);
} }
{ {
@@ -215,7 +230,7 @@ void main() {
10, 10,
6, 6,
60, 60,
1 1,
]); ]);
} }
{ {
@@ -300,9 +315,24 @@ void main() {
104, 104,
45, 45,
43, 43,
1 1,
]); ]);
} }
{
// Default buffer is 2048 bytes, add 2300 bytes of strings that force it
// to grow.
final s1 = 'A' * 1000;
final s2 = 'B' * 800;
final s3 = 'C' * 500;
var flx = Builder()
..startVector()
..addString(s1)
..addString(s2)
..addString(s3)
..end();
expect(flx.finish().length, 2323);
}
}); });
test('build map', () { test('build map', () {
@@ -322,8 +352,24 @@ void main() {
..addKey('') ..addKey('')
..addInt(45) ..addInt(45)
..end(); ..end();
expect( expect(flx.finish(), [
flx.finish(), [97, 0, 0, 2, 2, 5, 2, 1, 2, 45, 12, 4, 4, 4, 36, 1]); 97,
0,
0,
2,
2,
5,
2,
1,
2,
45,
12,
4,
4,
4,
36,
1,
]);
} }
{ {
var flx = Builder() var flx = Builder()
@@ -367,7 +413,7 @@ void main() {
36, 36,
4, 4,
40, 40,
1 1,
]); ]);
} }
}); });
@@ -381,133 +427,152 @@ void main() {
test('build from object', () { test('build from object', () {
expect( expect(
Builder.buildFromObject(Uint8List.fromList([1, 2, 3]).buffer) Builder.buildFromObject(
.asUint8List(), Uint8List.fromList([1, 2, 3]).buffer,
[3, 1, 2, 3, 3, 100, 1]); ).asUint8List(),
[3, 1, 2, 3, 3, 100, 1],
);
expect(Builder.buildFromObject(null).asUint8List(), [0, 0, 1]); expect(Builder.buildFromObject(null).asUint8List(), [0, 0, 1]);
expect(Builder.buildFromObject(true).asUint8List(), [1, 104, 1]); expect(Builder.buildFromObject(true).asUint8List(), [1, 104, 1]);
expect(Builder.buildFromObject(false).asUint8List(), [0, 104, 1]); expect(Builder.buildFromObject(false).asUint8List(), [0, 104, 1]);
expect(Builder.buildFromObject(25).asUint8List(), [25, 4, 1]); expect(Builder.buildFromObject(25).asUint8List(), [25, 4, 1]);
expect(Builder.buildFromObject(-250).asUint8List(), [6, 255, 5, 2]); expect(Builder.buildFromObject(-250).asUint8List(), [6, 255, 5, 2]);
expect(Builder.buildFromObject(-2.50).asUint8List(), [
0,
0,
32,
192,
14,
4,
]);
expect(Builder.buildFromObject('Maxim').asUint8List(), [
5,
77,
97,
120,
105,
109,
0,
6,
20,
1,
]);
expect( expect(
Builder.buildFromObject(-2.50).asUint8List(), [0, 0, 32, 192, 14, 4]); Builder.buildFromObject([1, 3.3, 'max', true, null, false]).asUint8List(),
expect(Builder.buildFromObject('Maxim').asUint8List(), [
[5, 77, 97, 120, 105, 109, 0, 6, 20, 1]); 3,
109,
97,
120,
0,
0,
0,
0,
6,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
102,
102,
102,
102,
102,
102,
10,
64,
31,
0,
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
4,
15,
20,
104,
0,
104,
54,
43,
1,
],
);
expect( expect(
Builder.buildFromObject([1, 3.3, 'max', true, null, false]) Builder.buildFromObject([
.asUint8List(), {'something': 12},
[ {'something': 45},
3, ]).asUint8List(),
109, [
97, 115,
120, 111,
0, 109,
0, 101,
0, 116,
0, 104,
6, 105,
0, 110,
0, 103,
0, 0,
0, 1,
0, 11,
0, 1,
0, 1,
1, 1,
0, 12,
0, 4,
0, 6,
0, 1,
0, 1,
0, 45,
0, 4,
102, 2,
102, 8,
102, 4,
102, 36,
102, 36,
102, 4,
10, 40,
64, 1,
31, ],
0, );
0,
0,
0,
0,
0,
0,
1,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
4,
15,
20,
104,
0,
104,
54,
43,
1
]);
expect(
Builder.buildFromObject([
{'something': 12},
{'something': 45}
]).asUint8List(),
[
115,
111,
109,
101,
116,
104,
105,
110,
103,
0,
1,
11,
1,
1,
1,
12,
4,
6,
1,
1,
45,
4,
2,
8,
4,
36,
36,
4,
40,
1
]);
}); });
test('add double indirectly', () { test('add double indirectly', () {
@@ -543,7 +608,7 @@ void main() {
35, 35,
8, 8,
40, 40,
1 1,
]); ]);
}); });
@@ -580,7 +645,7 @@ void main() {
27, 27,
8, 8,
40, 40,
1 1,
]); ]);
}); });

File diff suppressed because it is too large Load Diff

View File

@@ -48,116 +48,210 @@ void main() {
expect(ValueTypeUtils.isFixedTypedVector(ValueType.VectorInt), isFalse); expect(ValueTypeUtils.isFixedTypedVector(ValueType.VectorInt), isFalse);
}); });
test('to typed vector', () { test('to typed vector', () {
expect(ValueTypeUtils.toTypedVector(ValueType.Int, 0), expect(
equals(ValueType.VectorInt)); ValueTypeUtils.toTypedVector(ValueType.Int, 0),
expect(ValueTypeUtils.toTypedVector(ValueType.UInt, 0), equals(ValueType.VectorInt),
equals(ValueType.VectorUInt)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Bool, 0), expect(
equals(ValueType.VectorBool)); ValueTypeUtils.toTypedVector(ValueType.UInt, 0),
expect(ValueTypeUtils.toTypedVector(ValueType.Float, 0), equals(ValueType.VectorUInt),
equals(ValueType.VectorFloat)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Key, 0), expect(
equals(ValueType.VectorKey)); ValueTypeUtils.toTypedVector(ValueType.Bool, 0),
expect(ValueTypeUtils.toTypedVector(ValueType.String, 0), equals(ValueType.VectorBool),
equals(ValueType.VectorString)); );
expect(
ValueTypeUtils.toTypedVector(ValueType.Float, 0),
equals(ValueType.VectorFloat),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.Key, 0),
equals(ValueType.VectorKey),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.String, 0),
equals(ValueType.VectorString),
);
expect(ValueTypeUtils.toTypedVector(ValueType.Int, 2), expect(
equals(ValueType.VectorInt2)); ValueTypeUtils.toTypedVector(ValueType.Int, 2),
expect(ValueTypeUtils.toTypedVector(ValueType.UInt, 2), equals(ValueType.VectorInt2),
equals(ValueType.VectorUInt2)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Float, 2), expect(
equals(ValueType.VectorFloat2)); ValueTypeUtils.toTypedVector(ValueType.UInt, 2),
equals(ValueType.VectorUInt2),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.Float, 2),
equals(ValueType.VectorFloat2),
);
expect(ValueTypeUtils.toTypedVector(ValueType.Int, 3), expect(
equals(ValueType.VectorInt3)); ValueTypeUtils.toTypedVector(ValueType.Int, 3),
expect(ValueTypeUtils.toTypedVector(ValueType.UInt, 3), equals(ValueType.VectorInt3),
equals(ValueType.VectorUInt3)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Float, 3), expect(
equals(ValueType.VectorFloat3)); ValueTypeUtils.toTypedVector(ValueType.UInt, 3),
equals(ValueType.VectorUInt3),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.Float, 3),
equals(ValueType.VectorFloat3),
);
expect(ValueTypeUtils.toTypedVector(ValueType.Int, 4), expect(
equals(ValueType.VectorInt4)); ValueTypeUtils.toTypedVector(ValueType.Int, 4),
expect(ValueTypeUtils.toTypedVector(ValueType.UInt, 4), equals(ValueType.VectorInt4),
equals(ValueType.VectorUInt4)); );
expect(ValueTypeUtils.toTypedVector(ValueType.Float, 4), expect(
equals(ValueType.VectorFloat4)); ValueTypeUtils.toTypedVector(ValueType.UInt, 4),
equals(ValueType.VectorUInt4),
);
expect(
ValueTypeUtils.toTypedVector(ValueType.Float, 4),
equals(ValueType.VectorFloat4),
);
}); });
test('typed vector element type', () { test('typed vector element type', () {
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorInt), expect(
equals(ValueType.Int)); ValueTypeUtils.typedVectorElementType(ValueType.VectorInt),
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorUInt), equals(ValueType.Int),
equals(ValueType.UInt)); );
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorFloat), expect(
equals(ValueType.Float)); ValueTypeUtils.typedVectorElementType(ValueType.VectorUInt),
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorString), equals(ValueType.UInt),
equals(ValueType.String)); );
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorKey), expect(
equals(ValueType.Key)); ValueTypeUtils.typedVectorElementType(ValueType.VectorFloat),
expect(ValueTypeUtils.typedVectorElementType(ValueType.VectorBool), equals(ValueType.Float),
equals(ValueType.Bool)); );
expect(
ValueTypeUtils.typedVectorElementType(ValueType.VectorString),
equals(ValueType.String),
);
expect(
ValueTypeUtils.typedVectorElementType(ValueType.VectorKey),
equals(ValueType.Key),
);
expect(
ValueTypeUtils.typedVectorElementType(ValueType.VectorBool),
equals(ValueType.Bool),
);
}); });
test('fixed typed vector element type', () { test('fixed typed vector element type', () {
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt2), expect(
equals(ValueType.Int)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt2),
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt3), equals(ValueType.Int),
equals(ValueType.Int)); );
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt4), expect(
equals(ValueType.Int)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt3),
equals(ValueType.Int),
);
expect(
ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorInt4),
equals(ValueType.Int),
);
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt2), expect(
equals(ValueType.UInt)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt2),
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt3), equals(ValueType.UInt),
equals(ValueType.UInt)); );
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt4), expect(
equals(ValueType.UInt)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt3),
equals(ValueType.UInt),
);
expect(
ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorUInt4),
equals(ValueType.UInt),
);
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat2), expect(
equals(ValueType.Float)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat2),
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat3), equals(ValueType.Float),
equals(ValueType.Float)); );
expect(ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat4), expect(
equals(ValueType.Float)); ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat3),
equals(ValueType.Float),
);
expect(
ValueTypeUtils.fixedTypedVectorElementType(ValueType.VectorFloat4),
equals(ValueType.Float),
);
}); });
test('fixed typed vector element size', () { test('fixed typed vector element size', () {
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt2), expect(
equals(2)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt2),
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt3), equals(2),
equals(3)); );
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt4), expect(
equals(4)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt3),
equals(3),
);
expect(
ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorInt4),
equals(4),
);
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt2), expect(
equals(2)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt2),
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt3), equals(2),
equals(3)); );
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt4), expect(
equals(4)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt3),
equals(3),
);
expect(
ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorUInt4),
equals(4),
);
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat2), expect(
equals(2)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat2),
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat3), equals(2),
equals(3)); );
expect(ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat4), expect(
equals(4)); ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat3),
equals(3),
);
expect(
ValueTypeUtils.fixedTypedVectorElementSize(ValueType.VectorFloat4),
equals(4),
);
}); });
test('packed type', () { test('packed type', () {
expect( expect(
ValueTypeUtils.packedType(ValueType.Null, BitWidth.width8), equals(0)); ValueTypeUtils.packedType(ValueType.Null, BitWidth.width8),
equals(0),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Null, BitWidth.width16), equals(1)); ValueTypeUtils.packedType(ValueType.Null, BitWidth.width16),
equals(1),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Null, BitWidth.width32), equals(2)); ValueTypeUtils.packedType(ValueType.Null, BitWidth.width32),
equals(2),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Null, BitWidth.width64), equals(3)); ValueTypeUtils.packedType(ValueType.Null, BitWidth.width64),
equals(3),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Int, BitWidth.width8), equals(4)); ValueTypeUtils.packedType(ValueType.Int, BitWidth.width8),
equals(4),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Int, BitWidth.width16), equals(5)); ValueTypeUtils.packedType(ValueType.Int, BitWidth.width16),
equals(5),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Int, BitWidth.width32), equals(6)); ValueTypeUtils.packedType(ValueType.Int, BitWidth.width32),
equals(6),
);
expect( expect(
ValueTypeUtils.packedType(ValueType.Int, BitWidth.width64), equals(7)); ValueTypeUtils.packedType(ValueType.Int, BitWidth.width64),
equals(7),
);
}); });
test('bit width', () { test('bit width', () {
expect(BitWidthUtil.width(0), BitWidth.width8); expect(BitWidthUtil.width(0), BitWidth.width8);

View File

@@ -2,10 +2,11 @@
// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names // ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable, constant_identifier_names
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
import './include_test2_my_game.other_name_space_generated.dart'
import './include_test2_my_game.other_name_space_generated.dart' as my_game_other_name_space; as my_game_other_name_space;
class TableA { class TableA {
TableA._(this._bc, this._bcOffset); TableA._(this._bc, this._bcOffset);
@@ -19,15 +20,17 @@ class TableA {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
my_game_other_name_space.TableB? get b => my_game_other_name_space.TableB.reader.vTableGetNullable(_bc, _bcOffset, 4); my_game_other_name_space.TableB? get b => my_game_other_name_space
.TableB
.reader
.vTableGetNullable(_bc, _bcOffset, 4);
@override @override
String toString() { String toString() {
return 'TableA{b: ${b}}'; return 'TableA{b: ${b}}';
} }
TableAT unpack() => TableAT( TableAT unpack() => TableAT(b: b?.unpack());
b: b?.unpack());
static int pack(fb.Builder fbBuilder, TableAT? object) { static int pack(fb.Builder fbBuilder, TableAT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -38,8 +41,7 @@ class TableA {
class TableAT implements fb.Packable { class TableAT implements fb.Packable {
my_game_other_name_space.TableBT? b; my_game_other_name_space.TableBT? b;
TableAT({ TableAT({this.b});
this.b});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -59,8 +61,7 @@ class _TableAReader extends fb.TableReader<TableA> {
const _TableAReader(); const _TableAReader();
@override @override
TableA createObject(fb.BufferContext bc, int offset) => TableA createObject(fb.BufferContext bc, int offset) => TableA._(bc, offset);
TableA._(bc, offset);
} }
class TableABuilder { class TableABuilder {
@@ -85,10 +86,8 @@ class TableABuilder {
class TableAObjectBuilder extends fb.ObjectBuilder { class TableAObjectBuilder extends fb.ObjectBuilder {
final my_game_other_name_space.TableBObjectBuilder? _b; final my_game_other_name_space.TableBObjectBuilder? _b;
TableAObjectBuilder({ TableAObjectBuilder({my_game_other_name_space.TableBObjectBuilder? b})
my_game_other_name_space.TableBObjectBuilder? b, : _b = b;
})
: _b = b;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override

View File

@@ -4,8 +4,8 @@
library my_game.other_name_space; library my_game.other_name_space;
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import 'package:flat_buffers/flat_buffers.dart' as fb;
import './include_test1_generated.dart'; import './include_test1_generated.dart';
@@ -17,8 +17,10 @@ enum FromInclude {
factory FromInclude.fromValue(int value) { factory FromInclude.fromValue(int value) {
switch (value) { switch (value) {
case 0: return FromInclude.IncludeVal; case 0:
default: throw StateError('Invalid value $value for bit flag enum'); return FromInclude.IncludeVal;
default:
throw StateError('Invalid value $value for bit flag enum');
} }
} }
@@ -56,8 +58,7 @@ class Unused {
return 'Unused{a: ${a}}'; return 'Unused{a: ${a}}';
} }
UnusedT unpack() => UnusedT( UnusedT unpack() => UnusedT(a: a);
a: a);
static int pack(fb.Builder fbBuilder, UnusedT? object) { static int pack(fb.Builder fbBuilder, UnusedT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -68,8 +69,7 @@ class Unused {
class UnusedT implements fb.Packable { class UnusedT implements fb.Packable {
int a; int a;
UnusedT({ UnusedT({required this.a});
required this.a});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -90,8 +90,7 @@ class _UnusedReader extends fb.StructReader<Unused> {
int get size => 4; int get size => 4;
@override @override
Unused createObject(fb.BufferContext bc, int offset) => Unused createObject(fb.BufferContext bc, int offset) => Unused._(bc, offset);
Unused._(bc, offset);
} }
class UnusedBuilder { class UnusedBuilder {
@@ -103,16 +102,12 @@ class UnusedBuilder {
fbBuilder.putInt32(a); fbBuilder.putInt32(a);
return fbBuilder.offset; return fbBuilder.offset;
} }
} }
class UnusedObjectBuilder extends fb.ObjectBuilder { class UnusedObjectBuilder extends fb.ObjectBuilder {
final int _a; final int _a;
UnusedObjectBuilder({ UnusedObjectBuilder({required int a}) : _a = a;
required int a,
})
: _a = a;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override
@@ -129,6 +124,7 @@ class UnusedObjectBuilder extends fb.ObjectBuilder {
return fbBuilder.buffer; return fbBuilder.buffer;
} }
} }
class TableB { class TableB {
TableB._(this._bc, this._bcOffset); TableB._(this._bc, this._bcOffset);
factory TableB(List<int> bytes) { factory TableB(List<int> bytes) {
@@ -148,8 +144,7 @@ class TableB {
return 'TableB{a: ${a}}'; return 'TableB{a: ${a}}';
} }
TableBT unpack() => TableBT( TableBT unpack() => TableBT(a: a?.unpack());
a: a?.unpack());
static int pack(fb.Builder fbBuilder, TableBT? object) { static int pack(fb.Builder fbBuilder, TableBT? object) {
if (object == null) return 0; if (object == null) return 0;
@@ -160,8 +155,7 @@ class TableB {
class TableBT implements fb.Packable { class TableBT implements fb.Packable {
TableAT? a; TableAT? a;
TableBT({ TableBT({this.a});
this.a});
@override @override
int pack(fb.Builder fbBuilder) { int pack(fb.Builder fbBuilder) {
@@ -181,8 +175,7 @@ class _TableBReader extends fb.TableReader<TableB> {
const _TableBReader(); const _TableBReader();
@override @override
TableB createObject(fb.BufferContext bc, int offset) => TableB createObject(fb.BufferContext bc, int offset) => TableB._(bc, offset);
TableB._(bc, offset);
} }
class TableBBuilder { class TableBBuilder {
@@ -207,10 +200,7 @@ class TableBBuilder {
class TableBObjectBuilder extends fb.ObjectBuilder { class TableBObjectBuilder extends fb.ObjectBuilder {
final TableAObjectBuilder? _a; final TableAObjectBuilder? _a;
TableBObjectBuilder({ TableBObjectBuilder({TableAObjectBuilder? a}) : _a = a;
TableAObjectBuilder? a,
})
: _a = a;
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].
@override @override

View File

@@ -7,6 +7,7 @@ import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
enum Abc { enum Abc {
$void(0), $void(0),
where(1), where(1),
@@ -276,7 +277,7 @@ class Table2 {
Table2T unpack() => Table2T( Table2T unpack() => Table2T(
typeType: typeType, typeType: typeType,
type: type); type: type?.unpack());
static int pack(fb.Builder fbBuilder, Table2T? object) { static int pack(fb.Builder fbBuilder, Table2T? object) {
if (object == null) return 0; if (object == null) return 0;

View File

@@ -4,12 +4,12 @@
library my_game.example2; library my_game.example2;
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
import './monster_test_my_game_generated.dart' as my_game;
import './monster_test_my_game.example_generated.dart' as my_game_example;
import './include_test1_generated.dart'; import './include_test1_generated.dart';
import './monster_test_my_game.example_generated.dart' as my_game_example;
import './monster_test_my_game_generated.dart' as my_game;
class Monster { class Monster {
Monster._(this._bc, this._bcOffset); Monster._(this._bc, this._bcOffset);
@@ -23,7 +23,6 @@ class Monster {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
@override @override
String toString() { String toString() {
return 'Monster{}'; return 'Monster{}';
@@ -54,12 +53,11 @@ class _MonsterReader extends fb.TableReader<Monster> {
const _MonsterReader(); const _MonsterReader();
@override @override
Monster createObject(fb.BufferContext bc, int offset) => Monster createObject(fb.BufferContext bc, int offset) =>
Monster._(bc, offset); Monster._(bc, offset);
} }
class MonsterObjectBuilder extends fb.ObjectBuilder { class MonsterObjectBuilder extends fb.ObjectBuilder {
MonsterObjectBuilder(); MonsterObjectBuilder();
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].

File diff suppressed because it is too large Load Diff

View File

@@ -4,12 +4,12 @@
library my_game; library my_game;
import 'dart:typed_data' show Uint8List; import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
import './monster_test_my_game.example_generated.dart' as my_game_example;
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
import './include_test1_generated.dart'; import './include_test1_generated.dart';
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
import './monster_test_my_game.example_generated.dart' as my_game_example;
class InParentNamespace { class InParentNamespace {
InParentNamespace._(this._bc, this._bcOffset); InParentNamespace._(this._bc, this._bcOffset);
@@ -23,7 +23,6 @@ class InParentNamespace {
final fb.BufferContext _bc; final fb.BufferContext _bc;
final int _bcOffset; final int _bcOffset;
@override @override
String toString() { String toString() {
return 'InParentNamespace{}'; return 'InParentNamespace{}';
@@ -54,12 +53,11 @@ class _InParentNamespaceReader extends fb.TableReader<InParentNamespace> {
const _InParentNamespaceReader(); const _InParentNamespaceReader();
@override @override
InParentNamespace createObject(fb.BufferContext bc, int offset) => InParentNamespace createObject(fb.BufferContext bc, int offset) =>
InParentNamespace._(bc, offset); InParentNamespace._(bc, offset);
} }
class InParentNamespaceObjectBuilder extends fb.ObjectBuilder { class InParentNamespaceObjectBuilder extends fb.ObjectBuilder {
InParentNamespaceObjectBuilder(); InParentNamespaceObjectBuilder();
/// Finish building, and store into the [fbBuilder]. /// Finish building, and store into the [fbBuilder].

View File

@@ -6,7 +6,7 @@ https://flatbuffers.dev.
## Local Building ## Local Building
The documentation can be built and served locally during development, see [https//flatbuffers.dev/contributing/#local-development] for full details. The documentation can be built and served locally during development, see <https://flatbuffers.dev/contributing/#local-development> for full details.
__tl;dr__ __tl;dr__
@@ -21,4 +21,4 @@ Build and Serve:
``` ```
mkdocs serve -f docs/mkdocs.yml mkdocs serve -f docs/mkdocs.yml
``` ```

View File

@@ -139,7 +139,7 @@ nav:
- Dart: "languages/dart.md" - Dart: "languages/dart.md"
- Go: "languages/go.md" - Go: "languages/go.md"
- Java: "languages/java.md" - Java: "languages/java.md"
- JavasScript: "languages/javascript.md" - JavaScript: "languages/javascript.md"
- Kotlin: "languages/kotlin.md" - Kotlin: "languages/kotlin.md"
- Lobster: "languages/lobster.md" - Lobster: "languages/lobster.md"
- Lua: "languages/lua.md" - Lua: "languages/lua.md"

View File

@@ -55,8 +55,8 @@ The columns are as follows:
The prefix `+` is added to make searching for the offset (compared to some The prefix `+` is added to make searching for the offset (compared to some
random value) a bit easier. random value) a bit easier.
2. The raw binary data, expressed in hexadecimal format. 2. The raw binary data, expressed in hexadecimal format.
This is in the little endian format the buffer uses internally and what you This is in the little endian format the buffer uses internally and what you
would see with a normal binary text viewer. would see with a normal binary text viewer.
@@ -108,7 +108,7 @@ regions in the flatbuffer itself.
### Binary Regions ### Binary Regions
Binary regions are contiguous bytes regions that are grouped together to form Binary regions are contiguous bytes regions that are grouped together to form
some sort of value, e.g. a `scalar` or an array of scalars. A binary region may some sort of value, e.g. a `scalar` or an array of scalars. A binary region may
be split up over multiple text lines, if the size of the region is large. be split up over multiple text lines, if the size of the region is large.
@@ -122,7 +122,7 @@ vtable (AnnotatedBinary.Bar):
``` ```
The first column (`+0x00A0`) is the offset to this region from the beginning of The first column (`+0x00A0`) is the offset to this region from the beginning of
the buffer. the buffer.
The second column are the raw bytes (hexadecimal) that make up this region. The second column are the raw bytes (hexadecimal) that make up this region.
These are expressed in the little-endian format that flatbuffers uses for the These are expressed in the little-endian format that flatbuffers uses for the
@@ -135,7 +135,7 @@ The fourth column shows the raw bytes as a compacted, big-endian value. The raw
bytes are duplicated in this fashion since it is more intuitive to read the data bytes are duplicated in this fashion since it is more intuitive to read the data
in the big-endian format (e.g., `0x0008`). This value is followed by the decimal in the big-endian format (e.g., `0x0008`). This value is followed by the decimal
representation of the value (e.g., `(8)`). For strings, the raw string value is representation of the value (e.g., `(8)`). For strings, the raw string value is
shown instead. shown instead.
The fifth column is a textual comment on what the value is. As much metadata as The fifth column is a textual comment on what the value is. As much metadata as
known is provided. known is provided.
@@ -146,4 +146,4 @@ If the type in the 3rd column is of an absolute offset (`SOffet32` or
`Offset32`), the fourth column also shows an `Loc: +0x025A` value which shows `Offset32`), the fourth column also shows an `Loc: +0x025A` value which shows
where in the binary this region is pointing to. These values are absolute from where in the binary this region is pointing to. These values are absolute from
the beginning of the file, their calculation from the raw value in the 4th the beginning of the file, their calculation from the raw value in the 4th
column depends on the context. column depends on the context.

View File

@@ -89,6 +89,17 @@ CC=clang PATH=$PATH:$(pwd)/swift-${SWIFT_VERSION}-RELEASE-debian12/usr/bin bazel
If you are unsure which versions to use, check our CI config at `.bazelci/presubmit.yml`. If you are unsure which versions to use, check our CI config at `.bazelci/presubmit.yml`.
## Building with Conan
You can download and install flatbuffers using the [Conan](https://conan.io/) dependency manager:
conan install --requires="flatbuffers/[*]" --build=missing
The flatbuffers package in Conan Center is maintained by
[ConanCenterIndex](https://github.com/conan-io/conan-center-index) community.
If the version is out of date or the package does not work,
please create an issue or pull request on the [Conan Center Index repository](https://github.com/conan-io/conan-center-index).
## Building with VCPKG ## Building with VCPKG
You can download and install flatbuffers using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: You can download and install flatbuffers using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
@@ -152,11 +163,11 @@ add_subdirectory(${FLATBUFFERS_SRC_DIR}
# The flatbuffers target carry header search path automatically if CMake > 2.8.11. # The flatbuffers target carry header search path automatically if CMake > 2.8.11.
target_link_libraries(own_project_target PRIVATE flatbuffers) target_link_libraries(own_project_target PRIVATE flatbuffers)
``` ```
When build your project the `flatbuffers` library will be compiled and linked When build your project the `flatbuffers` library will be compiled and linked
to a target as part of your project. to a target as part of your project.
#### Override default depth limit of nested objects #### Override default depth limit of nested objects
To override [the depth limit of recursion](languages/cpp.md), To override [the depth limit of recursion](languages/cpp.md),
add this directive: add this directive:
```cmake ```cmake
set(FLATBUFFERS_MAX_PARSING_DEPTH 16) set(FLATBUFFERS_MAX_PARSING_DEPTH 16)
@@ -174,4 +185,4 @@ We generate [SLSA3 signatures](http://slsa.dev) using the OpenSSF's [slsa-framew
```shell ```shell
$ slsa-verifier -artifact-path <downloaded.zip> -provenance attestation.intoto.jsonl -source github.com/google/flatbuffers -tag <version> $ slsa-verifier -artifact-path <downloaded.zip> -provenance attestation.intoto.jsonl -source github.com/google/flatbuffers -tag <version>
PASSED: Verified SLSA provenance PASSED: Verified SLSA provenance
``` ```

View File

@@ -15,17 +15,17 @@ repository.
Before we can use your contributions, you __must__ sign one of the following license agreements. The agreements are self-served at the following links. Before we can use your contributions, you __must__ sign one of the following license agreements. The agreements are self-served at the following links.
Our code review process will automatically check if you have signed the CLA, so Our code review process will automatically check if you have signed the CLA, so
don't fret. Though it may be prudent to check before spending a lot of time on don't fret. Though it may be prudent to check before spending a lot of time on
contribution. contribution.
### Individual Contributions ### Individual Contributions
For individuals, the [Google Individual For individuals, the [Google Individual
Contributor License Agreement Contributor License Agreement
(CLA)](https://cla.developers.google.com/about/google-individual?csw=1) which is (CLA)](https://cla.developers.google.com/about/google-individual?csw=1) which is
self served at the link. The CLA is required since you own the copyright to your self served at the link. The CLA is required since you own the copyright to your
changes, even after your contribution becomes part of our codebase, so we need changes, even after your contribution becomes part of our codebase, so we need
your permission to use and distribute your code. your permission to use and distribute your code.
### Corporate Contributions ### Corporate Contributions
@@ -67,7 +67,7 @@ pip install mkdocs-material
pip install mkdocs-redirects pip install mkdocs-redirects
``` ```
Then, in the `root` directory of flatbuffers, run Then, in the `root` directory of flatbuffers, run
``` ```
mkdocs serve -f docs/mkdocs.yml mkdocs serve -f docs/mkdocs.yml
@@ -77,4 +77,4 @@ This will continually watch the repo for changes to the documentation and serve
the rendered pages locally. the rendered pages locally.
Submit your documentation changes with your code changes and they will Submit your documentation changes with your code changes and they will
automatically get published when your code is submitted. automatically get published when your code is submitted.

View File

@@ -261,7 +261,7 @@ a [option](flatc.md#additional-options) to do just that:
```sh ```sh
--conform FILE --conform FILE
``` ```
Where `FILE` is the base schema the rest of the input schemas must evolve from. Where `FILE` is the base schema the rest of the input schemas must evolve from.
It returns `0` if they are properly evolved, otherwise returns a non-zero value It returns `0` if they are properly evolved, otherwise returns a non-zero value

View File

@@ -1,13 +1,13 @@
# FlatBuffers Compiler (`flatc`) # FlatBuffers Compiler (`flatc`)
The main compiler for FlatBuffers is called `flatc` and is used to convert The main compiler for FlatBuffers is called `flatc` and is used to convert
schema definitions into generated code files for a variety of languages. schema definitions into generated code files for a variety of languages.
After [building](building.md) `flatc`, it is used as follows: After [building](building.md) `flatc`, it is used as follows:
```sh ```sh
flatc [ GENERATOR_OPTIONS ] [ -o PATH ] [- I PATH ] flatc [ GENERATOR_OPTIONS ] [ -o PATH ] [- I PATH ]
FILES... FILES...
[ -- BINARY_FILES... ] [ -- BINARY_FILES... ]
``` ```
@@ -65,25 +65,26 @@ list of `FILES...`.
=== "To Binary" === "To Binary"
To serialize the JSON data in `mydata.json` using the schema `myschema.fbs`: To serialize the JSON data in `mydata.json` using the schema `myschema.fbs`:
```sh ```sh
flatc --binary myschema.fbs mydata.json flatc --binary myschema.fbs mydata.json
``` ```
This will generate a `mydata_wire.bin` file containing the serialized This will generate a `mydata_wire.bin` file containing the serialized
flatbuffer data. flatbuffer data.
=== "To JSON" === "To JSON"
To convert the serialized binary flatbuffer `mydata.bin` using the schema To convert the serialized binary flatbuffer `mydata.bin` using the schema
`myschema.fbs` to JSON: `myschema.fbs` to JSON:
```sh ```sh
flatc --json myschema.fbs mydata.bin flatc --json myschema.fbs -- mydata.bin
``` ```
This will generate a `mydata.json` file. This will generate a `mydata.json` file. If there is no
[`file_identifier`](schema.md/#file-identification-and-extension) defined
for this schema, you will need to use the `--raw-binary` option.
### Additional options ### Additional options
@@ -131,7 +132,7 @@ list of `FILES...`.
- `--gen-mutable` : Generate additional non-const accessors for mutating - `--gen-mutable` : Generate additional non-const accessors for mutating
FlatBuffers in-place. FlatBuffers in-place.
- `--gen-onefile` : Generate single output file for C#, Go, and Python. - `--gen-onefile` : Generate a single output file for C#, Go, Java, Kotlin and Python.
- `--gen-name-strings` : Generate type name functions for C++. - `--gen-name-strings` : Generate type name functions for C++.
@@ -259,6 +260,11 @@ list of `FILES...`.
- `--python-typing` : Generate Python type annotations - `--python-typing` : Generate Python type annotations
- `--python-decode-obj-api-strings` : Decode bytes automaticaly with utf-8
- `--file-names-only` : Prints out files which would be generated by this command, one per
line, to `stdout`. No actual files are generated. This is useful for various CI checks.
Additional gRPC options: Additional gRPC options:
- `--grpc-filename-suffix`: `[C++]` An optional suffix for the generated - `--grpc-filename-suffix`: `[C++]` An optional suffix for the generated

View File

@@ -21,15 +21,15 @@ It is available as Open Source on
- :material-memory:{ .lg .middle } **Memory Efficiency and Speed** - :material-memory:{ .lg .middle } **Memory Efficiency and Speed**
--- ---
The only memory needed to access your data is that of the buffer. No heap is The only memory needed to access your data is that of the buffer.
required. No heap is required.
- :material-compare-horizontal:{ .lg .middle } **Backwards and Forwards - :material-compare-horizontal:{ .lg .middle } **Backwards and Forwards
Compatibility** Compatibility**
--- ---
The only memory needed to access your data is that of the buffer. No heap is FlatBuffers enables the schema to evolve over time while still maintaining
required. forwards and backwards compatibility with old flatbuffers.
- :material-scale-off:{ .lg .middle } **Small Footprint** - :material-scale-off:{ .lg .middle } **Small Footprint**

View File

@@ -6,7 +6,7 @@ errors and stores the resulting data in this IR, outputting `.bfbs` files.
Since this IR is a Flatbuffer, you can load and use it at runtime for runtime Since this IR is a Flatbuffer, you can load and use it at runtime for runtime
reflection purposes. reflection purposes.
There are some quirks: There are some quirks:
- Tables and Structs are serialized as `Object`s. - Tables and Structs are serialized as `Object`s.
- Unions and Enums are serialized as `Enum`s. - Unions and Enums are serialized as `Enum`s.
- It is the responsibility of the code generator to check the `advanced_features` - It is the responsibility of the code generator to check the `advanced_features`
@@ -18,7 +18,7 @@ There are some quirks:
inferred to be the directory containing the first provided schema file. inferred to be the directory containing the first provided schema file.
## Invocation ## Invocation
You can invoke it like so You can invoke it like so
```{.sh} ```{.sh}
flatc -b --schema ${your_fbs_files} flatc -b --schema ${your_fbs_files}

View File

@@ -23,7 +23,7 @@ FlatBuffers).
## Building the FlatBuffers C# library ## Building the FlatBuffers C# library
The `FlatBuffers.csproj` project contains multitargeting for .NET Standard 2.1, The `FlatBuffers.csproj` project contains multitargeting for .NET Standard 2.0, 2.1,
.NET 6 and .NET 8. .NET 6 and .NET 8.
You can build for a specific framework target when using the cross-platform You can build for a specific framework target when using the cross-platform

View File

@@ -57,7 +57,7 @@ a `char *` array, which you pass to `GetMonster()`.
```cpp ```cpp
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "monster_test_generate.h" #include "monster_test_generated.h"
#include <iostream> // C++ header file for printing #include <iostream> // C++ header file for printing
#include <fstream> // C++ header file for file access #include <fstream> // C++ header file for file access
@@ -242,6 +242,41 @@ provide the following functions to aide in the serialization process:
} }
``` ```
- `native_type("type")` (on a table): Tables can also be represented with
native types. For example, the following schema:
```cpp
table Matrix (native_type: "NativeMatrix") {
rows: int32;
columns: int32;
values: [float];
}
```
Would be represented by a user-defined C++ class:
```cpp
class NativeMatrix { ... }
```
In this case, the following function declarations are generated by the compiler.
The user must provide and link the matching function definitions:
```cpp
struct Matrix FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
// ...
static ::flatbuffers::Offset<Matrix> Pack(
::flatbuffers::FlatBufferBuilder& _fbb,
const NativeMatrix* _o,
const ::flatbuffers::rehasher_function_t* _rehasher = nullptr);
void UnPackTo(
NativeMatrix* _o,
const ::flatbuffers::resolver_function_t* _resolver = nullptr) const;
}
```
Finally, the following top-level attributes: Finally, the following top-level attributes:
- `native_include("path")` (at file level): Because the `native_type` attribute - `native_include("path")` (at file level): Because the `native_type` attribute
@@ -419,7 +454,8 @@ Each root type will have a verification function generated for it,
e.g. for `Monster`, you can call: e.g. for `Monster`, you can call:
```cpp ```cpp
bool ok = VerifyMonsterBuffer(Verifier(buf, len)); Verifier verifier(buf, len);
bool ok = VerifyMonsterBuffer(verifier);
``` ```
if `ok` is true, the buffer is safe to read. if `ok` is true, the buffer is safe to read.

View File

@@ -93,7 +93,7 @@ significant changes have been made.
goal of this implementation. Support for 16 bit integers was also added. goal of this implementation. Support for 16 bit integers was also added.
5. The code generation in this offers an "ObjectBuilder", which generates code 5. The code generation in this offers an "ObjectBuilder", which generates code
very similar to the SDK classes that consume FlatBuffers, as well as Builder very similar to the SDK classes that consume FlatBuffers, as well as Builder
classes, which produces code which more closely resembles the builders in classes, which produces code which more closely resembles the builders in
other languages. The ObjectBuilder classes are easier to use, at the cost of other languages. The ObjectBuilder classes are easier to use, at the cost of
additional references allocated. additional references allocated.

View File

@@ -16,7 +16,7 @@ documentation to build `flatc` and should be familiar with
## FlatBuffers JavaScript library code location ## FlatBuffers JavaScript library code location
The generated code for the FlatBuffers JavaScript library can be found at The generated code for the FlatBuffers JavaScript library can be found at
https://www.npmjs.com/package/flatbuffers. To use it from sources: https://www.npmjs.com/package/flatbuffers. To use it from sources:
1. Run `npm run compile` from the main folder to generate JS files from TS. 1. Run `npm run compile` from the main folder to generate JS files from TS.
@@ -36,7 +36,7 @@ transpile your sources to desired JS flavor. The minimal steps to get up and
running with JS are: running with JS are:
1. Generate TS files from `*.fbs` by using the `--ts` option. 1. Generate TS files from `*.fbs` by using the `--ts` option.
1. Transpile resulting TS files to desired JS flavor using `tsc` (see 1. Transpile resulting TS files to desired JS flavor using `tsc` (see
https://www.typescriptlang.org/download for installation instructions). https://www.typescriptlang.org/download for installation instructions).
~~~{.js} ~~~{.js}

View File

@@ -81,4 +81,4 @@ Kotlin generated code was designed to be as close as possible to the java counte
The most obvious ones are: The most obvious ones are:
* Fields as accessed as Kotlin [properties](https://kotlinlang.org/docs/reference/properties.html) * Fields as accessed as Kotlin [properties](https://kotlinlang.org/docs/reference/properties.html)
* Static methods are accessed in [companion object](https://kotlinlang.org/docs/reference/classes.html#companion-objects) * Static methods are accessed in [companion object](https://kotlinlang.org/docs/reference/classes.html#companion-objects)

View File

@@ -50,7 +50,7 @@ file into a `string`, which you pass to the `GetRootAsMonster` function:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lua} ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lua}
-- require the library -- require the library
local flatbuffers = require("flatbuffers") local flatbuffers = require("flatbuffers")
-- require the generated code -- require the generated code
local monster = require("MyGame.Sample.Monster") local monster = require("MyGame.Sample.Monster")

View File

@@ -48,7 +48,7 @@ function). Then you can read a FlatBuffer binary file, which you
pass the contents of to the `GetRootAsMonster` function: pass the contents of to the `GetRootAsMonster` function:
~~~{.php} ~~~{.php}
// It is recommended that your use PSR autoload when using FlatBuffers in PHP. // It is recommended that you use PSR autoload when using FlatBuffers in PHP.
// Here is an example: // Here is an example:
function __autoload($class_name) { function __autoload($class_name) {
// The last segment of the class name matches the file name. // The last segment of the class name matches the file name.
@@ -69,7 +69,7 @@ pass the contents of to the `GetRootAsMonster` function:
// Read the contents of the FlatBuffer binary file. // Read the contents of the FlatBuffer binary file.
$filename = "monster.dat"; $filename = "monster.dat";
$handle = fopen($filename, "rb"); $handle = fopen($filename, "rb");
$contents = $fread($handle, filesize($filename)); $contents = fread($handle, filesize($filename));
fclose($handle); fclose($handle);
// Pass the contents to `GetRootAsMonster`. // Pass the contents to `GetRootAsMonster`.

View File

@@ -97,6 +97,61 @@ convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
*Note: That we never stored a `mana` value, so it will return the default.* *Note: That we never stored a `mana` value, so it will return the default.*
## Fallible API and Custom Allocators
Every `FlatBufferBuilder` method that may allocate has a `try_*` counterpart
(e.g. `try_create_string`, `try_push`, `try_finish`) that returns
`Result<T, A::Error>` instead of panicking. This is useful when allocation
failures must be handled gracefully: for example in `no_std` environments or
with fixed-capacity buffers.
The existing panicking methods are unchanged and remain the simplest option
when using the default allocator.
#### Custom allocators
Implement the `Allocator` trait and pass it to `FlatBufferBuilder::new_in()`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
use flatbuffers::{Allocator, FlatBufferBuilder};
struct MyAllocator { /* ... */ }
unsafe impl Allocator for MyAllocator {
type Error = MyError;
fn grow_downwards(&mut self) -> Result<(), Self::Error> { /* ... */ }
fn len(&self) -> usize { /* ... */ }
}
let alloc = MyAllocator::new(/* ... */);
let mut builder = FlatBufferBuilder::new_in(alloc);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The built-in `DefaultAllocator` uses `Vec<u8>` and sets `Error = Infallible`,
so the `try_*` methods on a default builder can never fail.
#### Example: building a buffer with error propagation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
fn build<A: flatbuffers::Allocator>(
builder: &mut FlatBufferBuilder<A>,
) -> Result<(), A::Error> {
let name = builder.try_create_string("Orc")?;
let inventory = builder.try_create_vector(&[0u8, 1, 2, 3, 4])?;
let table_start = builder.start_table();
builder.try_push_slot_always(Monster::VT_NAME, name)?;
builder.try_push_slot_always(Monster::VT_INVENTORY, inventory)?;
builder.try_push_slot(Monster::VT_HP, 80i16, 100)?;
let root = builder.try_end_table(table_start)?;
builder.try_finish(root, None)?;
Ok(())
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See the `FlatBufferBuilder` rustdoc for the full list of `try_*` methods.
## Direct memory access ## Direct memory access
As you can see from the above examples, all elements in a buffer are As you can see from the above examples, all elements in a buffer are
@@ -177,6 +232,75 @@ functions require a mutable (aka exclusive) reference which can only be created
when no other references to the `FlatBufferBuilder` exist, and may not be copied when no other references to the `FlatBufferBuilder` exist, and may not be copied
within the same thread, let alone to a second thread. within the same thread, let alone to a second thread.
## Reflection (& Resizing)
There is experimental support for reflection in FlatBuffers, allowing you to
read and write data even if you don't know the exact format of a buffer, and
even allows you to change sizes of strings in-place.
The way this works is very elegant; there is actually a FlatBuffer schema that
describes schemas (\!) which you can find in `reflection/reflection.fbs`.
The compiler, `flatc`, can write out any schemas it has just parsed as a binary
FlatBuffer, corresponding to this meta-schema.
Loading in one of these binary schemas at runtime allows you to traverse any
FlatBuffer data that corresponds to it without knowing the exact format. You
can query what fields are present, and then read/write them after.
For convenient field manipulation, you can use the crate
`flatbuffers-reflection` which includes both the generated code from the meta
schema, as well as a lot of helper functions.
And example of usage, for the time being, can be found in
`tests/rust_reflection_test/src/lib.rs`. Two sets of APIs are provided:
- [Unsafe getters/setters](https://docs.rs/flatbuffers-reflection/latest/flatbuffers_reflection/#functions),
which you can use when you are processing trusted data (either from a source you know, or has been verified)
- Safe getters in [SafeBuffer](https://docs.rs/flatbuffers-reflection/latest/flatbuffers_reflection/struct.SafeBuffer.html),
which does verification when constructed so you can use it for any data source
## Buffer pre allocation in a latency-sensitive context
In latency-sensitive applications, dynamic memory allocations can introduce unpredictable latency spikes. The `FlatBufferBuilder` internally uses several `Vec`s that may reallocate during serialization:
- The backing buffer for the FlatBuffer data
- `field_locs` for tracking field locations within tables
- `written_vtable_revpos` for deduplicating vtables
- `strings_pool` for shared string interning
To avoid allocations during serialization, you can preallocate all internal vectors upfront using the `with_internal_capacity` constructor:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
// Preallocate: 1KB buffer, 8 field locations, 16 vtables, 32 shared strings
let mut builder = FlatBufferBuilder::with_internal_capacity(1024, 8, 16, 32);
// All subsequent operations will not allocate (if capacities are sufficient)
let name = builder.create_shared_string("MyMonster");
// ... build your FlatBuffer ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are three variants available:
- `with_internal_capacity(size, field_locs, vtables, strings)` - Creates a new builder with all capacities preallocated
- `from_vec_with_internal_capacity(buffer, field_locs, vtables, strings)` - Reuses an existing `Vec<u8>` as the backing buffer
- `new_in_with_internal_capacity(allocator, field_locs, vtables, strings)` - Uses a custom `Allocator` with preallocated internal vecs
When combined with `reset()`, you can reuse the same builder across multiple serializations without any allocations after the initial setup:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
let mut builder = FlatBufferBuilder::with_internal_capacity(1024, 8, 16, 32);
loop {
// Build a FlatBuffer (allocation-free if capacities are sufficient)
let data = build_message(&mut builder);
send(data);
// Reset for reuse - clears state but retains allocated capacity
builder.reset();
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Useful tools created by others ## Useful tools created by others
* [flatc-rust](https://github.com/frol/flatc-rust) - FlatBuffers compiler * [flatc-rust](https://github.com/frol/flatc-rust) - FlatBuffers compiler

View File

@@ -57,7 +57,7 @@ a data object from the server, which you can pass into the `GetRootAsMonster` fu
let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon") let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon")
guard let data = try? Data(contentsOf: url) else { return } guard let data = try? Data(contentsOf: url) else { return }
let monster = Monster.getRootAsMonster(bb: ByteBuffer(data: data)) let monster: Monster = try! getCheckedRoot(byteBuffer: &byteBuffer)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now you can access values like this: Now you can access values like this:
@@ -81,7 +81,7 @@ In some cases it's necessary to modify values in an existing FlatBuffer in place
fatalError("couldn't mutate") fatalError("couldn't mutate")
} }
// mutate a struct field using flatbuffers struct // mutate a struct field using flatbuffers struct
// DONT use monster.pos to mutate since swift copy on write // DONT use monster.pos to mutate since swift copy on write
// will not mutate the value in the buffer // will not mutate the value in the buffer
let vec = monster.mutablePos.mutate(z: 4) let vec = monster.mutablePos.mutate(z: 4)

View File

@@ -30,7 +30,7 @@ See the [Tutorial](tutorial.md) for a more in depth guide.
code: code:
```sh ```sh
./flatc --cpp --rust mosnter.fbs ./flatc --cpp --rust monster.fbs
``` ```
Which generates `monster_generated.h` and `monster_generated.rs` files. Which generates `monster_generated.h` and `monster_generated.rs` files.
@@ -44,11 +44,11 @@ See the [Tutorial](tutorial.md) for a more in depth guide.
#include "flatbuffers.h" #include "flatbuffers.h"
#include "monster_generated.h" #include "monster_generated.h"
int main() { int main() {
// Used to build the flatbuffer // Used to build the flatbuffer
FlatBufferBuilder builder; FlatBufferBuilder builder;
// Auto-generated function emitted from `flatc` and the input // Auto-generated function emitted from `flatc` and the input
// `monster.fbs` schema. // `monster.fbs` schema.
auto monster = CreateMonsterDirect(builder, "Abominable Snowman", 100); auto monster = CreateMonsterDirect(builder, "Abominable Snowman", 100);
@@ -60,8 +60,8 @@ See the [Tutorial](tutorial.md) for a more in depth guide.
See complete [C++ Example](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.cpp#L24-L56). See complete [C++ Example](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.cpp#L24-L56).
5. **Transmit/Store the serialized FlatBuffer** 5. **Transmit/Store the serialized FlatBuffer**
Use your serialized buffer however you want. Send it to someone, save if for Use your serialized buffer however you want. Send it to someone, save it for
later, etc... later, etc...
```c++ title="my_monster_factory.cc" linenums="13" ```c++ title="my_monster_factory.cc" linenums="13"
@@ -73,10 +73,10 @@ See the [Tutorial](tutorial.md) for a more in depth guide.
Use the generated accessors to read the data from the serialized buffer. Use the generated accessors to read the data from the serialized buffer.
It doesn't need to be the same language, or even schema version (see It doesn't need to be the same language, or even schema version (see
[Evolving](evolution.md)), FlatBuffers ensures the data is readable across [Evolving](evolution.md)), FlatBuffers ensures the data is readable across
languages and schema versions. languages and schema versions.
```c++ title="my_monster_factory.cc" linenums="15" ```c++ title="my_monster_factory.cc" linenums="15"
// Get a view of the root monster from the flatbuffer. // Get a view of the root monster from the flatbuffer.
const Monster snowman = GetMonster(flatbuffer); const Monster snowman = GetMonster(flatbuffer);
@@ -84,7 +84,7 @@ See the [Tutorial](tutorial.md) for a more in depth guide.
// Access the monster's fields directly. // Access the monster's fields directly.
ASSERT_EQ(snowman->name(), "Abominable Snowman"); ASSERT_EQ(snowman->name(), "Abominable Snowman");
ASSERT_EQ(snowman->health(), 100); ASSERT_EQ(snowman->health(), 100);
``` ```
See [`Rust` examples](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs#L92-L106) See [`Rust` examples](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs#L92-L106)
for reading the data written by `C++`. for reading the data written by `C++`.

View File

@@ -427,9 +427,6 @@ Current understood attributes:
it won't be accessible anymore by newer code. Note that if you deprecate a it won't be accessible anymore by newer code. Note that if you deprecate a
field that was previous required, old code may fail to validate new data (when field that was previous required, old code may fail to validate new data (when
using the optional verifier). using the optional verifier).
### `required`
- `required` (on a non-scalar table field): this field must always be set. By - `required` (on a non-scalar table field): this field must always be set. By
default, fields do not need to be present in the binary. This is desirable, as default, fields do not need to be present in the binary. This is desirable, as
it helps with forwards/backwards compatibility, and flexibility of data it helps with forwards/backwards compatibility, and flexibility of data

View File

@@ -24,14 +24,14 @@ Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Ye
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No | No JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No | No
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No | Yes Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No | Yes
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | No Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | Yes
Native Object API | Yes | No | Yes | Yes | Yes | Yes | Yes | No | No | Yes | No | No | No Native Object API | Yes | No | Yes | Yes | Yes | Yes | Yes | No | No | Yes | No | No | Yes
Optional Scalars | Yes | Yes | Yes | No | No | Yes | Yes | Yes | No | No | Yes | Yes | Yes Optional Scalars | Yes | Yes | Yes | Yes | No | Yes | Yes | Yes | No | No | Yes | Yes | Yes
Flexbuffers | Yes | Yes | ? | ? | ? | ? | ? | ? | ? | ? | ? | Yes | ? Flexbuffers | Yes | Yes | ? | ? | ? | ? | ? | ? | ? | ? | ? | Yes | Yes
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes | No Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes | No
Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb | Great Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb | Great
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes | No Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes | Yes
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ? | No Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ? | No

View File

@@ -165,11 +165,11 @@ serializing and deserializing the flatbuffer binary data.
=== "C" === "C"
!!! Note !!! Note
If you're working in C, you need to use the separate project If you're working in C, you need to use the separate project
[FlatCC](https://github.com/dvidelabs/flatcc) which contains a schema [FlatCC](https://github.com/dvidelabs/flatcc) which contains a schema
compiler and runtime library in C for C. See compiler and runtime library in C for C. See
[flatcc build instructions](https://github.com/dvidelabs/flatcc#building). [flatcc build instructions](https://github.com/dvidelabs/flatcc#building).
Please be aware of the difference between `flatc` and `flatcc` tools. Please be aware of the difference between `flatc` and `flatcc` tools.
@@ -291,7 +291,7 @@ generally involves two things:
// Convenient namespace macro to manage long namespace prefix. // Convenient namespace macro to manage long namespace prefix.
#undef ns #undef ns
// Specified in the schema. // Specified in the schema.
#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x) #define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Sample, x)
// A helper to simplify creating vectors from C-arrays. // A helper to simplify creating vectors from C-arrays.
#define c_vec_len(V) (sizeof(V)/sizeof((V)[0])) #define c_vec_len(V) (sizeof(V)/sizeof((V)[0]))
@@ -333,14 +333,14 @@ generally involves two things:
=== "JavaScript" === "JavaScript"
```javascript ```javascript
// The following code is an example - use your desired module flavor by // The following code is an example - use your desired module flavor by
// transpiling from TS. // transpiling from TS.
var flatbuffers = require('/js/flatbuffers').flatbuffers; var flatbuffers = require('/js/flatbuffers').flatbuffers;
var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`. var MyGame = require('./monster_generated').MyGame; // Generated by `flatc`.
//------------------------------------------------------------------------// //------------------------------------------------------------------------//
// The following code is for browser-based HTML/JavaScript. Use the above // The following code is for browser-based HTML/JavaScript. Use the above
// code for JavaScript module loaders (e.g. Node.js). // code for JavaScript module loaders (e.g. Node.js).
<script src="../js/flatbuffers.js"></script> <script src="../js/flatbuffers.js"></script>
<script src="monster_generated.js"></script> // Generated by `flatc`. <script src="monster_generated.js"></script> // Generated by `flatc`.
@@ -384,12 +384,12 @@ generally involves two things:
// The last segment of the class name matches the file name. // The last segment of the class name matches the file name.
$class = substr($class_name, strrpos($class_name, "\\") + 1); $class = substr($class_name, strrpos($class_name, "\\") + 1);
// `flatbuffers` root. // `flatbuffers` root.
$root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__)))); $root_dir = join(DIRECTORY_SEPARATOR, array(dirname(dirname(__FILE__))));
// Contains the `*.php` files for the FlatBuffers library and the `flatc` // Contains the `*.php` files for the FlatBuffers library and the `flatc`
// generated files. // generated files.
$paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")), $paths = array(join(DIRECTORY_SEPARATOR, array($root_dir, "php")),
join(DIRECTORY_SEPARATOR, join(DIRECTORY_SEPARATOR,
array($root_dir, "samples", "MyGame", "Sample"))); array($root_dir, "samples", "MyGame", "Sample")));
foreach ($paths as $path) { foreach ($paths as $path) {
$file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php")); $file = join(DIRECTORY_SEPARATOR, array($path, $class . ".php"));
@@ -546,7 +546,7 @@ for it. The builder will automatically resize the backing buffer when necessary.
=== "Lobster" === "Lobster"
```lobster ```lobster
// Construct a Builder with 1024 byte backing array. // Construct a Builder with 1024 byte backing array.
let builder = flatbuffers_builder {} let builder = flatbuffers_builder {}
``` ```
@@ -630,9 +630,9 @@ Let's serialize two weapon strings.
=== "C" === "C"
```c ```c
flatbuffers_string_ref_t weapon_one_name flatbuffers_string_ref_t weapon_one_name
= flatbuffers_string_create_str(B, "Sword"); = flatbuffers_string_create_str(B, "Sword");
flatbuffers_string_ref_t weapon_two_name flatbuffers_string_ref_t weapon_two_name
= flatbuffers_string_create_str(B, "Axe"); = flatbuffers_string_create_str(B, "Axe");
``` ```
@@ -722,7 +722,7 @@ Let's serialize two weapon strings.
=== "TypeScript" === "TypeScript"
```ts ```ts
let weaponOne = builder.createString('Sword'); let weaponOne = builder.createString('Sword');
let weaponTwo = builder.createString('Axe'); let weaponTwo = builder.createString('Axe');
``` ```
@@ -760,9 +760,9 @@ offset to the weapon's name and a numerical value for the damage field.
uint16_t weapon_one_damage = 3; uint16_t weapon_one_damage = 3;
uint16_t weapon_two_damage = 5; uint16_t weapon_two_damage = 5;
ns(Weapon_ref_t) sword ns(Weapon_ref_t) sword
= ns(Weapon_create(B, weapon_one_name, weapon_one_damage)); = ns(Weapon_create(B, weapon_one_name, weapon_one_damage));
ns(Weapon_ref_t) axe ns(Weapon_ref_t) axe
= ns(Weapon_create(B, weapon_two_name, weapon_two_damage)); = ns(Weapon_create(B, weapon_two_name, weapon_two_damage));
``` ```
@@ -772,7 +772,7 @@ offset to the weapon's name and a numerical value for the damage field.
short weaponOneDamage = 3; short weaponOneDamage = 3;
short weaponTwoDamage = 5; short weaponTwoDamage = 5;
// Use the `CreateWeapon()` helper function to create the weapons, since we // Use the `CreateWeapon()` helper function to create the weapons, since we
// set every field. // set every field.
Offset<Weapon> sword = Offset<Weapon> sword =
Weapon.CreateWeapon(builder, weaponOneName, weaponOneDamage); Weapon.CreateWeapon(builder, weaponOneName, weaponOneDamage);
@@ -1073,7 +1073,7 @@ The Builder provides multiple ways to create `vectors`.
=== "Java" === "Java"
```java ```java
// Place the two weapons into an array, and pass it to the // Place the two weapons into an array, and pass it to the
// `createWeaponsVector()` method to create a FlatBuffer vector. // `createWeaponsVector()` method to create a FlatBuffer vector.
int[] weaps = new int[2]; int[] weaps = new int[2];
weaps[0] = sword; weaps[0] = sword;
@@ -1096,7 +1096,7 @@ The Builder provides multiple ways to create `vectors`.
=== "Kotlin" === "Kotlin"
```kotlin ```kotlin
// Place the two weapons into an array, and pass it to the // Place the two weapons into an array, and pass it to the
// `createWeaponsVector()` method to create a FlatBuffer vector. // `createWeaponsVector()` method to create a FlatBuffer vector.
val weaps = intArrayOf(sword, axe) val weaps = intArrayOf(sword, axe)
@@ -1134,12 +1134,8 @@ The Builder provides multiple ways to create `vectors`.
=== "Python" === "Python"
```py ```py
# Create a FlatBuffer vector and prepend the weapons. # Use the generated helper to create the weapons vector from offsets.
# Note: Since we prepend the data, prepend them in reverse order. weapons = MyGame.Sample.Monster.CreateWeaponsVector(builder, [sword, axe])
MyGame.Sample.Monster.StartWeaponsVector(builder, 2)
builder.PrependUOffsetTRelative(axe)
builder.PrependUOffsetTRelative(sword)
weapons = builder.EndVector()
``` ```
=== "Rust" === "Rust"
@@ -1352,16 +1348,13 @@ bit more directly.
```py ```py
# Create a `vector` representing the inventory of the Orc. Each number # Create a `vector` representing the inventory of the Orc. Each number
# could correspond to an item that can be claimed after he is slain. # could correspond to an item that can be claimed after he is slain.
# Note: Since we prepend the bytes, this loop iterates in reverse. inv = MyGame.Sample.Monster.CreateInventoryVector(builder, range(0, 10))
MyGame.Sample.Monster.StartInventoryVector(builder, 10)
for i in reversed(range(0, 10)):
builder.PrependByte(i)
inv = builder.EndVector()
MyGame.Sample.Monster.StartPathVector(builder, 2) path_points = [
MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0) MyGame.Sample.Vec3T(x=1.0, y=2.0, z=3.0),
MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0) MyGame.Sample.Vec3T(x=4.0, y=5.0, z=6.0),
path = builder.EndVector() ]
path = MyGame.Sample.Monster.CreatePathVector(builder, path_points)
``` ```
=== "Rust" === "Rust"
@@ -1537,7 +1530,7 @@ the necessary values and Offsets to make a `Monster`.
```java ```java
// Serialize a name for our monster, called "Orc". // Serialize a name for our monster, called "Orc".
int name = builder.createString("Orc"); int name = builder.createString("Orc");
// Create our monster using `startMonster()` and `endMonster()`. // Create our monster using `startMonster()` and `endMonster()`.
Monster.startMonster(builder); Monster.startMonster(builder);
Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)); Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f));
@@ -1567,7 +1560,7 @@ the necessary values and Offsets to make a `Monster`.
MyGame.Sample.Monster.addName(builder, name); MyGame.Sample.Monster.addName(builder, name);
MyGame.Sample.Monster.addInventory(builder, inv); MyGame.Sample.Monster.addInventory(builder, inv);
MyGame.Sample.Monster.addWeapons(builder, weapons); MyGame.Sample.Monster.addWeapons(builder, weapons);
MyGame.Sample.Monster.addEquippedType(builder, MyGame.Sample.Monster.addEquippedType(builder,
MyGame.Sample.Equipment.Weapon); MyGame.Sample.Equipment.Weapon);
MyGame.Sample.Monster.addEquipped(builder, axe); MyGame.Sample.Monster.addEquipped(builder, axe);
MyGame.Sample.Monster.addPath(builder, path); MyGame.Sample.Monster.addPath(builder, path);
@@ -1649,7 +1642,7 @@ the necessary values and Offsets to make a `Monster`.
\MyGame\Sample\Monster::AddInventory($builder, $inv); \MyGame\Sample\Monster::AddInventory($builder, $inv);
\MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red); \MyGame\Sample\Monster::AddColor($builder, \MyGame\Sample\Color::Red);
\MyGame\Sample\Monster::AddWeapons($builder, $weapons); \MyGame\Sample\Monster::AddWeapons($builder, $weapons);
\MyGame\Sample\Monster::AddEquippedType($builder, \MyGame\Sample\Monster::AddEquippedType($builder,
\MyGame\Sample\Equipment::Weapon); \MyGame\Sample\Equipment::Weapon);
\MyGame\Sample\Monster::AddEquipped($builder, $axe); \MyGame\Sample\Monster::AddEquipped($builder, $axe);
\MyGame\Sample\Monster::AddPath($builder, $path); \MyGame\Sample\Monster::AddPath($builder, $path);
@@ -1782,7 +1775,7 @@ deserializing the buffer later.
```dart ```dart
// Call `finish()` to instruct the builder that this monster is complete. // Call `finish()` to instruct the builder that this monster is complete.
// See the next code section, as in Dart `finish` will also return the byte // See the next code section, as in Dart `finish` will also return the byte
// array. // array.
``` ```
@@ -1982,7 +1975,7 @@ like so:
```php ```php
// This must be called after `finish()`. // This must be called after `finish()`.
$buf = $builder->dataBuffer(); // Of type `Google\FlatBuffers\ByteBuffer` $buf = $builder->dataBuffer(); // Of type `Google\FlatBuffers\ByteBuffer`
// The data in this ByteBuffer does NOT start at 0, but at // The data in this ByteBuffer does NOT start at 0, but at
// buf->getPosition(). // buf->getPosition().
// The end of the data is marked by buf->capacity(), so the size is // The end of the data is marked by buf->capacity(), so the size is
// buf->capacity() - buf->getPosition(). // buf->capacity() - buf->getPosition().
@@ -2011,6 +2004,8 @@ like so:
let buf = builder.sizedByteArray let buf = builder.sizedByteArray
// or you can use to get an object of type Data // or you can use to get an object of type Data
let bufData = ByteBuffer(data: builder.data) let bufData = ByteBuffer(data: builder.data)
// or
let buf = builder.sizedBuffer
``` ```
=== "TypeScript" === "TypeScript"
@@ -2054,7 +2049,7 @@ functions to get the root object given the buffer.
```c++ ```c++
uint8_t *buffer_pointer = /* the data you just read */; uint8_t *buffer_pointer = /* the data you just read */;
// Get an view to the root object inside the buffer. // Get a view to the root object inside the buffer.
Monster monster = GetMonster(buffer_pointer); Monster monster = GetMonster(buffer_pointer);
``` ```
@@ -2074,7 +2069,7 @@ functions to get the root object given the buffer.
```c# ```c#
byte[] bytes = /* the data you just read */ byte[] bytes = /* the data you just read */
// Get an view to the root object inside the buffer. // Get a view to the root object inside the buffer.
Monster monster = Monster.GetRootAsMonster(new ByteBuffer(bytes)); Monster monster = Monster.GetRootAsMonster(new ByteBuffer(bytes));
``` ```
@@ -2202,7 +2197,7 @@ functions to get the root object given the buffer.
```ts ```ts
// the data you just read, as a `Uint8Array`. // the data you just read, as a `Uint8Array`.
// Note that the example here uses `readFileSync` from the built-in `fs` // Note that the example here uses `readFileSync` from the built-in `fs`
// module, but other methods for accessing the file contents will also work. // module, but other methods for accessing the file contents will also work.
let bytes = new Uint8Array(readFileSync('./monsterdata.bin')); let bytes = new Uint8Array(readFileSync('./monsterdata.bin'));
@@ -2654,9 +2649,9 @@ you need to handle the result as a FlatBuffer table. Here we iterate over the
ns(Weapon_vec_t) weapons = ns(Monster_weapons(monster)); ns(Weapon_vec_t) weapons = ns(Monster_weapons(monster));
size_t weapons_len = ns(Weapon_vec_len(weapons)); size_t weapons_len = ns(Weapon_vec_len(weapons));
// We can use `const char *` instead of `flatbuffers_string_t`. // We can use `const char *` instead of `flatbuffers_string_t`.
const char *second_weapon_name = const char *second_weapon_name =
ns(Weapon_name(ns(Weapon_vec_at(weapons, 1)))); ns(Weapon_name(ns(Weapon_vec_at(weapons, 1))));
uint16_t second_weapon_damage = uint16_t second_weapon_damage =
ns(Weapon_damage(ns(Weapon_vec_at(weapons, 1)))); ns(Weapon_damage(ns(Weapon_vec_at(weapons, 1))));
``` ```
@@ -2789,11 +2784,11 @@ only stores a FlatBuffer `table`).
```c++ ```c++
auto union_type = monster.equipped_type(); auto union_type = monster.equipped_type();
if (union_type == Equipment_Weapon) { if (union_type == Equipment_Weapon) {
// Requires `static_cast` to type `const Weapon*`. // Requires `static_cast` to type `const Weapon*`.
auto weapon = static_cast<const Weapon*>(monster->equipped()); auto weapon = static_cast<const Weapon*>(monster->equipped());
auto weapon_name = weapon->name()->str(); // "Axe" auto weapon_name = weapon->name()->str(); // "Axe"
auto weapon_damage = weapon->damage(); // 5 auto weapon_damage = weapon->damage(); // 5
} }
@@ -2805,7 +2800,7 @@ only stores a FlatBuffer `table`).
// Access union type field. // Access union type field.
if (ns(Monster_equipped_type(monster)) == ns(Equipment_Weapon)) { if (ns(Monster_equipped_type(monster)) == ns(Equipment_Weapon)) {
// Cast to appropriate type: // Cast to appropriate type:
// C allows for silent void pointer assignment, so we need no // C allows for silent void pointer assignment, so we need no
// explicit cast. // explicit cast.
ns(Weapon_table_t) weapon = ns(Monster_equipped(monster)); ns(Weapon_table_t) weapon = ns(Monster_equipped(monster));
const char *weapon_name = ns(Weapon_name(weapon)); // "Axe" const char *weapon_name = ns(Weapon_name(weapon)); // "Axe"
@@ -2817,10 +2812,10 @@ only stores a FlatBuffer `table`).
```c# ```c#
var unionType = monster.EquippedType; var unionType = monster.EquippedType;
if (unionType == Equipment.Weapon) { if (unionType == Equipment.Weapon) {
var weapon = monster.Equipped<Weapon>().Value; var weapon = monster.Equipped<Weapon>().Value;
var weaponName = weapon.Name; // "Axe" var weaponName = weapon.Name; // "Axe"
var weaponDamage = weapon.Damage; // 5 var weaponDamage = weapon.Damage; // 5
} }
@@ -2850,7 +2845,7 @@ only stores a FlatBuffer `table`).
unionType := monster.EquippedType() unionType := monster.EquippedType()
if unionType == sample.EquipmentWeapon { if unionType == sample.EquipmentWeapon {
// Create a `sample.Weapon` object that can be initialized with the // Create a `sample.Weapon` object that can be initialized with the
// contents of the `flatbuffers.Table` (`unionTable`), which was // contents of the `flatbuffers.Table` (`unionTable`), which was
// populated by `monster.Equipped()`. // populated by `monster.Equipped()`.
unionWeapon = new(sample.Weapon) unionWeapon = new(sample.Weapon)
@@ -2885,7 +2880,7 @@ only stores a FlatBuffer `table`).
// 'Axe' // 'Axe'
var weaponName = monster.equipped(new MyGame.Sample.Weapon()).name(); var weaponName = monster.equipped(new MyGame.Sample.Weapon()).name();
// 5 // 5
var weaponDamage = var weaponDamage =
monster.equipped(new MyGame.Sample.Weapon()).damage(); monster.equipped(new MyGame.Sample.Weapon()).damage();
} }
``` ```
@@ -2910,8 +2905,8 @@ only stores a FlatBuffer `table`).
union_type = monster.equipped_type union_type = monster.equipped_type
if union_type == MyGame_Sample_Equipment_Weapon: if union_type == MyGame_Sample_Equipment_Weapon:
// `monster.equipped_as_Weapon` returns a FlatBuffer handle much like // `monster.equipped_as_Weapon` returns a FlatBuffer handle much like
// normal table fields, but this is only valid to call if we already // normal table fields, but this is only valid to call if we already
// know it is the correct type. // know it is the correct type.
let union_weapon = monster.equipped_as_Weapon let union_weapon = monster.equipped_as_Weapon
@@ -2943,8 +2938,8 @@ only stores a FlatBuffer `table`).
$weapon_name = $weapon_name =
$monster->getEquipped(new \MyGame\Sample\Weapon())->getName(); $monster->getEquipped(new \MyGame\Sample\Weapon())->getName();
// 5 // 5
$weapon_damage = $weapon_damage =
$monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage(); $monster->getEquipped(new \MyGame\Sample\Weapon())->getDamage();
} }
``` ```
@@ -2994,8 +2989,8 @@ only stores a FlatBuffer `table`).
if (unionType == MyGame.Sample.Equipment.Weapon) { if (unionType == MyGame.Sample.Equipment.Weapon) {
// 'Axe' // 'Axe'
let weaponName = monster.equipped(new MyGame.Sample.Weapon()).name(); let weaponName = monster.equipped(new MyGame.Sample.Weapon()).name();
// 5 // 5
let weaponDamage = monster.equipped(new MyGame.Sample.Weapon()).damage(); let weaponDamage = monster.equipped(new MyGame.Sample.Weapon()).damage();
} }
``` ```

10
eslint.config.mjs Normal file
View File

@@ -0,0 +1,10 @@
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
export default [
{files: ["**/*.{js,mjs,cjs,ts}"]},
{languageOptions: { globals: {...globals.browser, ...globals.node} }},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
];

View File

@@ -28,12 +28,12 @@ func ReadResponse(r *http.Response) {
res := net.GetRootAsResponse(body, 0) res := net.GetRootAsResponse(body, 0)
player := res.Player(nil) player := res.Player(nil)
fmt.Printf("Got response (name: %v, hp: %v)\n", string(player.Name()), player.Hp()) fmt.Printf("Got response (name: %v, hp: %v)\n", string(player.Name()), player.Hp())
} }
func main() { func main() {
body := RequestBody() body := RequestBody()
req, err := http.NewRequest("POST", "http://localhost:8080/echo", body) req, err := http.NewRequest("POST", "http://localhost:8080/echo", body)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)

View File

@@ -8,7 +8,7 @@ import (
type WarriorT struct { type WarriorT struct {
Name string `json:"name"` Name string `json:"name"`
Hp uint32 `json:"hp"` Hp uint32 `json:"hp"`
} }
func (t *WarriorT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT { func (t *WarriorT) Pack(builder *flatbuffers.Builder) flatbuffers.UOffsetT {

View File

@@ -104,15 +104,18 @@ func (b *Builder) StartObject(numfields int) {
// logically-equal vtables will be deduplicated. // logically-equal vtables will be deduplicated.
// //
// A vtable has the following format: // A vtable has the following format:
// <VOffsetT: size of the vtable in bytes, including this value> //
// <VOffsetT: size of the object in bytes, including the vtable offset> // <VOffsetT: size of the vtable in bytes, including this value>
// <VOffsetT: offset for a field> * N, where N is the number of fields in // <VOffsetT: size of the object in bytes, including the vtable offset>
// the schema for this type. Includes deprecated fields. // <VOffsetT: offset for a field> * N, where N is the number of fields in
// the schema for this type. Includes deprecated fields.
//
// Thus, a vtable is made of 2 + N elements, each SizeVOffsetT bytes wide. // Thus, a vtable is made of 2 + N elements, each SizeVOffsetT bytes wide.
// //
// An object has the following format: // An object has the following format:
// <SOffsetT: offset to this object's vtable (may be negative)> //
// <byte: data>+ // <SOffsetT: offset to this object's vtable (may be negative)>
// <byte: data>+
func (b *Builder) WriteVtable() (n UOffsetT) { func (b *Builder) WriteVtable() (n UOffsetT) {
// Prepend a zero scalar to the object. Later in this function we'll // Prepend a zero scalar to the object. Later in this function we'll
// write an offset here that points to the object's vtable: // write an offset here that points to the object's vtable:
@@ -296,8 +299,9 @@ func (b *Builder) PrependUOffsetT(off UOffsetT) {
// StartVector initializes bookkeeping for writing a new vector. // StartVector initializes bookkeeping for writing a new vector.
// //
// A vector has the following format: // A vector has the following format:
// <UOffsetT: number of elements in this vector> //
// <T: data>+, where T is the type of elements of this vector. // <UOffsetT: number of elements in this vector>
// <T: data>+, where T is the type of elements of this vector.
func (b *Builder) StartVector(elemSize, numElems, alignment int) UOffsetT { func (b *Builder) StartVector(elemSize, numElems, alignment int) UOffsetT {
b.assertNotNested() b.assertNotNested()
b.nested = true b.nested = true

View File

@@ -25,7 +25,7 @@ func GetByte(buf []byte) byte {
// GetBool decodes a little-endian bool from a byte slice. // GetBool decodes a little-endian bool from a byte slice.
func GetBool(buf []byte) bool { func GetBool(buf []byte) bool {
return buf[0] == 1 return buf[0] != 0
} }
// GetUint8 decodes a little-endian uint8 from a byte slice. // GetUint8 decodes a little-endian uint8 from a byte slice.

View File

@@ -1,7 +1,17 @@
package flatbuffers package flatbuffers
// Codec implements gRPC-go Codec which is used to encode and decode messages. import "errors"
var Codec = "flatbuffers"
var (
// Codec implements gRPC-go Codec which is used to encode and decode messages.
Codec = "flatbuffers"
// ErrInsufficientData is returned when the data is too short to read the root UOffsetT.
ErrInsufficientData = errors.New("insufficient data")
// ErrInvalidRootOffset is returned when the root UOffsetT is out of bounds.
ErrInvalidRootOffset = errors.New("invalid root offset")
)
// FlatbuffersCodec defines the interface gRPC uses to encode and decode messages. Note // FlatbuffersCodec defines the interface gRPC uses to encode and decode messages. Note
// that implementations of this interface must be thread safe; a Codec's // that implementations of this interface must be thread safe; a Codec's
@@ -15,7 +25,21 @@ func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
// Unmarshal parses the wire format into v. // Unmarshal parses the wire format into v.
func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error { func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
v.(flatbuffersInit).Init(data, GetUOffsetT(data)) // Need at least 4 bytes to read the root table offset (UOffsetT).
// Vtable soffset_t and metadata are read later during field access.
if len(data) < SizeUOffsetT {
return ErrInsufficientData
}
off := GetUOffsetT(data)
// The root UOffsetT must be within the data buffer
// Compare in the unsigned domain to avoid signedness pitfalls
if off > UOffsetT(len(data)-SizeUOffsetT) {
return ErrInvalidRootOffset
}
v.(flatbuffersInit).Init(data, off)
return nil return nil
} }

View File

@@ -31,10 +31,25 @@ func (t *Table) String(off UOffsetT) string {
} }
// ByteVector gets a byte slice from data stored inside the flatbuffer. // ByteVector gets a byte slice from data stored inside the flatbuffer.
// If the offset is invalid or out of bounds, returns nil to prevent crashes.
func (t *Table) ByteVector(off UOffsetT) []byte { func (t *Table) ByteVector(off UOffsetT) []byte {
n := UOffsetT(len(t.Bytes))
// Need at least SizeUOffsetT bytes to read the relative vector offset.
u := UOffsetT(SizeUOffsetT)
if n < u || off > n-u {
return nil
}
off += GetUOffsetT(t.Bytes[off:]) off += GetUOffsetT(t.Bytes[off:])
// Need at least SizeUOffsetT bytes to read the vector length.
if n < u || off > n-u {
return nil
}
start := off + UOffsetT(SizeUOffsetT) start := off + UOffsetT(SizeUOffsetT)
length := GetUOffsetT(t.Bytes[off:]) length := GetUOffsetT(t.Bytes[off:])
// Avoid overflow by checking the length against the remaining buffer space.
if length > n-start {
return nil
}
return t.Bytes[start : start+length] return t.Bytes[start : start+length]
} }

View File

@@ -3,8 +3,8 @@
This directory is a repository for the generated files of `flatc`. This directory is a repository for the generated files of `flatc`.
We check in the generated code so we can see, during a PR review, how the We check in the generated code so we can see, during a PR review, how the
changes affect the generated output. Its also useful as a reference to point too changes affect the generated output. It's also useful as a reference to show
as how things work across various languages. how things work across various languages.
These files are **NOT** intended to be depended on by any code, such as tests or These files are **NOT** intended to be depended on by any code, such as tests or
or compiled examples. or compiled examples.
@@ -18,7 +18,7 @@ view of things across languages. These are kept in the `schema/` directory.
Some languages may not support every generation feature, so each language is Some languages may not support every generation feature, so each language is
required to specify the `flatc` arguments individually. required to specify the `flatc` arguments individually.
* Try to avoid includes and nested directories, preferring it as flat as * Try to avoid includes and nested directories, preferring it as flat as
possible. possible.
## Updating ## Updating

View File

@@ -9,8 +9,8 @@
// Ensure the included flatbuffers.h is the same version as when this file was // Ensure the included flatbuffers.h is the same version as when this file was
// generated, otherwise it may not be compatible. // generated, otherwise it may not be compatible.
static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && static_assert(FLATBUFFERS_VERSION_MAJOR == 25 &&
FLATBUFFERS_VERSION_MINOR == 2 && FLATBUFFERS_VERSION_MINOR == 12 &&
FLATBUFFERS_VERSION_REVISION == 10, FLATBUFFERS_VERSION_REVISION == 19,
"Non-compatible flatbuffers version included"); "Non-compatible flatbuffers version included");
namespace flatbuffers { namespace flatbuffers {
@@ -30,7 +30,8 @@ struct Galaxy FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
int64_t num_stars() const { int64_t num_stars() const {
return GetField<int64_t>(VT_NUM_STARS, 0); return GetField<int64_t>(VT_NUM_STARS, 0);
} }
bool Verify(::flatbuffers::Verifier &verifier) const { template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
VerifyField<int64_t>(verifier, VT_NUM_STARS, 8) && VerifyField<int64_t>(verifier, VT_NUM_STARS, 8) &&
verifier.EndTable(); verifier.EndTable();
@@ -75,7 +76,8 @@ struct Universe FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
const ::flatbuffers::Vector<::flatbuffers::Offset<flatbuffers::goldens::Galaxy>> *galaxies() const { const ::flatbuffers::Vector<::flatbuffers::Offset<flatbuffers::goldens::Galaxy>> *galaxies() const {
return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<flatbuffers::goldens::Galaxy>> *>(VT_GALAXIES); return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<flatbuffers::goldens::Galaxy>> *>(VT_GALAXIES);
} }
bool Verify(::flatbuffers::Verifier &verifier) const { template <bool B = false>
bool Verify(::flatbuffers::VerifierTemplate<B> &verifier) const {
return VerifyTableStart(verifier) && return VerifyTableStart(verifier) &&
VerifyField<double>(verifier, VT_AGE, 8) && VerifyField<double>(verifier, VT_AGE, 8) &&
VerifyOffset(verifier, VT_GALAXIES) && VerifyOffset(verifier, VT_GALAXIES) &&
@@ -135,14 +137,16 @@ inline const flatbuffers::goldens::Universe *GetSizePrefixedUniverse(const void
return ::flatbuffers::GetSizePrefixedRoot<flatbuffers::goldens::Universe>(buf); return ::flatbuffers::GetSizePrefixedRoot<flatbuffers::goldens::Universe>(buf);
} }
template <bool B = false>
inline bool VerifyUniverseBuffer( inline bool VerifyUniverseBuffer(
::flatbuffers::Verifier &verifier) { ::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.VerifyBuffer<flatbuffers::goldens::Universe>(nullptr); return verifier.template VerifyBuffer<flatbuffers::goldens::Universe>(nullptr);
} }
template <bool B = false>
inline bool VerifySizePrefixedUniverseBuffer( inline bool VerifySizePrefixedUniverseBuffer(
::flatbuffers::Verifier &verifier) { ::flatbuffers::VerifierTemplate<B> &verifier) {
return verifier.VerifySizePrefixedBuffer<flatbuffers::goldens::Universe>(nullptr); return verifier.template VerifySizePrefixedBuffer<flatbuffers::goldens::Universe>(nullptr);
} }
inline void FinishUniverseBuffer( inline void FinishUniverseBuffer(

View File

@@ -2,9 +2,9 @@ from golden_utils import flatc_golden
def flatc(options, schema): def flatc(options, schema):
# Wrap the golden flatc generator with C++ specifics # Wrap the golden flatc generator with C++ specifics
flatc_golden(options=["--cpp"] + options, schema=schema, prefix="cpp") flatc_golden(options=["--cpp"] + options, schema=schema, prefix="cpp")
def GenerateCpp(): def GenerateCpp():
flatc([], "basic.fbs") flatc([], "basic.fbs")

View File

@@ -13,7 +13,7 @@ public struct Galaxy : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_25_2_10(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_25_12_19(); }
public static Galaxy GetRootAsGalaxy(ByteBuffer _bb) { return GetRootAsGalaxy(_bb, new Galaxy()); } public static Galaxy GetRootAsGalaxy(ByteBuffer _bb) { return GetRootAsGalaxy(_bb, new Galaxy()); }
public static Galaxy GetRootAsGalaxy(ByteBuffer _bb, Galaxy obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static Galaxy GetRootAsGalaxy(ByteBuffer _bb, Galaxy obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }

View File

@@ -13,7 +13,7 @@ public struct Universe : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_25_2_10(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_25_12_19(); }
public static Universe GetRootAsUniverse(ByteBuffer _bb) { return GetRootAsUniverse(_bb, new Universe()); } public static Universe GetRootAsUniverse(ByteBuffer _bb) { return GetRootAsUniverse(_bb, new Universe()); }
public static Universe GetRootAsUniverse(ByteBuffer _bb, Universe obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static Universe GetRootAsUniverse(ByteBuffer _bb, Universe obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public static bool VerifyUniverse(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, UniverseVerify.Verify); } public static bool VerifyUniverse(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, UniverseVerify.Verify); }

View File

@@ -2,9 +2,9 @@ from golden_utils import flatc_golden
def flatc(options, schema): def flatc(options, schema):
# Wrap the golden flatc generator with C# specifics # Wrap the golden flatc generator with C# specifics
flatc_golden(options=["--csharp"] + options, schema=schema, prefix="csharp") flatc_golden(options=["--csharp"] + options, schema=schema, prefix="csharp")
def GenerateCSharp(): def GenerateCSharp():
flatc([], "basic.fbs") flatc([], "basic.fbs")

View File

@@ -7,6 +7,7 @@ import 'dart:typed_data' show Uint8List;
import 'package:flat_buffers/flat_buffers.dart' as fb; import 'package:flat_buffers/flat_buffers.dart' as fb;
class Galaxy { class Galaxy {
Galaxy._(this._bc, this._bcOffset); Galaxy._(this._bc, this._bcOffset);
factory Galaxy(List<int> bytes) { factory Galaxy(List<int> bytes) {

View File

@@ -2,9 +2,9 @@ from golden_utils import flatc_golden
def flatc(options, schema): def flatc(options, schema):
# Wrap the golden flatc generator with Dart specifics # Wrap the golden flatc generator with Dart specifics
flatc_golden(options=["--dart"] + options, schema=schema, prefix="dart") flatc_golden(options=["--dart"] + options, schema=schema, prefix="dart")
def GenerateDart(): def GenerateDart():
flatc([], "basic.fbs") flatc([], "basic.fbs")

Some files were not shown because too many files have changed in this diff Show More