Compare commits

..

248 Commits

Author SHA1 Message Date
Wouter van Oortmerssen
697147a2e6 updated maven build files
Change-Id: I33c69978fe7a22485a7fd5ceb7a480e84e8bcdb3
2020-03-16 11:33:42 -07:00
Wouter van Oortmerssen
6df40a2471 pre-tag version bump for 1.12
Change-Id: I84a9365e9d8a1afe333b1df85058401ffe0a6b7c
2020-03-12 15:33:39 -07:00
mustiikhalil
0dba63909f Removes the inner loop in the endtable check written tables (#5803) 2020-03-12 12:13:03 -07:00
Marc Butler
0e3fdd0eea Escape characters in jsonschema descriptions (#5644)
* Escape JSON Schema comments

* Add quotes to monster comment

Thus exercising the JSON Schema comment escape support.
2020-03-12 12:10:30 -07:00
Vladimir Glavnyy
45a2b07cbd Remove noexcept qualifier copy-ctor of union type (#5800) (#5802)
- Remove `noexcept` qualifier from generated 'union' copy-constructor
- Remove `noexcept` qualifier from generated 'union' assign-operator
2020-03-12 12:07:27 -07:00
Vladimir Glavnyy
d10c163142 Replace 'assert' by 'FLATBUFFERS_ASSERT' inside idl_parser.cpp (#5799) 2020-03-12 11:18:10 -07:00
Jakub Vrána
35abb7f89b Add non-nullable modifier to return type of functions never returning null (#5797) 2020-03-12 09:02:29 -07:00
Myrice
9954e09ab7 [C++] Generate code for vector force_align attribute. (#5796)
* [Flatbuffer] Generate code for force_align with CreateXDirect and Pack functions.

* Fixed Visual Studio 10.0 compile error for std::to_string.

* Fixed Visual Studio 10.0 compile error for std::to_string.
2020-03-12 08:32:29 -07:00
jean-airoldie
95a21327fc rust: pub export the VectorIter type (#5736) 2020-03-09 17:25:03 -07:00
Wouter van Oortmerssen
89b6183ee9 Fix Python min alignment
This was accidentally deleted in:
9fa8245e81

Change-Id: I8cad721e075279f6a67aca81259f73fb75aba482
2020-03-09 16:46:41 -07:00
Lee Mracek
5a98d65e86 [Rust] Add gen-name-strings for Rust (#5757)
* Add gen-name-strings for Rust

* Clang format

* Add tests and generate with gen-name-strings

* Clang-format

* Stop doing gen-name-strings with C++ code

* Bring generate_code.bat up with generate_code.sh
2020-03-08 19:05:20 -07:00
Wouter van Oortmerssen
f73d205bc7 Removed assert that wasn't backwards compatible.
Change-Id: I8e74d6fddf91fe955fffc572af9d671160325731
2020-03-05 17:21:47 -08:00
Wouter van Oortmerssen
7c37abe92d [C#] add ObjectAPI Serialization Utility (#5785)
* [C#] add ObjectAPI Serialization Utility

* set InitialBufferSize to 64k

* rename SerializeToFlatBuffers to SerializeToBinary
2020-03-05 09:33:22 -08:00
Wouter van Oortmerssen
4749e77b0e Fixed docs on how to obtain parser error.
Change-Id: Ib3ffbdf51ef6af1f5c8267b84b84dceed9d4a838
2020-03-02 12:16:02 -08:00
Derek Bailey
6ff1898413 Added --filename-suffix and --filename-ext to flatc (#5778)
* Fixed refractoring issue in reflection/generate_code.sh. Also, mv deletes the original file, so I don't need to clean it up manually in that case.

* Added --filename-suffix and --filename-ext to flatc

* Fixed typo and added example generation of suffix and extension for C++

* Removed extra ;

* Removed clang-format block from a region that didn't need it. Fixed an auto format of another clang-format block

* Added docs, fixed pointer alignment, removed suffix test file
2020-03-02 10:15:23 -08:00
Derek Bailey
c9a30c9ca2 Fixed refractoring issue in reflection/generate_code.sh. Also, mv deletes the original file, so I don't need to clean it up manually in that case. (#5777) 2020-02-27 12:59:43 -08:00
Derek Bailey
8c02d17bea Skip writing reflection_generated.h if not changed (#5776) 2020-02-24 14:46:24 -08:00
mustiikhalil
34305c4ce4 [Swift] Adds GRPC to Swift (#5758)
* Adds the basic structure for required to add grpc support

Added the message implementation

Updated the code to confirm to the protocol flatbuffersobject

Adds an example for Swift flatbuffers GRPC

Started implementing the swift GRPC code Gen

Generator generates protocols now

Fixing ci issues

Migrated the logic to use grpc_generator::File instead of string

Refactored swift project

Implemented GRPC in swift

Finished implementing GRPC in swift

Fixes issues

Adds contiguousBytes initializer to swift

Adds documentation + fixes buffer nameing in tables + structs

Adds documentation + fixes buffer nameing in tables + structs

Updated tests

* Updated version
2020-02-24 09:27:41 -08:00
Paulo Pinheiro
cd88e6b2aa [Java][FlexBuffers] Abstract buffer access from ByteBuffer (#5743)
To read and build flexbuffers on Java, one needs to wrap the data
using  ByteBuffer. But for the common case of having ByteBuffers
backed by arrays, accessing from a ByteBuffer might be inefficient.

So this change introduces two interfaces: ReadBuf and ReadWriteBuf.
It allows one to read and writes data directly on an array. It also allow
 other buffer implementations to be used with flexbuffers.

Another change is that FlexBuffersBuilder backed by array allows
the buffer to grow with the increase of the message size. Something
that could not be done with ByteBuffer.
2020-02-21 11:46:40 -08:00
mustiikhalil
3ec7a53c62 Adds cocoapods and a readme of how to get the package (#5771) 2020-02-21 11:42:07 -08:00
Omer Akram
6d44cede70 [snap] Fix versioning (#5727)
* fix snap versioning

* no need to install git as build packages
2020-02-13 08:05:21 -08:00
Joseph Pyott
cc08c0835b [Python] Fixed potential allignment issue (#5768) 2020-02-12 13:53:09 -08:00
xtrm0
54f8b787cb Fix memory leak on cpp object api (#5761)
Previously UnPack would allocate data with new and assign it to a
raw pointer. This behavior makes it possible for the pointer to be
leaked in case of OOM. This commit defaults to use the user specified
pointer (which needs to implement a move constructor, a .get() and a
 .release() operators), thus preventing these leaks.
2020-02-12 12:12:45 -08:00
Joseph Pyott
17557f9131 [Python] Fixed issue #5499 (#5764) 2020-02-11 15:02:21 -08:00
David P. Sicilia
d54af8cd43 [C++] Use strong enum type for vectors when scoped-enums is on. (#5750)
* [C++] Use strong enum type for vectors when scoped-enums is on.

These changes only apply when scoped-enums is on, and thus only
the C++17 tests show diffs.

This may break users who use 1) use scoped-enums and 2) use
vectors of enums.  However, it seems that this change should
have been made originally when scoped-enums were added.

Fixes #5285

* [C++] Put strong enum change also behind C++17 flag.

It actually only needs C++11 technically, but this is being done
to avoid breaking any existing users.

Tests were rerun, but produced no additional diffs, as expected.

* [C++] Forgot one location in which C++17 guard needs to go.

This commit produces no additional diffs in generated code.

* Use g_only_fixed_enums instead of scoped_enums.
2020-02-10 17:45:32 -08:00
mugisoba
173e10fdf1 [C#] support Json Serialization (#5752)
* support json serialization

* fix invalid json format.
* string must be written with double quotes.
* remove commma after the last object member.

* fix indent

* Revert "fix invalid json format."

This reverts commit d6820ed50c.

* quated string value.

* add cs-gen-json-serializer flag.

* fix preprocessor indent

* ENABLE_JSON_SERIALIZATION -> ENABLE_JSON_SERIALIZATION_TEST

* share TestBuffer method

* remove ENABLE_JSON_SERIALIZATION

* remove duplicated test data

* [windows] add nuget restore and copy test data.

* [docker mono] share msbuild settings with windows. add nuget restore and copy test data.

* add some note for json api.
2020-02-10 17:43:36 -08:00
Wouter van Oortmerssen
8f56990f6c FlexBuffers: C++: scalar-only typed vectors were not aligned.
This means data written with older versions of this code has
potentially misaligned data, which we'll need to support.
This isn't a problem on most architectures, but could be on
older ARM chips. To support them properly may require swapping
out uses of `flatbuffers::ReadScalar` with a version that does a
memcpy internally.

Change-Id: Ib352aab4a586f3a8c6602fb25488dcfff61e06e0
2020-02-06 11:56:28 -08:00
Robert Winslow
6400c9b054 Bump Rust port to 0.6.1 (#5747) 2020-01-30 13:55:44 -08:00
mugisoba
7418d85872 [C#] support Object API (#5710)
* [C#] support Object API

* fix sign-compare

* fix indent

* add new line before for loop.

* using auto whenever possible

* reduce the amout of blank lines.

* wip: support vectors of union

* done: support unions of vectors

* set C# version to 4.0
* remove null propagation operator
* remove auto property initializer
* remove expression-bodied method
* remove pattern matching

* add Example2 to NetTest.sh

* separate JavaUsage.md and CsharpUsage.md from JavaCsharpUsage.md

* add C# Object based API notes.

* support vs2010.

* remove range based for loop.

* remove System.Linq

* fix indent

* CreateSharedString to CreateString

* check shared attribute

* snake case
2020-01-30 10:18:28 -08:00
mustiikhalil
c580fa284c Adds min and max, comments, and all of swift's keywords + fix docs (#5737) 2020-01-27 10:05:41 -08:00
Dan Field
f2a1272303 Use VS 2017 and 2019 on CI, fix cast issue in dart_idl (#5740)
* vs2019

* another attempt

* syntax

* fewer

* fix dart
2020-01-27 10:03:00 -08:00
mustiikhalil
316d7c2089 Creates a flatbuffers validation function + small fix (#5725) 2020-01-24 14:55:57 -08:00
sjoblom65
47026ea6ba Added the code to embed the binary schema to the source (--bfbs-gen-embed). (#5701)
* Added the code to embed the binary schema to the source.
This is pulled forward from a old PR #5162 that will be closed.

* Update idl_gen_cpp.cpp

Added a small comment to trigger a new build. The build was failing in a strange location and doesn't look like it has anything to do with the code.

* Moved the EscapeAndWrapBuffer to util.cpp and did some formating.

* One more camelCases removed and renamed some variables.

* wrapped_line_xxx should have been passed as a const reference in the first place.

* Moved the bfbs embed sample to it's own file.

* Missed moving the namespace back.

* Moved the embedded bfbs to test.cpp instead of using a sample.

* Missed adding the generation of embedded bfbs to the build.

* See if this makes the build happier.

* Fixed a in-compatable cpp output of the generated header.

* Did some changes to reflect the code review comments.
1. Update the EscapeAndWrapBuffer to BufferToHexText and fixed a variable name.
2. Moved the include of the embedded binary schema to all the other includes.

* Moved some code to inline the instead of using a local variable.

* Moved the BufferToHexText back to be a inline function in util.h
2020-01-24 14:55:34 -08:00
Paulo Pinheiro
3f677f2414 [Java][FlexBuffers] Deprecate typed vector strings due to design flaw (#5722)
* [Java][FlexBuffers] Deprecate typed vector strings due to design flaw

It will still be possible to read buffers with this type, but the
elements will be treated as FBT_KEY and will be read as null-terminated
string.

Trying to build a vector of strings as typed will throw an exception.

More information on https://github.com/google/flatbuffers/issues/5627

Also, fix another bug on strings, where long strings were not properly
aligned.

* [Java][FlexBuffers] Make FBT_VECTOR_STRING_DEPRECATED considered typed.

The logic for FlexBuffers.isVectorType() was changed
to not consider FBT_VECTOR_STRING_DEPRECATED a typed
vector, but that can lead to missinterpretation for
existing serialized data. So we are reverting.
2020-01-24 09:58:15 -08:00
mustiikhalil
a593a11e59 [Go] Implements a SharedStrings function (#5733)
* Adds the sharedstring implementation for go

* Reimplemented testcase according to request
2020-01-24 09:57:34 -08:00
vkill
7cdfc8475e [Swift] Fix padding function overflow when bufSize is 0 (#5721)
* [Swift] Fix padding function overflow when bufSize is 0

[Swift] Generate linuxmain

* [Swift] Using the overflow addition operator to resolve integer overflow
2020-01-24 09:45:19 -08:00
Phoebe
bab2b0db48 Add vcpkg installation instructions (#5732)
* Add vcpkg installation instructions

* Update comments
2020-01-23 15:46:25 -08:00
Dan Field
89418eb848 [Dart] Fix deprecated field support, inf/nan (#5724)
* Fix deprecated field support, inf/nan

* unused params

* rerun tests
2020-01-23 14:53:58 -08:00
Max Burke
9cadf05d89 [typescript] Size-prefixed root accessors not taking into account size prefix (#5717)
* [typescript/javascript] Size-prefixed root accessor needs to account for the size prefix.

* [typescript] Add parentheses after "new" expression.

* Update generated test files
2020-01-20 21:20:52 -08:00
Max Burke
6da1cf79d9 [rust] Add use declarations to Rust-generated bindings for imported FB definitions (#5645)
* Bugfix for Rust generation of union fields named with language keywords

Looking at ParseField, it appears that in the case of unions, an extra field with a `UnionTypeFieldSuffix` is added to the type definition, however, if the name of this field is a keyword in the target language, it isn't escaped.

For example, if generating code for rust for a union field named `type`, flatc will generate a (non-keyword escaped) field named `type_type` for this hidden union field, and one (keyword escaped) called `type_` for the actual union contents.

When the union accessors are generated, they refer to this `type_type` field, but they will escape it mistakenly, generating code like this:

```
  #[inline]
  #[allow(non_snake_case)]
  pub fn type__as_int(&self) -> Option<Int<'a>> {
    if self.type__type() == Type::Int {
      self.type_().map(|u| Int::init_from_table(u))
    } else {
      None
    }
  }
```

Which will fail to build because the field is called `self.type_type()`, not `self.type__type()`.

* [Rust] Add crate-relative use statements for FBS includes.

At present if a flatbuffer description includes a reference to a type in
another file, the generated Rust code needs to be hand-modified to add
the appropriate `use` statements.

This assumes that the dependencies are built into the same crate, which
I think is a reasonable assumption?

* Revert "[Rust] Add crate-relative use statements for FBS includes."

This reverts commit d554d79fec.

* Add updated generated test files.

* Fixing Rust test harness to handle new includes.

Test binaries need to add references to generated code that's
transitively included.

This also has the knock-on in that this code (which is referenced by
include directives directly in the flatbuffer schema files) also needs
to be generated, hence the changes to generate_code.sh.

* Test harnesses expect test data to be checked in.

Put include_test2 files into the same directory as the include_test2
schema definition.

Update all code generation scripts (forgot the batch file from last
time).

Path updates in Rust test.

* Include updated generated code

* Address comments raised in PR

* Fix failing Rust tests.

* Previous merge clobbered this branch change.

* Add updated imports to benchmarks.

* Clarifying comment per PR request

* Update documentation comments per feedback

* Remove non-Rust generated files for include tests, per feedback from @rw/@aardappel

* Broken code generation batch file

* Fix typo

* Add TODO for tidying up use declaration traversal sometime in the future

* Update test files.
2020-01-19 14:47:28 -08:00
Somo
bee1df96dc [Go] Replace references to hardcoded ”Monster" etc with idiomatic go wherever possible (#5716)
* go: replace objAPI-generated Pack func with method

See discussion at https://github.com/google/flatbuffers/issues/5668

* go: replace generated union type UnPack func with method

Similar to discussion https://github.com/google/flatbuffers/issues/5668

But signature:
```
func AnyUnPack(t Any, table flatbuffers.Table) *AnyT
```

Becomes,
```
func (rcv Any) UnPack(table flatbuffers.Table) *AnyT
```
2020-01-16 16:19:00 -08:00
Vladimir Glavnyy
01189d7edd [C++] Fix for printing of enum in case output_enum_identifiers=1. (#5706)
* Add test-case for testing of the future Color in json (output_enum_identifiers = true)

* Refactoring of idl_gen_text.cpp. Fix for printing of bit-enum with active output_enum_identifiers=1.

* Move  GenerateText implementation into class

* Remove unnecessary code from flatbuffers.h
2020-01-16 14:12:25 -08:00
vkill
c4b2b0a25d [Swift] Support create long string (#5709)
* [Swift] Support create long string

* [Swift] Move the test case to correct dir
2020-01-16 12:08:59 -08:00
mustiikhalil
a4b2884e4e Added create function for swift (#5707)
Fixed the create functions and updated the test cases in swift

Removes unneeded code

Updated documentation
2020-01-13 12:34:06 -08:00
mustiikhalil
04d80f255d [Swift] Swift implementation 🎉🎉 (#5603)
* Implemented the swift version of Flatbuffers

Implemented serailzing, reading, and mutating data from object monster

Fixes mis-aligned pointer issue

Fixes issue when shared strings are removed from table

Adds swift enum, structs code gen

Fixed namespace issues + started implementing the table gen

Added Mutate function to the code generator

Generated linux test cases

Fixed an issue with bools, and structs readers in table writer

Swift docker image added

Updated the test cases, and removed a method parameters in swift

Fixed createVector api when called with scalars

Fixed issues with scalar arrays, and fixed the code gen namespaces, added sample_binary.swift

Cleaned up project

Added enum vectors, and their readers

Refactored code

Added swift into the support document

Added documentation in docs, and fixed a small issue with Data() not being returned correctly

Fixes Lowercase issue, and prevents generating lookups for deprecated keys

* Made all the required funcs to have const + removed unneeded code + fix lowercase func

* Removed transform from lowercased and moved it to function

* Fixes an issue with iOS allocation from read

* Refactored cpp code to be more readable

* casts position into int for position

* Fix enums issue, moves scalar writer code to use memcpy

* Removed c_str from struct function

* Fixed script to generate new objects when ran on travis ci: fix

* Handles deallocating space allocated for structs

* Updated the test cases to adhere to the fileprivate lookup, no mutation for unions, and updated the names of the vector functions
2020-01-09 12:12:10 -08:00
Wouter van Oortmerssen
55686100aa Changed direct calls to strtod to use StringToNumber
StringToNumber will correctly use locale-insensitive functions
when available.

Change-Id: I6bde11039a541634186f8f791012af2eb0d86b8d
2020-01-09 11:48:09 -08:00
emkornfield
718351831d Document JSON compatibility guarantees. (#5704)
https://github.com/google/flatbuffers/issues/5688
2020-01-09 10:56:34 -08:00
Vladimir Glavnyy
d1b34f0f28 Add CMake 'generated_code' target to simplify resolution of build dependencies (#5697) 2020-01-06 15:26:41 -08:00
Michael Beardsworth
21b7061963 (Optionally) add an additional suffix namespace to generated fbs files. (#5698)
This change allows for the generation of fbs files (from proto) that
don't contain name collisions with the protobuf generated C++ code,
allowing both the proto and fbs message types to be linked into the same binary.
2020-01-06 10:00:59 -08:00
dreifachstein
35daaf83d3 [Java] Replace Table.UTF8_CHARSET with StandardCharsets.UTF_8 (#5696)
StandardCharsets.UTF_8 is already used in FlexBuffersBuilder.
2020-01-06 09:28:19 -08:00
Robert Winslow
3b458f7a17 Rust: Temporarily disable 2 endianness unit tests (#5695)
Rare failures occur on AppVeyor in these functions; the failures appear
spurious.
2020-01-02 13:34:47 -08:00
David P. Sicilia
a5d9d0f7d3 [C++17] Add Traits class for Tables and Factory function within it. (#5678)
* Include flattests_cpp17 in unit tests when C++17 build is enabled.

* [C++17] Generate generic table factory function.

1. For each table, generate a convenient free-standing factory
   function that allows creating the table in a generic way by
   specifying only the type.  This is the first change in a series
   of changes to make Flatbuffers generated C++ code more friendly
   to code bases that make use of C++ template metaprogramming
   techniques to manage the serialization process.  Example:

     Before :(

       // The name of the Flatbuffers type (and namespace) must
       // be hard-coded when writing the factory function.
       auto monster = MyGame::Example::CreateMonster(fbb, ...);

     After  :)

       using type_to_create = MyGame::Example::Monster;
       // No namespace needed on CreateByTagType.
       auto monster = CreateByTagType((type_to_create*)nullptr,
                                      fbb, ...);

   This feature requires building with C++14 or greater, and thus
   it is guarded behind --cpp-std >= c++17 in the flatbuffers C++
   generator.

2. Fix a CMake bug to include C++17 unit tests in test suite.

* [C++17] Replace standalone variadic factory function with type_traits.

Add a `type_traits` to each table class.  This `type_traits` can be
populated with various compile-time info about the table.  Initially,
we have the Create* function and type, but is extensible in the future.

* Remove empty line and fix stale comments.

* Rename type_traits to Traits and move fwd declaration.

* Fix parameter evaluation order issue and use lambda for scope.
2020-01-02 10:12:14 -08:00
Wouter van Oortmerssen
3cd9b6434a Removed code_generators.cpp from library targets
Change-Id: Ia6e032a77983bf1838b8675f51d1c910acc991d8
2020-01-02 08:50:39 -08:00
Max Burke
355dfd48d1 [rust] Make enum names public (#5690)
* Bugfix for Rust generation of union fields named with language keywords

Looking at ParseField, it appears that in the case of unions, an extra field with a `UnionTypeFieldSuffix` is added to the type definition, however, if the name of this field is a keyword in the target language, it isn't escaped.

For example, if generating code for rust for a union field named `type`, flatc will generate a (non-keyword escaped) field named `type_type` for this hidden union field, and one (keyword escaped) called `type_` for the actual union contents.

When the union accessors are generated, they refer to this `type_type` field, but they will escape it mistakenly, generating code like this:

```
  #[inline]
  #[allow(non_snake_case)]
  pub fn type__as_int(&self) -> Option<Int<'a>> {
    if self.type__type() == Type::Int {
      self.type_().map(|u| Int::init_from_table(u))
    } else {
      None
    }
  }
```

Which will fail to build because the field is called `self.type_type()`, not `self.type__type()`.

* [Rust] Add crate-relative use statements for FBS includes.

At present if a flatbuffer description includes a reference to a type in
another file, the generated Rust code needs to be hand-modified to add
the appropriate `use` statements.

This assumes that the dependencies are built into the same crate, which
I think is a reasonable assumption?

* Revert "[Rust] Add crate-relative use statements for FBS includes."

This reverts commit d554d79fec.

* Address comments raised in PR

* Update documentation comments per feedback

* Fix typo

* [rust] Make enum variant names public.

* Update generated test files

* Add test for public enum names
2019-12-31 10:28:58 -08:00
Michael Beardsworth
bcd58a159b Correct inverted logic around include prefixes. (#5689)
4d1a9f8d9e inverted the logic around
keeping the include prefix. This change fixes the error.
2019-12-30 10:34:01 -08:00
lu-wang-g
a2c12900aa Optimize Pack method using numpy (#5662)
Add the support to pack using numpy for scalar vectors when numpy is available.
2019-12-26 21:42:11 -05:00
Austin Schuh
901b89e733 [C++] Add Builder and Table typedefs (#5685)
* Add Builder and Table typedefs

This gives us a way to use templates to go from a builder to a table
and back again without having to pass both types in.

* Fix tests/cpp17/generated_cpp17/monster_test_generated.h
2019-12-26 14:56:46 -08:00
Wouter van Oortmerssen
31f8799083 Minor doc updates: FlexBuffers C#, Discord, CppUsage.
Change-Id: Ie34ff580eb2f41ff35f85271b10865f4a14d0dca
2019-12-26 12:36:41 -08:00
Austin Schuh
8023d99e21 Upgrade rules_go (#5684)
This should help with #5672 if I'm reading the report back from
buildkite properly.
2019-12-26 10:07:15 -08:00
Austin Schuh
b4154405d1 Fix --incompatible_load_cc_rules_from_bzl (#5683)
Incompatible flag --incompatible_load_cc_rules_from_bzl will break
FlatBuffers once Bazel 1.2.1 is released.

Fixes #5671
2019-12-26 10:03:22 -08:00
Austin Schuh
04c17c7a76 Add support for absl::string_view when available (#5682)
For C++11 platforms, absl::string_view is sometimes available. This can
be used for string_view when std::string_view is not available.
2019-12-26 10:02:24 -08:00
Austin Schuh
62ec7d52ce [Bazel] Add support for compatible_with and restricted_to (#5681)
* Add support for compatible_with and restricted_to

These attributes have been available in Bazel for years.  Pass them
through so the flatbuffer rules can be used with them.  They let you
constrain which target platform is used.

While we are here, fix gen_reflections to work with bazel.

* Add docs
2019-12-26 09:58:48 -08:00
Robert Winslow
7de668053f CI: New Docker tests for Python with numpy (#5677)
* New Docker tests for Python with numpy

* print numpy status in test suite
2019-12-24 02:14:55 -05:00
Wouter van Oortmerssen
3a70e0b308 Fixed struct initialization error on older versions of C#
"'this' object cannot be used before all of its fields are assigned to"

Change-Id: Icccdcc0d0be0fe0b87abe0eb28fe1cc91116fcfb
2019-12-23 17:35:54 -08:00
Wouter van Oortmerssen
9b13201356 Fixed warnings in FlexBuffers.java
- Missing return statement <- bug!
- Missing hashCode function.

Change-Id: I6333cac72adf8ead92ab2e6c7215650ce4571a73
2019-12-23 17:11:57 -08:00
Wouter van Oortmerssen
5e3916050c Fixed out of date licenses on gRPC Python files.
Change-Id: Ia6c3bf5d7da795db46c0baa8e9c7591de3400517
2019-12-23 14:01:41 -08:00
Wouter van Oortmerssen
c957550511 Removed test proto output.
Change-Id: Iaf64bec068d03dd1b75670e9a28dde7392ebddb5
2019-12-23 12:33:16 -08:00
Vladimir Glavnyy
44bf719883 Add flatc '--cpp_std' switch (#5656)
* Add flatc '--cpp_std' switch and sandbox for C++17 code generator

- Added 'flac --cpp_std legacy' for compatibility with old compilers (VS2010);
- Added experimental switch 'flac --cpp_std c++17' for future development;
- Added C++17 sandbox test_cpp17.cpp;
- C++ code generator generates enums with explicit underlying type to avoid problems with the forward and backward schema compatibility;
- Adjusted CMakeLists.txt, CI and generate code scripts to support of introduced '--cpp_std';

* Fix --cpp_std values: c++0x, c++11, c++17

* Add 'cpp::CppStandard' enum

* Add testing engine into test_cpp17

* Rebase to upstream/master

* Set default '--cpp-std C++0x'

* Fix code generation (--cpp_std C++11) in CMakeLists.txt

- Fix dependency declaration of grpctest target

* Revert --cpp-std for the tests from explicit C++11 to flatc default value (C++0x)
2019-12-23 12:13:48 -08:00
Wouter van Oortmerssen
3e8f15df90 Fix for FlexBuffers FBT_VECTOR_STRING size bit-width.
For details, test.cpp/FlexBuffersDeprecatedTest(), and also
https://github.com/google/flatbuffers/issues/5627

Change-Id: I6e86e1138a5777e31055cfa2f79276d44732efbc
2019-12-23 11:49:59 -08:00
stefan301
602721a735 Added Check to VerifyAlignment (#5675)
* Added missing EndTable() call to VerifyObject()

VerifyObject called VerifyTableStart() but not EndTable(). This made Verifier::VerifyComplexity() increase depth_ with each table, not with the depth of tables.

https://groups.google.com/forum/#!topic/flatbuffers/OpxtW5UFAdg

* Added Check to VerifyAlignment

https://stackoverflow.com/questions/59376308/flatbuffers-verifier-returns-false-without-any-assertion-flatbuffers-debug-veri
2019-12-23 09:08:35 -08:00
Michael Beardsworth
13c05f4da3 Improve import handling for proto conversion (#5673)
* Keep include prefix when converting from proto.

This change preserves the include prefix when generating flatbuffers
from proto (with FBS_GEN_INCLUDES) defined.

* Improve handling of imports in proto conversion.

Previously, there was no runtime flag to make proto->fbs conversion keep
the import structure of a collection of files. This change makes proto
conversion respect the --no-gen-includes flag and skip the output of
"generated" symbols.
2019-12-23 08:50:29 -08:00
Light Lin
ce3a1c43a2 [Dart] Fix prepare space for writeListInt64 and writeListUint64 (#5654)
* Fix prepare space for writeListInt64 and 

writeListUint64

* Fix align issues
2019-12-18 11:23:54 -08:00
Matt Brubeck
aa75e5734b Make Rust constants public (#5659)
* Make Rust constants public

Otherwise they cannot be accessed by code that consumes the generated
bindings.

* Re-generate test code

* Add a test for enum constants
2019-12-17 12:18:59 -08:00
cryptocode
2790fee257 Add namespace qualification to union types (#5666) 2019-12-17 09:11:26 -08:00
Max Burke
eddebec1b6 Bugfix for Rust generation of union fields named with language keywords (#5592)
* Bugfix for Rust generation of union fields named with language keywords

Looking at ParseField, it appears that in the case of unions, an extra field with a `UnionTypeFieldSuffix` is added to the type definition, however, if the name of this field is a keyword in the target language, it isn't escaped.

For example, if generating code for rust for a union field named `type`, flatc will generate a (non-keyword escaped) field named `type_type` for this hidden union field, and one (keyword escaped) called `type_` for the actual union contents.

When the union accessors are generated, they refer to this `type_type` field, but they will escape it mistakenly, generating code like this:

```
  #[inline]
  #[allow(non_snake_case)]
  pub fn type__as_int(&self) -> Option<Int<'a>> {
    if self.type__type() == Type::Int {
      self.type_().map(|u| Int::init_from_table(u))
    } else {
      None
    }
  }
```

Which will fail to build because the field is called `self.type_type()`, not `self.type__type()`.

* [Rust] Add crate-relative use statements for FBS includes.

At present if a flatbuffer description includes a reference to a type in
another file, the generated Rust code needs to be hand-modified to add
the appropriate `use` statements.

This assumes that the dependencies are built into the same crate, which
I think is a reasonable assumption?

* Revert "[Rust] Add crate-relative use statements for FBS includes."

This reverts commit d554d79fec.

* Address comments raised in PR

* Update documentation comments per feedback

* Fix typo
2019-12-15 15:18:22 -08:00
FujiZ
030fee36ab wrap multiple statements in do {} while(!IsConstTrue(true)) (#5655) 2019-12-13 10:14:14 -08:00
Gautham B A
f9724d1bde [gRPC] Uncomment MessageBuilder (#5658)
The line where the MessageBuilder was
constructed was commented out (perhaps
an oversight).
2019-12-09 10:28:31 -08:00
Björn Harrtell
b20801ca40 Supress unsigned-integer-overflow for PaddingBytes (#5647) 2019-12-09 10:06:04 -08:00
cryptocode
a8e800bd7c Add --force-empty-vectors option (#5653)
The rationale for this option is that JSON clients typically want empty arrays (i.e [] in the JSON) instead of missing properties, but not empty strings when the value isn't set.
--force-empty is kept as-is, i.e. it will force both empty strings and vectors.

Closes #5652
2019-12-05 17:33:45 -08:00
Wouter van Oortmerssen
d7530ae961 Fixed enum min/max values not properly escaped.
Change-Id: I503fbfaff1d2579807ca71a07cca8363dff75e52
2019-12-05 14:28:36 -08:00
bttk
99d11e279f Split Bazel targets into multiple packages (#5640)
* Split Bazel targets into multiple packages

* Merge /include/BUILD back into /BUILD
2019-12-02 14:14:48 -08:00
Google AutoFuzz Team
4fd8eb214b Remove a static_assert (#5643)
Having a static_assert on MSAN and ASAN prevents
the fuzzers from being used with different engines,
like TSAN, UBSAN, … but also with fuzzers that aren't
using MSAN/ASAN like afl for example.
2019-12-02 14:13:28 -08:00
lu-wang-g
65f8703572 Flatbuffers Python Object API (#5616)
* Flatbuffers Python Object API

Implement the logic to generate the Python object API that can
unpack the data from a buf class into an object class, and pack
the data of an object class to a buf class.

* Fix the build issues

Remove unused parameters and replace auto in the for-loop statement
with std::string to make it compatible with VS2010.

* Fix the build issues.

* Add support for Array type

Added logic to handle Array type in Python Object API. Updated the
generated code accordingly.

* Fix the old style casting from int to char

* Fixed another conversion from int to char

* Fixed the import for typing

Importing typing may cause errors when a machine do not have the
moduel typing installed. This PR fixes the issue by guarding
"import typing" with the "try/except" statement.

* Fix issue of iterating the vector of import list

* Update the generated examples using generate_code.sh

* Fix the import order for typing

The import list was stored in unordered_set, so that each generated
codes may have different import order. Therefore, it failed in the
consistency test where two generated copies need to have exactly the
same apperance.

* Optimize unpack using numpy

Use numpy to unpack vector whenever it is possible to improve unpack
performance.

Also, added codegen command for Python specificly in generate_code.sh,
because --no-includes cannot be turn on for Python.

* Fix the import order

* Update generate_code.bat for windows accordingly

* Replace error message with pass

Avoid printing error message for every Python2 users about typing.
Replace it with pass.
2019-12-02 14:11:28 -08:00
Ivan Shynkarenka
75823cc275 [Clang 10]: definition of implicit copy constructor for 'TableKeyComparatoris deprecated #5649 (#5650) 2019-12-02 14:10:09 -08:00
nilsocket
58e279244c [docs]: add missing semicolon (#5648)
Add missing semicolon for table field.
2019-12-02 14:01:25 -08:00
Tiago Silva
3c964e10ab [GO] Fix support for enums with underscores and Unions with imported members (#5600)
* Fix Enum Stringer method when Enum has underscores

Fixes #5481

* Fix go package importing itself when Union has imported members.
2019-11-26 12:25:36 -08:00
Vladimir Glavnyy
c3c32ec942 Fix ambiguity of a type deduction in TEST_EQ macro if arguments have enum class type. (#5630) 2019-11-25 12:56:47 -08:00
Vladimir Glavnyy
075e8d676b Simplify declarations of x-macro FLATBUFFERS_TD (#5638) 2019-11-25 12:54:59 -08:00
FujiZ
bcf1bd5c9e read vtable size through ReadScalar() (#5636) 2019-11-25 12:52:42 -08:00
Derek Bailey
136d75fa65 Changed null checks in test. Removed verifier pointer usage (#5634) 2019-11-21 10:25:31 -08:00
Vladimir Glavnyy
091fa1fd1b Add testing of C++ with sanitizers (CI-Docker) (#5631)
* Add C++ build testing with clang and gcc

This adds Dockerfiles which test building flatc and the C++ library against clang
and gcc. See discussion at #5119.  It is derived from the Travis CI tooling.

The GRPC tests are failing due to #5099 so those are commented out.

These are run from the .travis.yml file rather than the tests/docker/languages
folder because the builds may each take longer than 30 minutes and were hitting
Travis timeouts.

Parallel builds and build caching attempt to keep the build times low.

* Add GCC 8.3 and Clang 7.0 with sanitizers into CI (based on #5130)

- Add a docker based on Debian Buster.
- Add C++ building scripts for the docker.
- Leak-sanitizer requires SYS_PTRACE.
2019-11-18 12:16:41 -08:00
FujiZ
ff3781dc2d add namespace prefix in FLATBUFFERS_MAX_BUFFER_SIZE (#5629) 2019-11-18 12:02:14 -08:00
Malar Kannan
6beb9f49cb Support for python grpc - continuing the work from the pull request #4270 #4705 (#5613)
* Support for python grpc

* add few fixes

* Fixes build

* Fix python generator

* Add tests

* Fix grpc python test

* Fix tests and add incomplete python generator

* Fix python generator

* Add python generator methods

* Fix Appveyor build

* grpc python support v0.1

* Update tests

* update grpctest

* Remove duplicated code and fix a brace

* tests for flatbuffers grpc python

* Updated tests + removed SerializeToString, From String

* remove pickle import

* include missing files in ci - BUILD and generated test result
2019-11-14 16:58:35 -08:00
Derek Bailey
80988ea869 Removed idl_gen_general.cpp and move contents to code_generators.cpp (#5625) 2019-11-14 15:47:58 -08:00
Derek Bailey
0f2ff7eaa9 Lua cleanup (#5624) 2019-11-14 15:46:46 -08:00
Derek Bailey
dda095023d [C++] Adds basic schema evolution tests (#5611)
* Added basic schema evolution tests

* Add BUILD targets for evolution tests. Added to test/generate_code scripts

* Use vector.front() instead of vector.data()

* Added --scoped-enums option for evolution test
2019-11-14 15:44:18 -08:00
Derek Bailey
adbcbba5d1 [C++, C#, Java] Separated C# and Java generators into their own classes (#5618)
* Cloned idl_gen_general.cpp to idl_gen_csharp.cpp and removed java references

* Java generator changes
2019-11-11 11:37:55 -08:00
Dmitry
cbbd6aca04 add check for root_type specified for json schema generation (#5622) 2019-11-11 11:33:27 -08:00
messense
405c64e07d [Rust] Bump smallvec version to 1.0 (#5621)
See https://github.com/servo/rust-smallvec/pull/175 for changelog.
2019-11-11 09:52:26 -08:00
Derek Bailey
42c08cbca6 Ran src/clang-format-all.sh (#5617) 2019-11-11 09:29:37 -08:00
Wouter van Oortmerssen
33d5dd9bdd Improved pull request & clang-format instructions.
Change-Id: Ia439bcc61bac5788792244d10e573b1fba54b347
2019-11-07 14:37:33 -08:00
Derek Bailey
105dd528e9 Change monster_extra generation to use flatbuffers::unique_ptr (#5612) 2019-11-07 14:10:41 -08:00
Derek Bailey
f0f0efe7b8 [C++] Refactor to conform to Google C++ style guide (#5608)
* Automatic refractor of C++ headers to Google C++ style guide

* Automatic refractor of C++ source to Google C++ style guide

* Automatic refractor of C++ tests to Google C++ style guide

* Fixed clang-format issues by running clang-format twice to correct itself. Kotlin was missing clang-format on after turning it off, so it was changed,
2019-11-07 12:22:54 -08:00
Wouter van Oortmerssen
e837d5a296 Fixed deprecated method in GRPC Java test.
Change-Id: Iccae8fe9409adbf3cd3013a5cf3368e068175ad3
2019-11-04 17:23:01 -08:00
Wouter van Oortmerssen
9834ee9787 Fixed Apache license not using canonical version.
Now identical to https://www.apache.org/licenses/LICENSE-2.0.txt

Change-Id: I6eab8bdee2472107dfc72265e204fdd16f3abc2e
2019-11-04 17:15:56 -08:00
Even Rouault
44b2ab087c include/flatbuffers/base.h: fix no_sanitize issue with old clang (#5610)
Older clang versions raise:
```
./flatbuffers/base.h:365:1: error: unknown attribute 'no_sanitize' ignored [-Werror,-Wattributes]
__supress_ubsan__("alignment")
^
./flatbuffers/base.h:246:50: note: expanded from macro '__supress_ubsan__'
  #define __supress_ubsan__(type) __attribute__((no_sanitize(type)))
                                                 ^
```

Comparing https://releases.llvm.org/3.6.0/tools/clang/docs/AttributeReference.html
with https://releases.llvm.org/3.7.0/tools/clang/docs/AttributeReference.html
shows that __attribute__((no_sanitize(type))) is available since 3.7.0
2019-11-04 14:58:51 -08:00
Derek Bailey
46ae3f80a6 [C++, Java, C#, TypeScript, JavaScript] Skip generation of mutable union types (#5599)
* Skip generation of mutable union types

* Removed C# and Java unit tests that mutated a Union type
2019-11-04 14:54:44 -08:00
Even Rouault
7b38aa71e6 flatbuffers.h: fix documentation warning (#5607)
Fixes following clang -Wdocumentation warning:
```
flatbuffers.h:1762:17: error: parameter ']' not found in the function declaration [-Werror,-Wdocumentation]
  /// @param[in]] v A const reference to the `std::vector` of structs to
```
2019-11-04 14:28:33 -08:00
Derek Bailey
661bedd837 Add Lua FlatbufferBuilder Clean() method to enable reuseable builders (#5606) 2019-11-04 14:27:59 -08:00
Paulo Pinheiro
8526e12d73 [Kotlin] Fix union vector accessor after change in Java API (#5605)
Kolin uses java library as dependency, which changed the way it access union vector recently
(e365c502ff).

This changes updates kotlin code generation to match Java's changes.
2019-11-04 14:25:07 -08:00
Paulo Pinheiro
3c7b660d62 [flatc] Remove an always true condition for flexbuffers (#5604)
The condition was unnecessary and Detected by

PVS-Studio
V560 [CWE-571] A part of conditional expression is always true: !opts.use_flexbuffers. flatc.cpp 438
2019-11-04 14:23:15 -08:00
Lawrence Chan
964365ba69 [Go] Add UnPackTo functions (#5598) 2019-11-04 12:12:25 -08:00
iceboy
32254b7acd [Go] Object API support (#5339)
* start

* works for current usages!

* unpack: vector of struct

* optimize byte slice

* support nested struct

* support null table

* support struct

* support union

* update generated code

* grumble

* fix compiler warning

* update generated code

* wrap type in namespace

* bug

* wrap in namespace

* enum byte arrays

* generate struct for unions

* basic testing

* remove branching

* fix assert

* pack vector of fixed structs correctly

* omit null vectors

* Refactor Union Pack and UnPack methods

Remove append usage to increase code efficiency when dealing with large vectors

* generate goldens
2019-10-31 11:13:45 -07:00
Mathias Svensson
521e255ad9 Rust: Add idiomatic iterator for Vector type (#5579)
* Rust: Add idiomatic iterator for Vector type

* Add comments explaining some implementation details
2019-10-28 14:19:47 -04:00
Even Rouault
1b85292fd3 Fix typos in comments (#5590)
Found by the https://github.com/OSGeo/gdal/blob/master/gdal/scripts/fix_typos.sh
script on the internal copy of flatbuffers inside GDAL
2019-10-28 10:02:46 -07:00
Derek Bailey
480815447a C++ verifier for evolved union fields should return true (#5586) 2019-10-28 09:43:33 -07:00
Derek Bailey
8d5e424c65 Add ByteBuffer copy for vector of bytes in Java (#5587) 2019-10-28 09:30:31 -07:00
Mathias Svensson
b4774d2354 Rust: Fix Copy and Clone impls for a few generic types (#5577)
* Rust: Fix Copy and Clone impls for a few generic types

* Add tests for Copy+Clone

* Wrap Copy+Clone checks in a #[test] function
2019-10-28 00:20:29 -04:00
Vladimir Glavnyy
26f238c248 Add --clean-first to the cmake-build command (travis) (#5574)
- `--clean-first` runs `clean` target to remove previously generated files
- missed `monster_extra_generated.h` file added to the `flattests` target
2019-10-21 10:11:32 -07:00
StackDoubleFlow
e93c8c46e6 Fix Follow implementation for bool (#5554) 2019-10-19 23:24:13 -04:00
Vladimir Glavnyy
e21516b9d7 Fix issue #5557 (#5573)
- remove not necessary file `monster_test_generated.h` from sample_bfbs.cpp
2019-10-18 10:16:55 -07:00
Björn Harrtell
fbc11e8aec Avoid intentional unsigned integer overflow getting caught by sanitizers (#5572)
* Avoid intentional unsigned integer overflow getting caught by sanitizers

* Adapt from suggested compiler compatible solution

* And a third way :)
2019-10-17 15:47:51 -07:00
Bharat Tak
e9d29c21a7 Python: Add forceDefaults opt to python Builder (#5564)
* Add forceDefaults opt to python Builder

* Add test functions for force_default option for python builder

* Simplify

* Add force default test for UOffsetTFlags
2019-10-17 15:25:05 -07:00
Jacek Surazski
8bfafc76de Java: Don't annotate vector-of-tables item getters with @nullable. (#5562)
* Annotate getters with @Pure when --java-checkerframework is specified.

Together with @Nullable, this allows users to use static analysis tools
like CheckerFramework to catch NPEs caused by unset fields.

* Don't annotate vector-of-tables item getters with @Nullable.

Since Flatbuffers don't support null items in vectors of tables.
2019-10-17 15:23:15 -07:00
Wouter van Oortmerssen
df3e8bf4a7 Fixed warnings generated by recent JSON sorting feature.
Change-Id: I6fd6283b616c7a39bb878b1610e4ddf6e208fa0a
2019-10-17 15:16:40 -07:00
Idan Sheinberg
5665cfe492 [Java] byte buffer factory returned buffer capcity is used instead of the requested size (#5558)
* byte buffer factory returned buffer is used instead of the requested capacity

* byte buffer factory returned buffer is used instead of the requested capacity

* Comment fix
2019-10-17 15:11:33 -07:00
tira-misu
5797540ed0 #5544 Fix of Array of table is not sorted if Create<type>Direct() is used (#5546)
* Fix C/C++ Create<Type>Direct with sorted vectors

If a struct has a key the vector has to be sorted. To sort the vector
you can't use "const".

* Changes due to code review

* Improve code readability
2019-10-17 14:22:21 -07:00
Brian Harris
7f1af7cb02 Fix build with gcc version 7.4.0 (#5570) 2019-10-15 10:56:58 -07:00
Wouter van Oortmerssen
32f47ad247 Fixed JSON parser not sorting vectors of tables/structs with key.
Change-Id: Iacc0c8513af80a736700e6cbaf513ebdf8e3ac89
2019-10-10 15:25:39 -07:00
Paulo Pinheiro
842f672baf [FlexBuffers][Java] Cache size of Sized objects in FlexBuffers (#5551)
In my benchmarks it shows deserialization performance improvements of
around 7%
2019-10-03 15:56:29 -07:00
Paulo Pinheiro
d4cae0a623 Fix issue #5542 (#5543)
Empty objects that inherit from Sized would try to access internal
ByteBuffer when Sized::size was called. So we add a single byte in
the empty buffer, so when size() is called it would return 0
2019-09-30 14:05:19 -07:00
Wouter van Oortmerssen
f1147f65bb Fixed Android STLPort related error.
Change-Id: I59ff072e526fc63b3215767a4d4a2a8944b65654
2019-09-30 12:12:36 -07:00
Jack Zhou
69d3fec488 Fix namespaced struct/field name collision detection (#5540) (#5545)
Changes the use of `LookupStruct` to `LookupCreateStruct` in
`ParseField` to also detect when collisions happen in namespaces.
2019-09-30 11:50:03 -07:00
Paulo Pinheiro
cfb4ecf6f0 [flac] Add FlexBuffers option for generating data (#5519)
Alongside --binary and --json, an additional
switch (--flexbuffers) can be passed to convert
data using FlexBuffers
2019-09-26 15:06:11 -07:00
Robert Winslow
a92039687a Update Rust versions under test from 1.30.1 to 1.37.0 (#5538)
Fixes build errors from using newer crate versions with an old Rust version.
2019-09-26 14:31:11 -07:00
mjvk
625338d095 Adds XOPEN_SOURCE for PATH_MAX and POSIX 1993 for stat (#5529)
* Adds XOPEN_SOURCE for PATH_MAX and POSIX 1993 for stat

These are the only two required extension for compilation of
flatbuffers using -std=c++11 instead of gnu++11.

* Sets _XOPEN_SOURCE to 600 and enable POSIX2001 for fseeko
2019-09-26 09:40:14 -07:00
Paulo Pinheiro
3f8ce99c50 [FlexBuffers][Java] Add override Key::toString (#5533) 2019-09-25 14:14:39 -07:00
Paulo Pinheiro
0798b7b698 [FlexBuffers][Java] Fix wrong access to a string using Reference::asString(). (#5532)
The real position of a string is  calculated by using the indirect() method,
which should be based on parentWidth and not byteWidth, as it was implemented.

We are also fixing the flag BUILDER_FLAG_SHARE_STRINGS on FlexBuffersBuilder
that was set as '1', same value as BUILDER_FLAG_SHARE_KEYS.
2019-09-25 11:59:10 -07:00
Vladimir Glavnyy
cbdf82e2fb Fix Mutate() methods of Array<scalar/struct> (override 5508) (#5526)
* Draft with Array specialization (#5508)

* Array specialization + SFINAE to fold copy-paste (#5508)

* Add implicit specialization of Array<scalar> and Array<struct> (#5508)

- Tag dispatching is used for implicit specialization
- Array<scalar> and Array<struct> have different iterators and accessors
- Array<scalar> and Array<struct> have different Mutate() methods

* Add implicit specialization of Array<scalar> and Array<struct> (#5508)

- Tag dispatching is used for implicit specialization
- Array<scalar> and Array<struct> have different iterators and accessors
- Array<scalar> and Array<struct> have different Mutate() methods
2019-09-23 09:31:51 -07:00
Kulikov Alexey
e365c502ff Java: Added access object for vector of struct and vector of tables. (#5233)
* Java: Added access object for vector of struct and vector of tables.

* Java: Workarounds removed when accessing the union vector.
2019-09-23 09:22:43 -07:00
mmoscicki2
97f3aa9174 Fixed DetachedBuffer self move assignment (#5521) 2019-09-19 10:32:24 -07:00
Austin Schuh
2f5bb2eec4 Fix buildifier warnings found in new bazel (#5517)
Fixes warnings caught in:
https://buildkite.com/bazel/flatbuffers/builds/863#cff87e1d-b976-4734-8157-4b6d88c7b5e1
2019-09-19 09:58:36 -07:00
Wouter van Oortmerssen
917687c7a6 Fixed Reflection Verifier not handling vectors of unions.
Change-Id: Ie94386ff8e10fd2a964bd9155139b50953746a37
2019-09-16 17:48:54 -07:00
Wouter van Oortmerssen
f9277e691d Fixed GenerateText not handling vectors of unions.
Change-Id: Ie82abaf178495c4692e7d10be6b4a13f2fa1bee6
2019-09-16 14:44:14 -07:00
Kevin Fort
2706381eef Add element size parameter to __vector_as_arraysegment [c#] (#5512)
* Add element size parameter to __vector_as_arraysegment

Add element size parameter to __vector_as_arraysegment fixing issue where VectorAsBytes returns incorrect size span for multibyte element types.

* Update codegen

Update codegen and Table to return typed span.

* update test files

update test files
2019-09-10 17:07:46 -07:00
Paulo Pinheiro
b5560fcd52 [Java][FlexBuffers] Improve documentation for FlexBuffers in Java. (#5506)
Also add a FlexBuffer constructor to simplify usage
2019-09-10 10:06:47 -07:00
jaceksur
782b865c55 Annotate getters with @Pure when --java-checkerframework is specified. (#5510)
Together with @Nullable, this allows users to use static analysis tools
like CheckerFramework to catch NPEs caused by unset fields.
2019-09-10 10:01:27 -07:00
Edward
3bfc86eaff [Dart]fix: segment fault with empty namespace when generating dart file (#5507)
* fix: segment fault with empty namespace when generating dart file

* fix: compile err

* fix: compile err

* fix: imported file names

* fix test issues

* fix some language style issues
2019-09-09 14:40:33 -07:00
Casper
c0282873fb Rust: Fixed cargo clippy on non-generated code (#5485)
* Cargo clippy lints

* more lints

* more lints

* Restored a doc comment

* Comment on float eps-eq and adjusted casting
2019-09-09 13:02:43 -07:00
Jaemin Park
4b870aca98 [Javascript] Fix syntax error for signed enum (#5503)
* wrap quotes to enum name map to prevent syntax errorn when enum value is negative

* Add a test that covers signed enum case
2019-09-05 10:22:04 -07:00
Nathan Williams
d0e3870c0f [C#] Fix retrieving enumeration vectors as arrays (#5457)
* [C#] Fix retrieving enumeration vectors as arrays

* [C#] Don't generate CreateVectorBlock for enums
2019-09-03 14:10:54 -07:00
Björn Harrtell
fb25eb87f2 Doc typo fixes (#5505) 2019-09-03 11:50:42 -07:00
Morten Grouleff
cb35d3a0e5 Use all of the available space in the buffer returned by ByteBufferFactory to allow the factory to keep a pool of larger than initialsize sized buffers. (#5500) 2019-09-03 11:13:32 -07:00
Paulo Pinheiro
8e6cabb31b [FlexBuffers][Java] Implementation of FlexBuffers API (#5476)
* [FlexBuffers][Java] Implementation of FlexBuffers API

This is the initial attemp to implement FlexBuffer on Java.

There is some limitations as compared to the C++ implementation:
  1 - No mutations implemented yet
  2 - Does not parse from json

Also, this initial implementation is not focused and performance, but
get the basics write. So there is many opportunities for optimization, for instance,
remove all enums, return CharSequence instead of Strings and object pooling.

* [FlexBuffers][Java] Optimizations and simplification of the Builder  API.

This change removes BitWidth enum in favor of static ints. Also
make all "reads" APIs closer to C++ implementation (try to cast or convert
as much as possible, assuming user knows what he is doing). Finally,
we remove the helper classes for building vectors and maps.

There is no official benchmarks, but the unit tests are running in less
than 50% for previous runs, which mean those optimizations are worth it.

* [FlexBuffers][Java] Fix Reference::asString behavior

There was a incorrect assumption that strings would be null-terminated, which
could lead to truncated strings. S now it relies size instead of null-termination.

Other minor improvements
2019-08-29 15:06:24 -07:00
Wouter van Oortmerssen
bd31dd2425 Clarified value reuse in FlexBuffers
Change-Id: Ib771bfa46ccdf38eff25be857b1b73f8b300c649
2019-08-26 14:59:21 -07:00
Wouter van Oortmerssen
65b67d2132 Fixed test build invocation of arrays_test.fbs
Change-Id: Idfc8d9cfbdefda44f803a6232700842ee6b6bffd
2019-08-26 14:33:38 -07:00
Wouter van Oortmerssen
1fbb711324 FlexBuffers: allow any values to be shared.
(see comments in the code).

Change-Id: I5603abb0db436145739653692644bbcfd3c946e3
2019-08-26 14:17:52 -07:00
Wouter van Oortmerssen
cd75a36587 Android: remove app_dummy() calls
Change-Id: I0ebd4502f98d009ce5afe8c8bafb629284f0366c
2019-08-23 14:33:16 -07:00
Wouter van Oortmerssen
ec6b0bf297 Fixed STLPort Android compile error
Change-Id: I3595b9c6803718f34ce61fdfc367da97b50dc444
2019-08-23 14:17:33 -07:00
Earlonus
c11b5d7447 [bugfix]flexbuffers isvector bugfix (#5488)
* commit isvector bugfix (change email recommit to pass cla)

* commit IsUntypedVector

* delete isvectorormap function
2019-08-23 10:51:36 -07:00
svenk177
4525c91be3 Fix incorrect padding in arrays of structs (Issue #5484) (#5491) 2019-08-23 10:46:47 -07:00
Wouter van Oortmerssen
b97b342f59 Fixed missing generated code.
Change-Id: Iaa0633167c2a4d4543fc4de2af58112d60d5d1e6
2019-08-19 17:57:23 -07:00
Wes McKinney
c1058a903b C++ IDL generation adds superfluous semicolon in GenTablePost, causing (#5483)
-Wextra-semi-stmt warning when building with Clang 8.0.0. Update generated
files for testing
2019-08-19 17:49:37 -07:00
Tsingson
3030449348 [go]add Name() for ForceCodec interface (#5486)
* add Name() for ForceCodec  interface

// ForceCodec returns a CallOption that will set the given Codec to be
// used for all request and response messages for a call. The result of calling
// String() will be used as the content-subtype in a case-insensitive manner.
//

* Update grpc.go
2019-08-19 15:32:04 -07:00
Mark Nauwelaerts
a2485d4ecc reflection: check for valid union enum value during object verification (#5475)
... to avoid assertion failure or invalid access due to invalid vector index
2019-08-19 12:48:25 -07:00
Edward
a20e71ac96 has_method support for primitive fields in java runtime. Changed: idl.h, FlatBufferBuilder.java , idl_gen_general.cpp, idl_parser.cpp, flatc.cpp (#5468)
* has_method support for primitive fields in java runtime

* adding the new flag to flatc

* addressing the review comments
2019-08-19 12:46:48 -07:00
Max Burke
acc9990abd Fix compilation error in tests. (#5472)
Local variables were shadowing member fields, causing errors.
2019-08-05 11:57:54 -07:00
Alexey Geraskin
2d5315ff0e [C++] remove static_cast expression (#5440)
* [C++] remove static_cast expression

* [C++] Add unit test for native_type usage

* [C++] Add flatc compilation for native_type_test.fbs

* [C++] update CMakeLists to compile native_type_test.fbs properly

* Update BUILD file for bazel

* [C++] Add generated native_type_test_generated.h and fix arguments for flatc according to CMakeList

* [C++] remove "= default" from constructor to support old compilers

* Update BUILD file for bazel, attempt 2

* [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types

* Update BUILD file for bazel, attempt 3

* Update BUILD file for bazel, attempt 4

* Update BUILD file for bazel, attempt 5

* Update BUILD file for bazel, attempt 6

* [C++] Workaround for MSVC 2010 for the issue with std::vector and explicitly aligned custom data types Part 2

* [C++] Keep only one optional parameter to compile_flatbuffers_schema_to_cpp_opt

* native_type_test.fbs style corrected

* [C++] Code style modifications

* [C++] Fix flatc arguments in CMakeLists

* [C++] Remove --gen-compare from default parameters for flatc in CMakeLists

* [C++] Change Vector3D fields from double to float, to have alignment eq. 4 (to support MSVC 2010), plus minor review fix

* [C++] Remove one more #if !defined

* [C++] Restore version with correct static_cast, add the same fix for SortedStructs

* Revert "[C++] Restore version with correct static_cast, add the same fix for SortedStructs"

This reverts commit d61f4d6628.

* [C++] Fix Android.mk
2019-08-01 14:31:48 -07:00
ll-antn
7de1a5e347 [C++ ] Correctly serialize bit_flags enums to JSON with output_enum_identifiers option (#5454)
* Support output_enum_identifiers for enums with multiple bit values

* Cast bit_flag enum val to uint64_t instead of int64_t
2019-08-01 14:16:44 -07:00
Derek Bailey
a4e3ad808e Fix for Boolean types (#5379) (#5466)
The packing/unpacking steps for Boolean values was failing because the
code expected numerical values. I overrode the functions for the Boolean
metatable to account for this. I also had to exclude the Boolean
metatable from the GenerateTypes helper function, as that was overriding
the Pack/Unpack functions defined in its metatable.

Added Linux bash script to run Lua tests from the command line.

Bug: google/flatbuffers#5379

Tested: Added Lua tests that were failing and are now fixed with the
code changes.
2019-08-01 10:28:54 -07:00
Wouter van Oortmerssen
c953fa572b Renamed stale label from "wontfix" to "stale".
Change-Id: Iea88624d9d90e029a64cab9edf4e7c1cfc005e4a
2019-07-29 11:43:54 -07:00
Vladimir Glavnyy
0c86085a5b Replace '--cpp-include' brackets to quotes (#5438) (#5464) 2019-07-29 11:38:52 -07:00
Wouter van Oortmerssen
a1f7ecd148 Made stale.yml friendlier. 2019-07-26 18:56:56 -07:00
Vladimir Glavnyy
a20c55bea5 Extend the error message if base type of parsed scalar not resolved (#5456)
* Extend the error message if base type of parsed scalar not resolved #5447

* Resolve PR notes
2019-07-26 17:56:41 -07:00
Wouter van Oortmerssen
d7c2b388ef Add .github/stale.yml to auto close stale issues and PRs.
See https://probot.github.io/apps/stale/

Change-Id: I8176eeb21dbcd516f1d6f7b1e8c28602cdd9332a
2019-07-26 17:49:40 -07:00
Joseph Pyott
9fa8245e81 Python: Added support for file_identifiers (#5123)
* Python: Added support for file_identifiers

* Added tests. Fixed file_identifier code.

* Python: Fixed excessive padding of file_identifier. Repaired tests.

* Python: Made code compatible with python2.7

* Python: Typo fix in @endcond

* whitespace normaalization

* Stylistic change from if(not X is None) to if(X is not None). Added comment to type string.

* Python: Added support for automatic code generation of file_identifiers. Added tests for said code generation.

* converted sprintf to snprintf

* Bugfix, added snprint deffinition for MSVC

* changed snprint deffinition for MSVC to sprint_s

* changed scanf to IntToStringHex. Renamed HasFileIdentifier to GenHasFileIdentifier.

* Added updated genereated code to commit

* Python bugix: flatc no longer produces HasFileIdentfier for shcemas with no file identifier

* Added tests to verify `MonsterBufferHasIdentifier` returns false on no Identifier

* Python: added tests for GetBufferIdentifier and BufferHasIdentifier
Python: removed unessasary parenethesis in if statements
Minor format changes.

* Python : correceted instances of keyword arguments being called as positional arguments

* fixed typos and grammer in comments

* Minor style fixes

* Indentation fix

* Equals style changes

* Python: Fixed Alignment Issues. Changed test code to test against atual output

* Ran make(forgot to run make last commit)

* Python: Style changes

* Style changes

* indentation and style

* readded CONTRIBUTING.md

* Formatting tweak

Mostly to make CI run again

* More formatting fixes

* More formatting fixes

* More formatting fixes

* More formatting fixes

* Formatting fix

* More formatting fixes

* Formatting

* ran generate_code.sh
2019-07-26 11:06:25 -07:00
ll-antn
a5ca8bee4d Fix numeric_limits<T>::max() to avoid conflict with windows.h header (#5462) 2019-07-26 09:14:05 -07:00
ll-antn
09dea79a22 Support nested_flatbuffer attribute when parsing bfbs schema (#5448) 2019-07-26 09:13:11 -07:00
Stewart Miles
b632061eff Pin FlatBuffers Android Travis builds to NDK r17c (#5460)
r17c is the last Android NDK to include stlport and gnustl.
We want to continue to support these deprecated STLs until we have
confidence few enough customers are using them.
2019-07-25 17:58:02 -07:00
Jason Monschke
da88be05e1 Change deprecated vector Length() to size() in tutorial (#5450) 2019-07-25 11:09:40 -07:00
Wouter van Oortmerssen
d4fa984f1d Added missing Kotlin generated code change.
Change-Id: I7eeee6519b6dc619691437e44272cf5424d0d4ca
2019-07-25 11:08:06 -07:00
Uilian Ries
a0c0131e36 #4590 Fix Conan build (#5449)
* #4590 Fix Conan build

- Create separated build for Conan on master branch
- Add Clang 7,8
- Add Gcc 9

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

* #4590 Do not build Conan for PRs

Signed-off-by: Uilian Ries <uilianries@gmail.com>
2019-07-25 11:06:40 -07:00
Paulo Pinheiro
de9aa0cdee Add basic Kotlin support (#5409)
* [Kotlin] Add kotlin generate code for tests and add
kotlin test to TestAll.sh

* [Kotlin] Add Kotlin generator

This change adds support for generating Kotlin classes.

The approach of this generator is to keep it as close
as possible to the java generator for now, in order
to keep the change simple.

It uses the already implemented java runtime,
so we don't support cross-platform nor js Kotlin yet.

Kotlin tests are just a copy of the java tests.

* Add optional ident support for CodeWriter

Identation is important for some languages and
different projects have different ways of ident
code, e.g. tabs vs spaces, so we are adding optional
support on CodeWriter for identation.

* [Kotlin] Add Documentation for Kotlin

* [Kotlin] Modify generated code to use experimental Unsigned types.
2019-07-22 16:05:15 -07:00
Alexey Geraskin
a752d1b88c [C++] fix static_cast expression (#5441) 2019-07-18 11:51:12 -07:00
jean-airoldie
db972be264 [rust] Ran rustfmt against library code (#5389) 2019-07-09 13:41:51 -07:00
Vladimir Glavnyy
e304f8c115 Extend the test of MonsterExtra (#5428)
* Extend the test of MonsterExtra

- Extend C++ test of MonsterExtra
- Add conversion of fbs/json NaNs to unsigned quiet-NaN
- Update documentation (cross-platform interoperability)

* Fix declaration of infinity constants int the test
2019-07-08 11:22:56 -07:00
Thanabodee Charoenpiriyakij
47c7aa0361 Fix echo not interpret \n in GoTest.sh (#5426)
When running GoTest.sh, the last step that checking go format files
are print \n instead of new line:

These files are not well gofmt'ed:\n\nMyGame/Example/Color.go
MyGame/Example/MonsterStorage_grpc.go

This changes fix it by echo NOT_FMT_FILES in separate line.
2019-07-01 11:42:00 -07:00
Vladimir Glavnyy
7a63792929 Remove unused variables (#5382)
- Fix GenerateTextFromTable (aliasing typo)
- Fix unused variable in idl_gen_dart.cpp
- Fix std::string passing (should be non-const value or const-reference)
- Remove unused variables
2019-07-01 11:38:21 -07:00
Andrew Noyes
7d7d796cd0 Fix undefined behavior. Closes #5422 (#5423)
* Fix undefined behavior. Closes #5422

* Move check into callers of make_space
2019-06-27 14:11:31 -07:00
Edward
550b386995 Update Utf8.java: more detailed exception message (#5421)
Provide more detailed exception message for malformed 2 byte utf8 character
2019-06-27 12:19:57 -07:00
Adrian Perez
5479adc80f Fix for FLATBUFFERS_PREFER_PRINTF writing zero-length strings (#5418) 2019-06-27 09:23:13 -07:00
Vladimir Glavnyy
b7012484f3 Set C# Struct/Table visibility to public (#5381) (#5416) 2019-06-24 17:51:04 -07:00
Bryan Furia
92e9f33036 Don't check ForceDefaults when adding Offfset values (#5415) 2019-06-24 17:49:53 -07:00
Wouter van Oortmerssen
ff1a22a05f Fixed broken Utf8Old.java
This would not correctly encode/decode strings when substituted for
the default Utf8Safe.java

Change-Id: Ib303697663b5b8cbf6888492f5255b2a45384c04
2019-06-24 16:54:28 -07:00
Bryan Furia
9fb195cce8 Fix generating nested Flatbuffer accessors when they cross namespaces (#5414) 2019-06-24 11:46:00 -07:00
Austin Schuh
7836e65dd4 Fix compatability with Bazel 0.27 (#5412)
rules_go was too old and using deprecated features.  Upgrade it.
2019-06-20 10:25:41 -07:00
Wouter van Oortmerssen
123c7a4890 Updated missing generated code for PR #5313 (fixed arrays)
Change-Id: I249140119e6241beb5aec5670d0e5ccddc8f5251
2019-06-20 10:21:10 -07:00
svenk177
e635141d5b Add support for fixed-size arrays (#5313) 2019-06-18 00:15:13 +02:00
Vladimir Glavnyy
0d2cebccfe Add FLATBUFFERS_COMPATIBILITY string (#5381)
* Add FLATBUFFERS_COMPATIBILITY string

- Add a new __reset method NET/JAVA which hides internal state

* Resolve PR notes

* Use operator new() to __init of Struct and Table

* Restrict visibility of C# Table/Struct to internal level
2019-06-17 19:16:21 +02:00
John Luxford
a80db8538c [C#, Java, C++] Fixes issue #5399 by always including namespaces (#5404)
* [C#] Fixes issue #5399 by always including namespaces

* Updated tests for code generator changes

* Fixed 'As' method names
2019-06-14 17:47:07 +02:00
John Luxford
a6be1d0d74 [Go] Fix namespaces on enums (#5406) 2019-06-13 20:25:03 -07:00
Tiger Caldwell
a7e20b1996 Excluded crtdbg.h from non-MSVC compilation (#5401) 2019-06-13 11:58:40 +02:00
Michael Seifert
4eb3efc221 [flatc][docs] Document rounding behavior of floats in JSON output (#5397)
* [docs] Added an example on how to convert a FlatBuffer binary to JSON
Slightly adjusted section on "Using flatc as a conversion tool".

Signed-off-by: Michael Seifert <m.seifert@digitalernachschub.de>

* [docs] Updated obsolete JSON data in example showing how to convert JSON to FlatBuffer binaries.

Signed-off-by: Michael Seifert <m.seifert@digitalernachschub.de>
2019-06-12 12:35:39 +02:00
Will Stott
a807fa9567 Remove out-dated -S option from the flatc syntax. (#5398)
Looks like it's an older syntax for --strict-json which was long-ago removed in d38b9af243
2019-06-09 20:30:10 +01:00
jean-airoldie
b80ad7e439 [rust] Use read_scalar_at where possible (#5385)
This slightly improves readability.
2019-06-07 14:06:20 -07:00
jean-airoldie
16aef8ac0d [rust] Derive Eq + PartialEq on FieldLoc and FlatBufferBuilder (#5394) 2019-06-06 14:09:58 -07:00
Ashwin Ramaswami
b59a1ca2f8 fix typo (#5384)
* fix typo

* fix typo
2019-06-05 19:24:29 +01:00
mugisoba
4fdfe0d468 [bfbs] fix deserializing nested struct (#5383) 2019-06-02 12:49:27 -07:00
Vladimir Glavnyy
95004218f7 Fix multi-line comments for cpp enums (#5345) (#5346)
- fix CSharp comments generation
- fix Python comments generation
- fix Lua comments generation
- fix PHP comments generation
- fix Dart comments generation
- add brief description of Color enum
- add multi-line comments to the Monster:Color
2019-06-02 12:36:49 -07:00
Alexander Gallego
bc7ede8fb3 c++: Add command line option to add extra includes to gen files (#5360)
* c++: Add command line option to add extra includes to gen files

Fixes #5351
We have an ability to pass custom types for strings, allocators, etc
but have no way to tell the generator to include the classes in gen code

* c++: remove std::strtok for std::string methods. passes msvc compile

* generate_code.sh: add --cpp-includes to the test gen script

* tests:generate.bat: update code gen scripts w/ --cpp-includes

* cpp: use command line parsing for extra includes

s/--cpp-includes/--cpp-include/g
Simplify command line parsing of includes by using a std::vector.

* cpp: idl.h: move std::vector for cpp_includes as the last member

msvc does not understand initalization list on our CI server

* cpp:msvc: CI fails on for-range loops

* cpp:codegen: fix error reporting on flatcc

* as per code review: remove unwated --cpp-include in the
tests/generate_code.{sh,bat}
2019-05-31 13:43:30 -07:00
Wouter van Oortmerssen
b652fcc3a7 Break internal Java/C# APIs
This is done on purpose, to avoid API version mismatches that
can cause bad decoding results, see:
https://github.com/google/flatbuffers/issues/5368

Change-Id: I2c857438377e080caad0e2d8bcc758c9b19bd6ec
2019-05-31 13:00:55 -07:00
Wouter van Oortmerssen
c978b9ef1f Enforce matching version in Java and C#.
Change-Id: I7f1f12f2f97e5227e0dabc2965ce66a6d41c229c
2019-05-31 12:15:19 -07:00
360 CodeSafe
3a88e1031b Dereference of null pointer #5353 (#5376)
add an assert to make sure that `key_field` is not a null pointer.
2019-05-30 17:50:21 -07:00
mugisoba
51dd733ba4 [C#] add FlatBuffersBuilder.CreateSharedString (#5372) 2019-05-30 16:15:50 -07:00
emkornfield
79f0df3dfc [C++] Fix Undefined behavior for zero length vectors (#5355)
* Fix Undefined behavior for zero length vectors

* Change fix for UBSan
2019-05-30 16:13:34 -07:00
iceboy
9d92fd92e1 Rename AnyUniqueAliases.T to AnyUniqueAliases.TS to avoid naming conflict (#5362) 2019-05-30 16:02:57 -07:00
Marc Butler
93f74c0363 Generate FlagsAttribute for Csharp (#5370)
For schema enums with the bit_flags attribute, generate the
corresponding System.FlagsAttribute in generated Csharp code.
2019-05-30 15:57:41 -07:00
aardappel
43dbac5d25 Lobster: added builder API for tables 2019-05-22 19:42:13 -07:00
aardappel
53ea1ab1bd Lobster documentation fixes 2019-05-22 16:01:51 -07:00
aardappel
b10b050ab9 Made Lobster builder offsets strongly typed 2019-05-22 15:55:28 -07:00
aardappel
563dcd6893 Made Lobster API use strongly typed enums 2019-05-22 15:28:16 -07:00
aardappel
30ac512a54 Fixed Lobster implementation to work with latest language features 2019-05-22 11:48:10 -07:00
aardappel
b04736f9bd Fixed warnings in idl_gen_go.cpp 2019-05-21 18:54:26 -07:00
Siddhartha Bagaria
bc240b3004 [Go] Public visibility for gazelle default target (#5361) 2019-05-21 14:48:51 -07:00
jonsimantov
0f7e7fd209 Change usage of std::string's .at() to more widely-compatible []. (#5365) 2019-05-21 14:40:33 -07:00
Siddhartha Bagaria
766ed04422 Go bazel default target for gazelle (#5358) 2019-05-20 17:16:48 -07:00
David Reiss
c5e2d37337 [Go] Change two more sites to use enum types (#5359)
Fixes #5357 (regression introduced by #5235)
2019-05-20 14:46:36 -07:00
David Cowan
fe83b68ac6 Added a CPP UnPackSizePrefixed<struct_name> generated helper function (#5350)
* Added a cpp  UnPackSizePrefixed<struct_name> generated helper function

Missing helper function added to the cpp API generator for unpacking size prefixed structures

* Added generated test files
2019-05-20 14:01:44 -07:00
David Reiss
718ddea558 [Go] Make enums into real types, add String() (#5235)
* [Go] Make enums into real types, add String()

This changes the generated code for enums: instead of type aliases,
they're now distinct types, allowing for better type-checking. Some
client code may have to be changed to add casts.

Enum types now have a String() method, so they implement fmt.Stringer.

An EnumValues map is now generated, in addition to the existing
EnumNames map, to easily map strings to values.

Generated enum files are now gofmt-clean.

Fixes #5207

* use example.ColorGreen explicitly

* use valid enum value in mutation test, add new test for "invalid" enum

* add length check and comment
2019-05-17 12:41:39 -07:00
Siarhei Fiedartsou
8d86b5347f Add support for IAR compiler (#5347) 2019-05-16 11:56:22 -07:00
mmoscicki2
39bd667fd0 Fix reverse_iterator in Vector and tests (#5344)
Before this commit tests for iterators passed, even if the code inside
the loop has not been executed.
2019-05-16 11:49:01 -07:00
Björn Harrtell
0bb3ce6935 [JS/TS] Size prefix support (#5326)
* WIP size prefix support

* Consider size prefix in overloaded variant

* Work on code gen

* Disabled helper functions in code gen

* Enabled helper functions in code gen

* Fix size prefixed test

* Fix bad function call

* Add SIZE_PREFIX_LENGTH

* Fix review comments
2019-05-16 11:43:31 -07:00
iceboy
b56d60f058 [Go] Generate imports with fixed order (#5340)
* use fixed order for golang imports

* grumble
2019-05-13 10:10:14 -07:00
Vladimir Glavnyy
bff7ffbc51 Add detection of strtoull_l function (#5333) (#5337) 2019-05-09 10:15:29 -07:00
Vladimir Glavnyy
107c08988a Set default CRTReportMode for the flatc target (#5336)
* Set default CRTReportMode for the `flatc` target

* Add util.cpp to GRPC test target

* Fix path to util.h
2019-05-09 10:10:10 -07:00
Vladimir Glavnyy
f9ebfcb9c4 Make Monster's Color unsigned (#5318)
- update C++ monster_test::Color to unsigned type
- update Go Color:ubyte in the go_test.go
- add workaround for unsigned enum in java test
- sync generate.bat and generate.sh
2019-05-09 10:07:38 -07:00
Vladimir Glavnyy
b701c7d56e Fix out-of-range error (MSVC2010) in idl_gen_dart.cpp (#5335)
-- MSVC2010 doesn't support indexed access to \0-terminator.
2019-05-09 10:05:21 -07:00
Will Stott
103f61b685 [Python PyPI] Added classifiers and more links. Fixes typo and #5215 (#5272) 2019-05-08 12:42:20 -07:00
Malthe Borch
e47ca7ab40 Use a hash table to index existing vtables (#5314)
* Use a hash table to index existing vtables

This allows for quick deduplication even in situations where there
might be thousands of vtables due to 'combinatoric explosion'.

This fixes issue #5301.

* Refactor 0-offset trimming

* Improve deduplication benchmark

The routine now generates a set of realistic logical layouts and
uses a timer function that randomly picks a layout for each iteration.

The benchmark runs in batches of # of logical layouts = 1, 10, 100, 1000.

(Note that due to alignment, the actual number of vtables is usually slightly
higher.)
2019-05-06 15:00:02 -07:00
Vladimir Glavnyy
d79f4e9717 Add monster_extra files to Bazel cc_test section (#5321)
- add monster_extra.fbs
- add monsterdata_extra.json
2019-05-06 12:27:04 -07:00
Lee Mracek
5d67693e8f Fix typo in build_defs.bzl (#5320) 2019-05-06 12:10:11 -07:00
Vladimir Glavnyy
af74f87ccd Make MonsterExtra table a root table (#5315)
- MonsterExtra table a root table
- add mosterdata_extra.json
2019-05-02 15:12:58 -07:00
Vladimir Glavnyy
b8ef8c1521 Fix issues with uint64 enums (#5265)
* Fix issues with uint64 enums

- hide the implementation of enums from code generators
- fix uint64 the issue in the cpp-generator
- fix #5108
- new tests
- enums with bit_flags attribute should be unsigned

* Refine objectives of EnumDef's FindByValue and ReverseLookup methods

- move EnumDef::ReverseLookup implementation to idl_parser.cpp
- fix typos

* Make the IsUInt64 method private
2019-05-02 13:57:58 -07:00
László Csomor
6cc30b3272 [BUILD] Fix Bazel test target //:flatbuffers_test (#5311) 2019-04-29 10:01:23 -07:00
jean-airoldie
e5b6125fa2 Added common rust traits to FlatBufferBuilder (#5307)
* Added Clone, Debug and Default
2019-04-26 18:40:10 -07:00
Wouter van Oortmerssen
ac14c8906f Update GRPC Java generated file.
Change-Id: I57ccbe0b9ccbbec65ca04f9db3cbd62243480d92
2019-04-24 12:34:42 -07:00
Wouter van Oortmerssen
9936adf473 [maven-release-plugin] prepare for next development iteration
Change-Id: I402d857eef9f3e5f3765427c5d3b868ed5a3a22e
2019-04-24 12:09:50 -07:00
Wouter van Oortmerssen
bf9eb67ab9 [maven-release-plugin] prepare release 1.11.0
Change-Id: I716f6b915adfa6682b5d864857abf7d491d788b5
2019-04-24 12:09:44 -07:00
445 changed files with 45694 additions and 7933 deletions

View File

@@ -19,6 +19,7 @@ call generate_code.bat -b %buildtype% || goto FAIL
:: TODO: Release and Debug builds produce differences here for some reason.
git checkout HEAD -- monster_test.bfbs
git checkout HEAD -- arrays_test.bfbs
git -c core.autocrlf=true diff --exit-code --quiet || goto :DIFFFOUND
goto SUCCESS

View File

@@ -1,6 +1,8 @@
Thank you for submitting a PR!
Please make sure you include the names of the affected language(s) in your PR title.
Please delete this standard text once you've created your own description.
Make sure you include the names of the affected language(s) in your PR title.
This helps us get the correct maintainers to look at your issue.
If you make changes to any of the code generators, be sure to run
@@ -11,6 +13,8 @@ If your PR includes C++ code, please adhere to the Google C++ Style Guide,
and don't forget we try to support older compilers (e.g. VS2010, GCC 4.6.3),
so only some C++11 support is available.
For any C++ changes, please make sure to run `sh src/clang-format-git.sh`
Include other details as appropriate.
Thanks!

18
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 365
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 14
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- security
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
activity for 1 year. It will be automatically closed if no further activity occurs.
To keep it open, simply post a new comment. Maintainers will re-open on
new activity. Thank you for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

9
.gitignore vendored
View File

@@ -1,6 +1,12 @@
*_wire.txt
*_wire.bin
.DS_Store
**/.build
**/Packages
/*.xcodeproj
**/xcuserdata/
**/xcshareddata/
**/.swiftpm/
*.o
*.o.d
*.class
@@ -116,3 +122,6 @@ dart/doc/api/
Cargo.lock
.corpus**
.seed**
grpc/google/
**/Package.resolved
.clangd/**

View File

@@ -22,6 +22,21 @@ conan-linux: &conan-linux
- ./conan/travis/build.sh
if: tag IS present
conan-linux-master: &conan-linux-master
os: linux
dist: xenial
language: python
python: "3.7"
services:
- docker
install:
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/install.sh; fi'
script:
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/build.sh; fi'
branches:
only:
- master
conan-osx: &conan-osx
os: osx
language: generic
@@ -78,7 +93,7 @@ matrix:
env:
matrix:
- BUILD_TYPE=Debug
- BUILD_TYPE=Release CONAN=true
- BUILD_TYPE=Release
before_install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
@@ -97,10 +112,9 @@ matrix:
-DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install
-DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf
-DFLATBUFFERS_CODE_SANITIZE=ON
- cmake --build . -- -j${JOBS}
- cmake --build . --target all --clean-first -- -j${JOBS}
- LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
- bash .travis/check-generate-code.sh
- if [ "$CONAN" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo pip install conan && conan create . flatbuffers/${TRAVIS_BRANCH}@google/testing -s build_type=$BUILD_TYPE -tf conan/test_package; fi
- language: cpp
os: osx
@@ -122,6 +136,8 @@ matrix:
- DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
- bash .travis/check-generate-code.sh
- <<: *conan-linux-master
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
- <<: *conan-linux
env: CONAN_GCC_VERSIONS=4.9 CONAN_DOCKER_IMAGE=conanio/gcc49
- <<: *conan-linux
@@ -132,6 +148,8 @@ matrix:
env: CONAN_GCC_VERSIONS=7 CONAN_DOCKER_IMAGE=conanio/gcc7
- <<: *conan-linux
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
- <<: *conan-linux
env: CONAN_GCC_VERSIONS=9 CONAN_DOCKER_IMAGE=conanio/gcc9
- <<: *conan-linux
env: CONAN_CLANG_VERSIONS=3.9 CONAN_DOCKER_IMAGE=conanio/clang39
- <<: *conan-linux
@@ -140,6 +158,10 @@ matrix:
env: CONAN_CLANG_VERSIONS=5.0 CONAN_DOCKER_IMAGE=conanio/clang50
- <<: *conan-linux
env: CONAN_CLANG_VERSIONS=6.0 CONAN_DOCKER_IMAGE=conanio/clang60
- <<: *conan-linux
env: CONAN_CLANG_VERSIONS=7.0 CONAN_DOCKER_IMAGE=conanio/clang7
- <<: *conan-linux
env: CONAN_CLANG_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/clang8
- <<: *conan-osx
osx_image: xcode7.3
env: CONAN_APPLE_CLANG_VERSIONS=7.3
@@ -153,11 +175,12 @@ matrix:
osx_image: xcode9.4
env: CONAN_APPLE_CLANG_VERSIONS=9.1
- <<: *conan-osx
osx_image: xcode10
osx_image: xcode10.2
env: CONAN_APPLE_CLANG_VERSIONS=10.0
- language: android
sudo: true
dist: trusty
android:
components:
- tools
@@ -171,8 +194,20 @@ matrix:
before_install:
# Output something every 10 minutes or Travis kills the job
- while sleep 540; do echo "=====[ $SECONDS seconds still running ]====="; done &
- git clone https://github.com/urho3d/android-ndk.git $HOME/android-ndk-root
- export ANDROID_NDK_HOME=$HOME/android-ndk-root
# Install the r17c version of the NDK that still so that we can continue to test with gnustl
# and stlport.
- export ANDROID_NDK_HOME=$HOME/android-ndk
- NDK_ZIP=$ANDROID_NDK_HOME/ndk.zip
- mkdir -p $ANDROID_NDK_HOME
- curl -o $NDK_ZIP https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
- unzip -q -d $ANDROID_NDK_HOME $NDK_ZIP
- rm $NDK_ZIP
- mv $ANDROID_NDK_HOME/android-ndk-*/* $ANDROID_NDK_HOME
- rmdir $ANDROID_NDK_HOME/android-ndk-*
- export CMAKE=$(which cmake)
# libc required for prebuilt llvm toolchain the NDK r17c.
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq libc6; fi
# Setup environment for Linux build which is required to build the sample.
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi

View File

@@ -15,10 +15,15 @@
# limitations under the License.
set -e
# build flatc on debian once to speed up the test loop below
docker build -t build_flatc_debian_stretch -f tests/docker/Dockerfile.testing.build_flatc_debian_stretch .
BUILD_CONTAINER_ID=$(docker create --read-only build_flatc_debian_stretch)
docker cp ${BUILD_CONTAINER_ID}:/code/flatc flatc_debian_stretch
docker build -t build_cpp_image -f tests/docker/Dockerfile.testing.cpp.debian_buster .
# Run tests with sanitizers (--cap-add SYS_PTRACE), both GCC and Clang.
cpp_test_args="--cap-add SYS_PTRACE build_cpp_image sh ./tests/docker/cpp_test.run.sh Debug"
docker run --rm $cpp_test_args
docker run --rm --env CC=/usr/bin/clang --env CXX=/usr/bin/clang++ $cpp_test_args
# Build flatc on debian once to speed up the test loop below.
docker run --name flatc_container build_cpp_image sh ./tests/docker/build_flatc.run.sh Debug
# All dependent dockers refer to 'flatc_debian_stretch'.
docker cp flatc_container:/flatbuffers/flatc flatc_debian_stretch
for f in $(ls tests/docker/languages | sort)
do

View File

@@ -21,6 +21,8 @@ cd ..
# TODO: Linux and macos builds produce differences here for some reason.
git checkout HEAD -- tests/monster_test.bfbs
git checkout HEAD -- tests/arrays_test.bfbs
git checkout HEAD -- samples/monster.bfbs
if ! git diff --quiet; then
echo >&2

148
BUILD
View File

@@ -1,34 +1,22 @@
licenses(["notice"])
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
package(
default_visibility = ["//visibility:public"],
features = [
"-layering_check",
"-parse_headers",
],
)
exports_files([
"LICENSE",
])
load(":build_defs.bzl", "flatbuffer_cc_library")
# Public flatc library to compile flatbuffer files at runtime.
cc_library(
name = "flatbuffers",
srcs = [
"src/code_generators.cpp",
"src/idl_gen_fbs.cpp",
"src/idl_gen_general.cpp",
"src/idl_gen_text.cpp",
"src/idl_parser.cpp",
"src/reflection.cpp",
"src/util.cpp",
],
hdrs = [":public_headers"],
includes = ["include/"],
hdrs = ["//:public_headers"],
linkstatic = 1,
strip_include_prefix = "/include",
deps = ["//src:flatbuffers"],
)
# Public C++ headers for the Flatbuffers library.
@@ -44,6 +32,7 @@ filegroup(
"include/flatbuffers/minireflect.h",
"include/flatbuffers/reflection.h",
"include/flatbuffers/reflection_generated.h",
"include/flatbuffers/registry.h",
"include/flatbuffers/stl_emulation.h",
"include/flatbuffers/util.h",
],
@@ -52,60 +41,29 @@ filegroup(
# Public flatc compiler library.
cc_library(
name = "flatc_library",
srcs = [
"src/code_generators.cpp",
"src/flatc.cpp",
"src/idl_gen_fbs.cpp",
"src/idl_parser.cpp",
"src/reflection.cpp",
"src/util.cpp",
],
hdrs = [
"include/flatbuffers/flatc.h",
":public_headers",
],
includes = [
"grpc/",
"include/",
linkstatic = 1,
deps = [
"//src:flatc_library",
],
)
# Public flatc compiler.
cc_binary(
name = "flatc",
srcs = [
"grpc/src/compiler/config.h",
"grpc/src/compiler/cpp_generator.cc",
"grpc/src/compiler/cpp_generator.h",
"grpc/src/compiler/go_generator.cc",
"grpc/src/compiler/go_generator.h",
"grpc/src/compiler/java_generator.cc",
"grpc/src/compiler/java_generator.h",
"grpc/src/compiler/schema_interface.h",
"src/flatc_main.cpp",
"src/idl_gen_cpp.cpp",
"src/idl_gen_dart.cpp",
"src/idl_gen_general.cpp",
"src/idl_gen_go.cpp",
"src/idl_gen_grpc.cpp",
"src/idl_gen_js_ts.cpp",
"src/idl_gen_json_schema.cpp",
"src/idl_gen_lobster.cpp",
"src/idl_gen_lua.cpp",
"src/idl_gen_php.cpp",
"src/idl_gen_python.cpp",
"src/idl_gen_rust.cpp",
"src/idl_gen_text.cpp",
],
includes = [
"grpc/",
"include/",
],
deps = [
":flatc_library",
"//src:flatc",
],
)
filegroup(
name = "flatc_headers",
srcs = [
"include/flatbuffers/flatc.h",
],
visibility = ["//:__subpackages__"],
)
# Library used by flatbuffer_cc_library rules.
cc_library(
name = "runtime_cc",
hdrs = [
@@ -115,72 +73,6 @@ cc_library(
"include/flatbuffers/stl_emulation.h",
"include/flatbuffers/util.h",
],
includes = ["include/"],
linkstatic = 1,
)
# Test binary.
cc_test(
name = "flatbuffers_test",
testonly = 1,
srcs = [
"include/flatbuffers/minireflect.h",
"include/flatbuffers/registry.h",
"src/code_generators.cpp",
"src/idl_gen_fbs.cpp",
"src/idl_gen_general.cpp",
"src/idl_gen_text.cpp",
"src/idl_parser.cpp",
"src/reflection.cpp",
"src/util.cpp",
"tests/namespace_test/namespace_test1_generated.h",
"tests/namespace_test/namespace_test2_generated.h",
"tests/test.cpp",
"tests/test_assert.cpp",
"tests/test_assert.h",
"tests/test_builder.cpp",
"tests/test_builder.h",
"tests/union_vector/union_vector_generated.h",
":public_headers",
],
copts = [
"-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE",
"-DBAZEL_TEST_DATA_PATH",
],
data = [
":tests/include_test/include_test1.fbs",
":tests/include_test/sub/include_test2.fbs",
":tests/monster_test.bfbs",
":tests/monster_test.fbs",
":tests/monsterdata_test.golden",
":tests/prototest/imported.proto",
":tests/prototest/test.golden",
":tests/prototest/test.proto",
":tests/prototest/test_union.golden",
":tests/unicode_test.json",
":tests/union_vector/union_vector.fbs",
":tests/union_vector/union_vector.json",
],
includes = ["include/"],
deps = [
":monster_extra_cc_fbs",
":monster_test_cc_fbs",
],
)
# Test bzl rules
flatbuffer_cc_library(
name = "monster_test_cc_fbs",
srcs = ["tests/monster_test.fbs"],
include_paths = ["tests/include_test"],
includes = [
"tests/include_test/include_test1.fbs",
"tests/include_test/sub/include_test2.fbs",
],
)
flatbuffer_cc_library(
name = "monster_extra_cc_fbs",
srcs = ["tests/monster_extra.fbs"],
strip_include_prefix = "/include",
)

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 2.8.12)
# generate compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
include(CheckCXXSymbolExists)
@@ -13,6 +13,8 @@ option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library"
ON)
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
ON)
option(FLATBUFFERS_STATIC_FLATC "Build flatbuffers compiler with -static flag"
OFF)
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
option(FLATBUFFERS_BUILD_SHAREDLIB
@@ -29,6 +31,13 @@ option(FLATBUFFERS_PACKAGE_REDHAT
option(FLATBUFFERS_PACKAGE_DEBIAN
"Build an deb using the 'package' target."
OFF)
option(FLATBUFFERS_BUILD_CPP17
"Enable the build of c++17 test target. \"
Requirements: Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher."
OFF)
option(FLATBUFFERS_BUILD_LEGACY
"Run C++ code generator with '--cpp-std c++0x' switch."
OFF)
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
message(WARNING
@@ -42,18 +51,23 @@ if(DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
endif()
# Auto-detect locale-narrow 'strtod_l' function.
# Auto-detect locale-narrow 'strtod_l' and 'strtoull_l' functions.
if(NOT DEFINED FLATBUFFERS_LOCALE_INDEPENDENT)
set(FLATBUFFERS_LOCALE_INDEPENDENT 0)
if(MSVC)
check_cxx_symbol_exists(_strtof_l stdlib.h FLATBUFFERS_LOCALE_INDEPENDENT)
check_cxx_symbol_exists(_strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
check_cxx_symbol_exists(_strtoui64_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
else()
check_cxx_symbol_exists(strtof_l stdlib.h FLATBUFFERS_LOCALE_INDEPENDENT)
check_cxx_symbol_exists(strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
check_cxx_symbol_exists(strtoull_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
endif()
if(FLATBUFFERS_HAS_STRTOF_L AND FLATBUFFERS_HAS_STRTOULL_L)
set(FLATBUFFERS_LOCALE_INDEPENDENT 1)
endif()
endif()
add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=$<BOOL:${FLATBUFFERS_LOCALE_INDEPENDENT}>)
set(FlatBuffers_Library_SRCS
include/flatbuffers/code_generators.h
include/flatbuffers/base.h
include/flatbuffers/flatbuffers.h
include/flatbuffers/hash.h
@@ -65,7 +79,6 @@ set(FlatBuffers_Library_SRCS
include/flatbuffers/flexbuffers.h
include/flatbuffers/registry.h
include/flatbuffers/minireflect.h
src/code_generators.cpp
src/idl_parser.cpp
src/idl_gen_text.cpp
src/reflection.cpp
@@ -75,9 +88,11 @@ set(FlatBuffers_Library_SRCS
set(FlatBuffers_Compiler_SRCS
${FlatBuffers_Library_SRCS}
src/idl_gen_cpp.cpp
src/idl_gen_csharp.cpp
src/idl_gen_dart.cpp
src/idl_gen_general.cpp
src/idl_gen_kotlin.cpp
src/idl_gen_go.cpp
src/idl_gen_java.cpp
src/idl_gen_js_ts.cpp
src/idl_gen_php.cpp
src/idl_gen_python.cpp
@@ -87,8 +102,11 @@ set(FlatBuffers_Compiler_SRCS
src/idl_gen_fbs.cpp
src/idl_gen_grpc.cpp
src/idl_gen_json_schema.cpp
src/idl_gen_swift.cpp
src/flatc.cpp
src/flatc_main.cpp
include/flatbuffers/code_generators.h
src/code_generators.cpp
grpc/src/compiler/schema_interface.h
grpc/src/compiler/cpp_generator.h
grpc/src/compiler/cpp_generator.cc
@@ -96,6 +114,11 @@ set(FlatBuffers_Compiler_SRCS
grpc/src/compiler/go_generator.cc
grpc/src/compiler/java_generator.h
grpc/src/compiler/java_generator.cc
grpc/src/compiler/python_generator.h
grpc/src/compiler/python_private_generator.h
grpc/src/compiler/python_generator.cc
grpc/src/compiler/swift_generator.h
grpc/src/compiler/swift_generator.cc
)
set(FlatHash_SRCS
@@ -111,8 +134,35 @@ set(FlatBuffers_Tests_SRCS
tests/test_assert.cpp
tests/test_builder.h
tests/test_builder.cpp
tests/native_type_test_impl.h
tests/native_type_test_impl.cpp
include/flatbuffers/code_generators.h
src/code_generators.cpp
# file generate by running compiler on tests/monster_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
# file generate by running compiler on namespace_test/namespace_test1.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test1_generated.h
${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test2_generated.h
# file generate by running compiler on union_vector/union_vector.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/union_vector/union_vector_generated.h
# file generate by running compiler on tests/arrays_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/arrays_test_generated.h
# file generate by running compiler on tests/native_type_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/native_type_test_generated.h
# file generate by running compiler on tests/monster_extra.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_extra_generated.h
# file generate by running compiler on tests/monster_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_bfbs_generated.h
)
set(FlatBuffers_Tests_CPP17_SRCS
${FlatBuffers_Library_SRCS}
tests/test_assert.h
tests/test_assert.cpp
tests/cpp17/test_cpp17.cpp
# file generate by running compiler on tests/monster_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/cpp17/generated_cpp17/monster_test_generated.h
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
)
set(FlatBuffers_Sample_Binary_SRCS
@@ -131,7 +181,6 @@ set(FlatBuffers_Sample_Text_SRCS
set(FlatBuffers_Sample_BFBS_SRCS
${FlatBuffers_Library_SRCS}
src/idl_gen_general.cpp
samples/sample_bfbs.cpp
# file generated by running compiler on samples/monster.fbs
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
@@ -140,6 +189,8 @@ set(FlatBuffers_Sample_BFBS_SRCS
set(FlatBuffers_GRPCTest_SRCS
include/flatbuffers/flatbuffers.h
include/flatbuffers/grpc.h
include/flatbuffers/util.h
src/util.cpp
tests/monster_test.grpc.fb.h
tests/test_assert.h
tests/test_builder.h
@@ -148,8 +199,8 @@ set(FlatBuffers_GRPCTest_SRCS
tests/test_builder.cpp
grpc/tests/grpctest.cpp
grpc/tests/message_builder_test.cpp
# file generated by running compiler on samples/monster.fbs
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
# file generate by running compiler on tests/monster_test.fbs
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
)
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
@@ -226,23 +277,28 @@ if(FLATBUFFERS_CODE_COVERAGE)
endif()
function(add_fsanitize_to_target _target _sanitizer)
# FLATBUFFERS_CODE_SANITIZE: boolean {ON,OFF,YES,NO} or string with list of sanitizer.
# List of sanitizer is string starts with '=': "=address,undefined,thread,memory".
if((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") OR
((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
)
set(_sanitizer_flags "=address,undefined")
if(_sanitizer MATCHES "=.*")
# override default by user-defined sanitizer list
set(_sanitizer_flags ${_sanitizer})
if(WIN32)
target_compile_definitions(${_target} PRIVATE FLATBUFFERS_MEMORY_LEAK_TRACKING)
message(STATUS "Sanitizer MSVC::_CrtDumpMemoryLeaks added to ${_target}")
else()
# FLATBUFFERS_CODE_SANITIZE: boolean {ON,OFF,YES,NO} or string with list of sanitizer.
# List of sanitizer is string starts with '=': "=address,undefined,thread,memory".
if((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") OR
((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
)
set(_sanitizer_flags "=address,undefined")
if(_sanitizer MATCHES "=.*")
# override default by user-defined sanitizer list
set(_sanitizer_flags ${_sanitizer})
endif()
target_compile_options(${_target} PRIVATE
-g -fsigned-char -fno-omit-frame-pointer
"-fsanitize${_sanitizer_flags}")
target_link_libraries(${_target} PRIVATE
"-fsanitize${_sanitizer_flags}")
set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ON)
message(STATUS "Sanitizer ${_sanitizer_flags} added to ${_target}")
endif()
target_compile_options(${_target} PRIVATE
-g -fsigned-char -fno-omit-frame-pointer
"-fsanitize${_sanitizer_flags}")
target_link_libraries(${_target} PRIVATE
"-fsanitize${_sanitizer_flags}")
set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ON)
message(STATUS "Sanitizer ${_sanitizer_flags} added to ${_target}")
endif()
endfunction()
@@ -256,7 +312,7 @@ include_directories(grpc)
if(FLATBUFFERS_BUILD_FLATLIB)
add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
# CMake > 2.8.11: Attach header directory for when build via add_subdirectory().
# Attach header directory for when build via add_subdirectory().
target_include_directories(flatbuffers INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
target_compile_options(flatbuffers PRIVATE "${FLATBUFFERS_PRIVATE_CXX_FLAGS}")
@@ -275,6 +331,9 @@ if(FLATBUFFERS_BUILD_FLATC)
# Make flatc.exe not depend on runtime dlls for easy distribution.
target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>)
endif()
if(FLATBUFFERS_STATIC_FLATC AND NOT MSVC)
target_link_libraries(flatc PRIVATE -static)
endif()
endif()
if(FLATBUFFERS_BUILD_FLATHASH)
@@ -289,57 +348,148 @@ if(FLATBUFFERS_BUILD_SHAREDLIB)
# - minor updated when there are additions in API/ABI
# - major (ABI number) updated when there are changes in ABI (or removals)
set(FlatBuffers_Library_SONAME_MAJOR "1")
set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.11.0")
set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.12.0")
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers
SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}"
VERSION "${FlatBuffers_Library_SONAME_FULL}")
endif()
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
# Global list of generated files.
# Use the global property to be independent of PARENT_SCOPE.
set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
function(get_generated_output generated_files)
get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
set(${generated_files} ${tmp} PARENT_SCOPE)
endfunction(get_generated_output)
function(register_generated_output file_name)
get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
list(APPEND tmp ${file_name})
set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS ${tmp})
endfunction(register_generated_output)
function(compile_flatbuffers_schema_to_cpp_opt SRC_FBS OPT)
if(FLATBUFFERS_BUILD_LEGACY)
set(OPT ${OPT};--cpp-std c++0x)
else()
# --cpp-std is defined by flatc default settings.
endif()
message(STATUS "`${SRC_FBS}`: add generation of C++ code with '${OPT}'")
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
add_custom_command(
OUTPUT ${GEN_HEADER}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
--gen-object-api --gen-compare -o "${SRC_FBS_DIR}"
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
--cpp --gen-mutable --gen-object-api --reflect-names
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
--reflect-names
${OPT}
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
-o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
DEPENDS flatc)
DEPENDS flatc
COMMENT "Run generation: '${GEN_HEADER}'")
register_generated_output(${GEN_HEADER})
endfunction()
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
compile_flatbuffers_schema_to_cpp_opt(${SRC_FBS} "--no-includes;--gen-compare")
endfunction()
function(compile_flatbuffers_schema_to_binary SRC_FBS)
message(STATUS "`${SRC_FBS}`: add generation of binary (.bfbs) schema")
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
# For details about flags see generate_code.bat(sh)
add_custom_command(
OUTPUT ${GEN_BINARY_SCHEMA}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -b --schema -o "${SRC_FBS_DIR}"
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
-b --schema --bfbs-comments --bfbs-builtins
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
-o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
DEPENDS flatc)
DEPENDS flatc
COMMENT "Run generation: '${GEN_BINARY_SCHEMA}'")
register_generated_output(${GEN_BINARY_SCHEMA})
endfunction()
function(compile_flatbuffers_schema_to_embedded_binary SRC_FBS OPT)
if(FLATBUFFERS_BUILD_LEGACY)
set(OPT ${OPT};--cpp-std c++0x)
else()
# --cpp-std is defined by flatc default settings.
endif()
message(STATUS "`${SRC_FBS}`: add generation of C++ embedded binary schema code with '${OPT}'")
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
string(REGEX REPLACE "\\.fbs$" "_bfbs_generated.h" GEN_BFBS_HEADER ${SRC_FBS})
# For details about flags see generate_code.bat(sh)
add_custom_command(
OUTPUT ${GEN_BFBS_HEADER}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
--cpp --gen-mutable --gen-object-api --reflect-names
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
${OPT}
--bfbs-comments --bfbs-builtins --bfbs-gen-embed
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
-o "${SRC_FBS_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
DEPENDS flatc
COMMENT "Run generation: '${GEN_BFBS_HEADER}'")
register_generated_output(${GEN_BFBS_HEADER})
endfunction()
if(FLATBUFFERS_BUILD_TESTS)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/samples" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
# TODO Add (monster_test.fbs monsterdata_test.json)->monsterdata_test.mon
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
compile_flatbuffers_schema_to_binary(tests/monster_test.fbs)
compile_flatbuffers_schema_to_cpp(tests/namespace_test/namespace_test1.fbs)
compile_flatbuffers_schema_to_cpp(tests/namespace_test/namespace_test2.fbs)
compile_flatbuffers_schema_to_cpp(tests/union_vector/union_vector.fbs)
compile_flatbuffers_schema_to_cpp_opt(tests/native_type_test.fbs "")
compile_flatbuffers_schema_to_cpp_opt(tests/arrays_test.fbs "--scoped-enums;--gen-compare")
compile_flatbuffers_schema_to_binary(tests/arrays_test.fbs)
compile_flatbuffers_schema_to_embedded_binary(tests/monster_test.fbs "--no-includes;--gen-compare")
if(NOT (MSVC AND (MSVC_VERSION LESS 1900)))
compile_flatbuffers_schema_to_cpp(tests/monster_extra.fbs) # Test floating-point NAN/INF.
endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
add_executable(flattests ${FlatBuffers_Tests_SRCS})
add_dependencies(flattests generated_code)
set_property(TARGET flattests
PROPERTY COMPILE_DEFINITIONS FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1)
if(FLATBUFFERS_CODE_SANITIZE)
if(WIN32)
target_compile_definitions(flattests PRIVATE FLATBUFFERS_MEMORY_LEAK_TRACKING)
message(STATUS "Sanitizer MSVC::_CrtDumpMemoryLeaks added to flattests")
else()
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
endif()
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
endif()
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
compile_flatbuffers_schema_to_binary(samples/monster.fbs)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
add_executable(flatsamplebinary ${FlatBuffers_Sample_Binary_SRCS})
add_dependencies(flatsamplebinary generated_code)
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
add_dependencies(flatsampletext generated_code)
add_executable(flatsamplebfbs ${FlatBuffers_Sample_BFBS_SRCS})
add_dependencies(flatsamplebfbs generated_code)
if(FLATBUFFERS_BUILD_CPP17)
# Don't generate header for flattests_cpp17 target.
# This target uses "generated_cpp17/monster_test_generated.h"
# produced by direct call of generate_code.bat(sh) script.
add_executable(flattests_cpp17 ${FlatBuffers_Tests_CPP17_SRCS})
add_dependencies(flattests_cpp17 generated_code)
target_compile_features(flattests_cpp17 PRIVATE cxx_std_17)
target_compile_definitions(flattests_cpp17 PRIVATE
FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1
)
if(FLATBUFFERS_CODE_SANITIZE)
add_fsanitize_to_target(flattests_cpp17 ${FLATBUFFERS_CODE_SANITIZE})
endif()
endif(FLATBUFFERS_BUILD_CPP17)
endif()
if(FLATBUFFERS_BUILD_GRPCTEST)
@@ -356,7 +506,12 @@ if(FLATBUFFERS_BUILD_GRPCTEST)
INCLUDE_DIRECTORIES(${PROTOBUF_DOWNLOAD_PATH}/src)
LINK_DIRECTORIES(${GRPC_INSTALL_PATH}/lib)
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
target_link_libraries(grpctest grpc++_unsecure grpc_unsecure gpr pthread dl)
add_dependencies(grpctest generated_code)
target_link_libraries(grpctest PRIVATE grpc++_unsecure grpc_unsecure gpr pthread dl)
if(FLATBUFFERS_CODE_SANITIZE AND NOT WIN32)
# GRPC test has problems with alignment and will fail under ASAN/UBSAN.
# add_fsanitize_to_target(grpctest ${FLATBUFFERS_CODE_SANITIZE})
endif()
endif()
include(CMake/Version.cmake)
@@ -439,14 +594,25 @@ endif()
if(FLATBUFFERS_BUILD_TESTS)
enable_testing()
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION
"${CMAKE_CURRENT_BINARY_DIR}")
add_test(NAME flattests COMMAND flattests)
if(FLATBUFFERS_BUILD_CPP17)
add_test(NAME flattests_cpp17 COMMAND flattests_cpp17)
endif()
if(FLATBUFFERS_BUILD_GRPCTEST)
add_test(NAME grpctest COMMAND grpctest)
endif()
endif()
# This target is sync-barrier.
# Other generate-dependent targets can depend on 'generated_code' only.
get_generated_output(fbs_generated)
if(fbs_generated)
# message(STATUS "Add generated_code target with files:${fbs_generated}")
add_custom_target(generated_code
DEPENDS ${fbs_generated}
COMMENT "All generated files were updated.")
endif()
include(CMake/BuildFlatBuffers.cmake)
if(UNIX)

View File

@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2014 Google Inc.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -4,11 +4,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "io_bazel_rules_go",
sha256 = "492c3ac68ed9dcf527a07e6a1b2dcbf199c6bf8b35517951467ac32e421c06c1",
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.17.0/rules_go-0.17.0.tar.gz"],
urls = [
"https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/v0.20.3/rules_go-v0.20.3.tar.gz",
"https://github.com/bazelbuild/rules_go/releases/download/v0.20.3/rules_go-v0.20.3.tar.gz",
],
sha256 = "e88471aea3a3a4f19ec1310a55ba94772d087e9ce46e41ae38ecebe17935de7b",
)
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()

View File

@@ -36,8 +36,7 @@ LOCAL_MODULE := flatbuffers_extra
LOCAL_SRC_FILES := src/idl_parser.cpp \
src/idl_gen_text.cpp \
src/reflection.cpp \
src/util.cpp \
src/code_generators.cpp
src/util.cpp
LOCAL_STATIC_LIBRARIES := flatbuffers
LOCAL_ARM_MODE := arm
include $(BUILD_STATIC_LIBRARY)
@@ -51,8 +50,10 @@ LOCAL_SRC_FILES := android/jni/main.cpp \
tests/test_builder.h \
tests/test_assert.cpp \
tests/test_builder.cpp \
tests/native_type_test_impl.h \
tests/native_type_test_impl.cpp \
src/idl_gen_fbs.cpp \
src/idl_gen_general.cpp
src/code_generators.cpp
LOCAL_LDLIBS := -llog -landroid -latomic
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra
LOCAL_ARM_MODE := arm

View File

@@ -18,9 +18,6 @@
extern int main(int argc, char **argv);
void android_main(android_app *app) {
// Make sure glue isn't stripped.
app_dummy();
void android_main(android_app *) {
main(0, NULL);
}

View File

@@ -2,23 +2,36 @@ branches:
only:
- master
os: Visual Studio 2015
environment:
global:
# Workaround for https://github.com/conda/conda-build/issues/636
PYTHONIOENCODING: UTF-8
CONDA_INSTALL_LOCN: "C:\\Miniconda35-x64"
CMAKE_OPTIONS: ""
CPP_TEST_OPTIONS: ""
matrix:
- CMAKE_VS_VERSION: "10 2010"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_VS_VERSION: "10 2010"
CMAKE_OPTIONS: "-DFLATBUFFERS_BUILD_LEGACY=1"
CPP_TEST_OPTIONS: "--std-cpp c++0x"
MONSTER_EXTRA: "skip"
- CMAKE_VS_VERSION: "12 2013"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_VS_VERSION: "12 2013"
MONSTER_EXTRA: "skip"
- CMAKE_VS_VERSION: "14 2015"
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_VS_VERSION: "14 2015"
MONSTER_EXTRA: ""
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_VS_VERSION: "15 2017"
MONSTER_EXTRA: ""
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
CMAKE_VS_VERSION: "16 2019"
MONSTER_EXTRA: ""
platform:
@@ -31,9 +44,11 @@ configuration:
before_build:
- set MONSTER_EXTRA=%MONSTER_EXTRA%
- cmake -G"Visual Studio %CMAKE_VS_VERSION%" -DFLATBUFFERS_CODE_SANITIZE=1 .
- cmake . -G"Visual Studio %CMAKE_VS_VERSION%" -DFLATBUFFERS_CODE_SANITIZE=1 %CMAKE_OPTIONS%
# This cuts down on a lot of noise generated by xamarin warnings.
- del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
- if exist "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
- if exist "C:\Program Files (x86)\MSBuild\15.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\15.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
- if exist "C:\Program Files (x86)\MSBuild\16.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\16.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
build:
project: ALL_BUILD.vcxproj
@@ -55,7 +70,7 @@ test_script:
- call .appveyor\check-generate-code.bat -b %CONFIGURATION%
- "cd tests"
- rem "Building all code"
- generate_code.bat -b %CONFIGURATION%
- generate_code.bat -b %CONFIGURATION% %CPP_TEST_OPTIONS%
- 7z a GeneratedMyGameCode.zip MyGame\
- rem "---------------- C++ -----------------"
- "cd .."
@@ -90,6 +105,11 @@ test_script:
# Have to compile this here rather than in "build" above because AppVeyor only
# supports building one project??
- "cd FlatBuffers.Test"
- "copy ..\\monsterdata_test.mon Resources\\"
- "copy ..\\monsterdata_test.json Resources\\"
- "dotnet new sln"
- "dotnet sln add FlatBuffers.Test.csproj"
- "nuget restore"
- "msbuild.exe /property:Configuration=Release;OutputPath=tempcs /verbosity:minimal FlatBuffers.Test.csproj"
- "tempcs\\FlatBuffers.Test.exe"
# Run tests with UNSAFE_BYTEBUFFER

View File

@@ -5,6 +5,8 @@
Rules for building C++ flatbuffers with Bazel.
"""
load("@rules_cc//cc:defs.bzl", "cc_library")
flatc_path = "@com_github_google_flatbuffers//:flatc"
DEFAULT_INCLUDE_PATHS = [
@@ -32,7 +34,9 @@ def flatbuffer_library_public(
include_paths = DEFAULT_INCLUDE_PATHS,
flatc_args = DEFAULT_FLATC_ARGS,
reflection_name = "",
reflection_visiblity = None,
reflection_visibility = None,
compatible_with = None,
restricted_to = None,
output_to_bindir = False):
"""Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
@@ -48,7 +52,12 @@ def flatbuffer_library_public(
flatc_args: Optional, list of additional arguments to pass to flatc.
reflection_name: Optional, if set this will generate the flatbuffer
reflection binaries for the schemas.
reflection_visiblity: The visibility of the generated reflection Fileset.
reflection_visibility: The visibility of the generated reflection Fileset.
output_to_bindir: Passed to genrule for output to bin directory.
compatible_with: Optional, The list of environments this rule can be
built for, in addition to default-supported environments.
restricted_to: Optional, The list of environments this rule can be built
for, instead of default-supported environments.
output_to_bindir: Passed to genrule for output to bin directory.
@@ -82,6 +91,8 @@ def flatbuffer_library_public(
output_to_bindir = output_to_bindir,
tools = [flatc_path],
cmd = genrule_cmd,
compatible_with = compatible_with,
restricted_to = restricted_to,
message = "Generating flatbuffer files for %s:" % (name),
)
if reflection_name:
@@ -107,16 +118,17 @@ def flatbuffer_library_public(
outs = reflection_outs,
output_to_bindir = output_to_bindir,
tools = [flatc_path],
compatible_with = compatible_with,
restricted_to = restricted_to,
cmd = reflection_genrule_cmd,
message = "Generating flatbuffer reflection binary for %s:" % (name),
)
native.Fileset(
name = reflection_name,
out = "%s_out" % reflection_name,
entries = [
native.FilesetEntry(files = reflection_outs),
],
visibility = reflection_visiblity,
native.filegroup(
name = "%s_out" % reflection_name,
srcs = reflection_outs,
visibility = reflection_visibility,
compatible_with = compatible_with,
restricted_to = restricted_to,
)
def flatbuffer_cc_library(
@@ -128,6 +140,8 @@ def flatbuffer_cc_library(
include_paths = DEFAULT_INCLUDE_PATHS,
flatc_args = DEFAULT_FLATC_ARGS,
visibility = None,
compatible_with = None,
restricted_to = None,
srcs_filegroup_visibility = None,
gen_reflections = False):
'''A cc_library with the generated reader/writers for the given flatbuffer definitions.
@@ -151,6 +165,10 @@ def flatbuffer_cc_library(
By default, use the value of the visibility parameter above.
gen_reflections: Optional, if true this will generate the flatbuffer
reflection binaries for the schemas.
compatible_with: Optional, The list of environments this rule can be built
for, in addition to default-supported environments.
restricted_to: Optional, The list of environments this rule can be built
for, instead of default-supported environments.
This produces:
filegroup([name]_srcs): all generated .h files.
@@ -206,10 +224,12 @@ def flatbuffer_cc_library(
includes = includes,
include_paths = include_paths,
flatc_args = flatc_args,
compatible_with = compatible_with,
restricted_to = restricted_to,
reflection_name = reflection_name,
reflection_visiblity = visibility,
reflection_visibility = visibility,
)
native.cc_library(
cc_library(
name = name,
hdrs = [
":" + srcs_lib,
@@ -224,6 +244,8 @@ def flatbuffer_cc_library(
"@com_github_google_flatbuffers//:runtime_cc",
],
includes = [],
compatible_with = compatible_with,
restricted_to = restricted_to,
linkstatic = 1,
visibility = visibility,
)
@@ -233,5 +255,7 @@ def flatbuffer_cc_library(
native.filegroup(
name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
srcs = srcs,
compatible_with = compatible_with,
restricted_to = restricted_to,
visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
)

View File

@@ -492,7 +492,7 @@ class Builder {
/// Write the given list of 64-bit float [values].
int writeListFloat64(List<double> values) {
_ensureNoVTable();
_prepare(4, 1 + (2 * values.length));
_prepare(_sizeofFloat64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
_setUint32AtTail(_buf, tail, values.length);
@@ -522,7 +522,7 @@ class Builder {
/// Write the given list of signed 64-bit integer [values].
int writeListInt64(List<int> values) {
_ensureNoVTable();
_prepare(_sizeofUint32, 2 * values.length);
_prepare(_sizeofInt64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
_setUint32AtTail(_buf, tail, values.length);
@@ -537,7 +537,7 @@ class Builder {
/// Write the given list of signed 64-bit integer [values].
int writeListUint64(List<int> values) {
_ensureNoVTable();
_prepare(_sizeofUint32, 2 * values.length);
_prepare(_sizeofUint64, values.length, additionalBytes: _sizeofUint32);
final int result = _tail;
int tail = _tail;
_setUint32AtTail(_buf, tail, values.length);

View File

@@ -1,5 +1,5 @@
name: flat_buffers
version: 1.11.0
version: 1.12.0
description: >
FlatBuffers reading and writing library for Dart. Use the flatc compiler to
generate Dart classes for a FlatBuffers schema, and this library to assist with

View File

@@ -11,6 +11,7 @@ import 'include_test2_my_game.example_generated.dart';
import './monster_test_my_game_generated.dart' as my_game;
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
/// Composite components of Monster color.
class Color {
final int value;
const Color._(this.value);
@@ -26,7 +27,12 @@ class Color {
static bool containsValue(int value) => values.containsKey(value);
static const Color Red = const Color._(1);
/// \brief color Green
/// Green is bit_flag with value (1u << 1)
static const Color Green = const Color._(2);
/// \brief color Blue (1u << 3)
static const Color Blue = const Color._(8);
static get values => {1: Red,2: Green,8: Blue,};
@@ -46,7 +52,48 @@ class _ColorReader extends fb.Reader<Color> {
@override
Color read(fb.BufferContext bc, int offset) =>
new Color.fromValue(const fb.Int8Reader().read(bc, offset));
new Color.fromValue(const fb.Uint8Reader().read(bc, offset));
}
class Race {
final int value;
const Race._(this.value);
factory Race.fromValue(int value) {
if (value == null) value = 0;
if (!values.containsKey(value)) {
throw new StateError('Invalid value $value for bit flag enum Race');
}
return values[value];
}
static const int minValue = -1;
static const int maxValue = 2;
static bool containsValue(int value) => values.containsKey(value);
static const Race None = const Race._(-1);
static const Race Human = const Race._(0);
static const Race Dwarf = const Race._(1);
static const Race Elf = const Race._(2);
static get values => {-1: None,0: Human,1: Dwarf,2: Elf,};
static const fb.Reader<Race> reader = const _RaceReader();
@override
String toString() {
return 'Race{value: $value}';
}
}
class _RaceReader extends fb.Reader<Race> {
const _RaceReader();
@override
int get size => 1;
@override
Race read(fb.BufferContext bc, int offset) =>
new Race.fromValue(const fb.Int8Reader().read(bc, offset));
}
class AnyTypeId {
@@ -108,9 +155,9 @@ class AnyUniqueAliasesTypeId {
static const AnyUniqueAliasesTypeId NONE = const AnyUniqueAliasesTypeId._(0);
static const AnyUniqueAliasesTypeId M = const AnyUniqueAliasesTypeId._(1);
static const AnyUniqueAliasesTypeId T = const AnyUniqueAliasesTypeId._(2);
static const AnyUniqueAliasesTypeId TS = const AnyUniqueAliasesTypeId._(2);
static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
static get values => {0: NONE,1: M,2: T,3: M2,};
static get values => {0: NONE,1: M,2: TS,3: M2,};
static const fb.Reader<AnyUniqueAliasesTypeId> reader = const _AnyUniqueAliasesTypeIdReader();
@@ -259,7 +306,7 @@ class TestSimpleTableWithEnum {
final fb.BufferContext _bc;
final int _bcOffset;
Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 2));
Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 4, 2));
@override
String toString() {
@@ -287,7 +334,7 @@ class TestSimpleTableWithEnumBuilder {
}
int addColor(Color color) {
fbBuilder.addInt8(0, color?.value);
fbBuilder.addUint8(0, color?.value);
return fbBuilder.offset;
}
@@ -311,7 +358,7 @@ class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder {
assert(fbBuilder != null);
fbBuilder.startTable();
fbBuilder.addInt8(0, _color?.value);
fbBuilder.addUint8(0, _color?.value);
return fbBuilder.endTable();
}
@@ -335,7 +382,7 @@ class Vec3 {
double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
Color get test2 => new Color.fromValue(const fb.Int8Reader().read(_bc, _bcOffset + 24));
Color get test2 => new Color.fromValue(const fb.Uint8Reader().read(_bc, _bcOffset + 24));
Test get test3 => Test.reader.read(_bc, _bcOffset + 26);
@override
@@ -366,7 +413,7 @@ class Vec3Builder {
fbBuilder.pad(2);
test3();
fbBuilder.pad(1);
fbBuilder.putInt8(test2?.value);
fbBuilder.putUint8(test2?.value);
fbBuilder.putFloat64(test1);
fbBuilder.pad(4);
fbBuilder.putFloat32(z);
@@ -409,7 +456,7 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder {
fbBuilder.pad(2);
_test3.finish(fbBuilder);
fbBuilder.pad(1);
fbBuilder.putInt8(_test2?.value);
fbBuilder.putUint8(_test2?.value);
fbBuilder.putFloat64(_test1);
fbBuilder.pad(4);
fbBuilder.putFloat32(_z);
@@ -690,7 +737,7 @@ class Monster {
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 8));
Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 16, 8));
AnyTypeId get testType => new AnyTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 18, 0));
dynamic get test {
switch (testType?.value) {
@@ -702,8 +749,8 @@ class Monster {
}
List<Test> get test4 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 22, null);
List<String> get testarrayofstring => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 24, null);
/// an example documentation comment: this will end up in the generated code
/// multiline too
/// an example documentation comment: this will end up in the generated code
/// multiline too
List<Monster> get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGet(_bc, _bcOffset, 26, null);
Monster get enemy => Monster.reader.vTableGet(_bc, _bcOffset, 28, null);
List<int> get testnestedflatbuffer => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 30, null);
@@ -740,7 +787,7 @@ class Monster {
dynamic get anyUnique {
switch (anyUniqueType?.value) {
case 1: return M.reader.vTableGet(_bc, _bcOffset, 92, null);
case 2: return T.reader.vTableGet(_bc, _bcOffset, 92, null);
case 2: return TS.reader.vTableGet(_bc, _bcOffset, 92, null);
case 3: return M2.reader.vTableGet(_bc, _bcOffset, 92, null);
default: return null;
}
@@ -755,10 +802,11 @@ class Monster {
}
}
List<Color> get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGet(_bc, _bcOffset, 98, null);
Race get signedEnum => new Race.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 100, -1));
@override
String toString() {
return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums}';
return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums, signedEnum: $signedEnum}';
}
}
@@ -802,7 +850,7 @@ class MonsterBuilder {
return fbBuilder.offset;
}
int addColor(Color color) {
fbBuilder.addInt8(6, color?.value);
fbBuilder.addUint8(6, color?.value);
return fbBuilder.offset;
}
int addTestType(AnyTypeId testType) {
@@ -969,6 +1017,10 @@ class MonsterBuilder {
fbBuilder.addOffset(47, offset);
return fbBuilder.offset;
}
int addSignedEnum(Race signedEnum) {
fbBuilder.addInt8(48, signedEnum?.value);
return fbBuilder.offset;
}
int finish() {
return fbBuilder.endTable();
@@ -1023,6 +1075,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
final AnyAmbiguousAliasesTypeId _anyAmbiguousType;
final dynamic _anyAmbiguous;
final List<Color> _vectorOfEnums;
final Race _signedEnum;
MonsterObjectBuilder({
Vec3ObjectBuilder pos,
@@ -1072,6 +1125,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
AnyAmbiguousAliasesTypeId anyAmbiguousType,
dynamic anyAmbiguous,
List<Color> vectorOfEnums,
Race signedEnum,
})
: _pos = pos,
_mana = mana,
@@ -1119,7 +1173,8 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
_anyUnique = anyUnique,
_anyAmbiguousType = anyAmbiguousType,
_anyAmbiguous = anyAmbiguous,
_vectorOfEnums = vectorOfEnums;
_vectorOfEnums = vectorOfEnums,
_signedEnum = signedEnum;
/// Finish building, and store into the [fbBuilder].
@override
@@ -1185,7 +1240,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
final int anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
final int anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
final int vectorOfEnumsOffset = _vectorOfEnums?.isNotEmpty == true
? fbBuilder.writeListInt8(_vectorOfEnums.map((f) => f.value))
? fbBuilder.writeListUint8(_vectorOfEnums.map((f) => f.value))
: null;
fbBuilder.startTable();
@@ -1200,7 +1255,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
if (inventoryOffset != null) {
fbBuilder.addOffset(5, inventoryOffset);
}
fbBuilder.addInt8(6, _color?.value);
fbBuilder.addUint8(6, _color?.value);
fbBuilder.addUint8(7, _testType?.value);
if (testOffset != null) {
fbBuilder.addOffset(8, testOffset);
@@ -1288,6 +1343,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
if (vectorOfEnumsOffset != null) {
fbBuilder.addOffset(47, vectorOfEnumsOffset);
}
fbBuilder.addInt8(48, _signedEnum?.value);
return fbBuilder.endTable();
}

View File

@@ -29,6 +29,19 @@ Building should also produce two sample executables, `flatsamplebinary` and
*Note that you MUST be in the root of the FlatBuffers distribution when you
run 'flattests' or `flatsampletext`, or it will fail to load its files.*
## Building with VCPKG
You can download and install flatbuffers using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install flatbuffers
The flatbuffers port in vcpkg is kept up to date by Microsoft team members and community contributors.
If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Building for Android
There is a `flatbuffers/android` directory that contains all you need to build

View File

@@ -3,7 +3,7 @@ Using the schema compiler {#flatbuffers_guide_using_schema_compiler}
Usage:
flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] [ -S ] FILES...
flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] FILES...
[ -- FILES...]
The files are read and parsed in order, and can contain either schemas
@@ -23,6 +23,8 @@ For any schema input files, one or more generators can be specified:
- `--java`, `-j` : Generate Java code.
- `--kotlin`, `-k` : Generate Kotlin code.
- `--csharp`, `-n` : Generate C# code.
- `--go`, `-g` : Generate Go code.
@@ -45,6 +47,8 @@ For any schema input files, one or more generators can be specified:
- `--rust`, `-r` : Generate Rust code.
- `--swift`: Generate Swift code.
For any data input files:
- `--binary`, `-b` : If data is contained in this file, generate a
@@ -92,7 +96,7 @@ Additional options:
statements) use `--no-includes.`
- `--no-includes` : Don't generate include statements for included schemas the
generated file depends on (C++).
generated file depends on (C++ / Python).
- `--gen-mutable` : Generate additional non-const accessors for mutating
FlatBuffers in-place.
@@ -117,6 +121,8 @@ Additional options:
output (by default the case for C++ and JS), all code will end up in
this one file.
- `--cpp-include` : Adds an #include in generated file
- `--cpp-ptr-type T` : Set object API pointer type (default std::unique_ptr)
- `--cpp-str-type T` : Set object API string type (default std::string)
@@ -128,6 +134,11 @@ Additional options:
std::string from Flatbuffers, but (char* + length). This allows efficient
construction of custom string types, including zero-copy construction.
- `--cpp-std CPP_STD` : Generate a C++ code using features of selected C++ standard.
Supported `CPP_STD` values:
* `c++0x` - generate code compatible with old compilers (VS2010).
* `c++11` - use C++11 code generator (default);
- `--object-prefix` : Customise class prefix for C++ object-based API.
- `--object-suffix` : Customise class suffix for C++ object-based API.
@@ -177,6 +188,13 @@ Additional options:
- `--conform-includes PATH` : Include path for the schema given with
`--conform PATH`.
- `--filename-suffix SUFFIX` : The suffix appended to the generated
file names. Default is '_generated'.
- `--filename-ext EXTENSION` : The extension appended to the generated
file names. Default is language-specific (e.g. "h" for C++). This
should not be used when multiple languages are specified.
- `--include-prefix PATH` : Prefix this path to any generated include
statements.
@@ -199,5 +217,8 @@ Additional options:
- `--force-empty` : When serializing from object API representation, force
strings and vectors to empty rather than null.
- `--force-empty-vectors` : When serializing from object API representation, force
vectors to empty rather than null.
NOTE: short-form options for generators are deprecated, use the long form
whenever possible.

View File

@@ -35,7 +35,7 @@ The test code itself is located in
[test.cpp](https://github.com/google/flatbuffers/blob/master/tests/test.cpp).
This test file is built alongside `flatc`. To review how to build the project,
please read the [Building](@ref flatbuffers_guide_building) documenation.
please read the [Building](@ref flatbuffers_guide_building) documentation.
To run the tests, execute `flattests` from the root `flatbuffers/` directory.
For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply
@@ -114,7 +114,7 @@ To use:
MonsterT monsterobj;
// Deserialize from buffer into object.
UnPackTo(&monsterobj, flatbuffer);
GetMonster(flatbuffer)->UnPackTo(&monsterobj);
// Update object directly like a C++ class instance.
cout << monsterobj->name; // This is now a std::string!
@@ -122,7 +122,7 @@ To use:
// Serialize into new flatbuffer.
FlatBufferBuilder fbb;
Pack(fbb, &monsterobj);
fbb.Finish(Monster::Pack(fbb, &monsterobj));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The following attributes are specific to the object-based API code generation:
@@ -426,6 +426,8 @@ it, this will provide you an easy way to use that data directly.
(see the schema documentation for some specifics on the JSON format
accepted).
Schema evolution compatibility for the JSON format follows the same rules as the binary format (JSON formatted data will be forwards/backwards compatible with schemas that evolve in a compatible way).
There are two ways to use text formats:
#### Using the compiler as a conversion tool
@@ -477,7 +479,7 @@ include paths. If not specified, any include statements try to resolve from
the current directory.
If there were any parsing errors, `Parse` will return `false`, and
`Parser::err` contains a human readable error string with a line number
`Parser::error_` contains a human readable error string with a line number
etc, which you should present to the creator of that file.
After each JSON file, the `Parser::fbb` member variable is the
@@ -546,21 +548,63 @@ locale-independent or locale-narrow functions `strtof_l`, `strtod_l`,
These functions use specified locale rather than the global or per-thread
locale instead. They are part of POSIX-2008 but not part of the C/C++
standard library, therefore, may be missing on some platforms.
The Flatbuffers library try to detect these functions at configuration and
compile time:
- `_MSC_VER >= 1900`: check MSVC2012 or higher for MSVC buid
- `_XOPEN_SOURCE>=700`: check POSIX-2008 for GCC/Clang build
- `check_cxx_symbol_exists(strtof_l stdlib.h)`: CMake check of `strtod_f`
- CMake `"CMakeLists.txt"`:
- Check existence of `strtol_l` and `strtod_l` in the `<stdlib.h>`.
- Compile-time `"/include/base.h"`:
- `_MSC_VER >= 1900`: MSVC2012 or higher if build with MSVC.
- `_XOPEN_SOURCE>=700`: POSIX-2008 if build with GCC/Clang.
After detection, the definition `FLATBUFFERS_LOCALE_INDEPENDENT` will be
set to `0` or `1`.
To override or stop this detection use CMake `-DFLATBUFFERS_LOCALE_INDEPENDENT={0|1}`
or predefine `FLATBUFFERS_LOCALE_INDEPENDENT` symbol.
It is possible to test the compatibility of the Flatbuffers library with
a specific locale using the environment variable `FLATBUFFERS_TEST_LOCALE`:
To test the compatibility of the Flatbuffers library with
a specific locale use the environment variable `FLATBUFFERS_TEST_LOCALE`:
```sh
>FLATBUFFERS_TEST_LOCALE="" ./flattests
>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./flattests
```
## Support of floating-point numbers
The Flatbuffers library assumes that a C++ compiler and a CPU are
compatible with the `IEEE-754` floating-point standard.
The schema and json parser may fail if `fast-math` or `/fp:fast` mode is active.
### Support of hexadecimal and special floating-point numbers
According to the [grammar](@ref flatbuffers_grammar) `fbs` and `json` files
may use hexadecimal and special (`NaN`, `Inf`) floating-point literals.
The Flatbuffers uses `strtof` and `strtod` functions to parse floating-point
literals. The Flatbuffers library has a code to detect a compiler compatibility
with the literals. If necessary conditions are met the preprocessor constant
`FLATBUFFERS_HAS_NEW_STRTOD` will be set to `1`.
The support of floating-point literals will be limited at compile time
if `FLATBUFFERS_HAS_NEW_STRTOD` constant is less than `1`.
In this case, schemas with hexadecimal or special literals cannot be used.
### Comparison of floating-point NaN values
The floating-point `NaN` (`not a number`) is special value which
representing an undefined or unrepresentable value.
`NaN` may be explicitly assigned to variables, typically as a representation
for missing values or may be a result of a mathematical operation.
The `IEEE-754` defines two kind of `NaNs`:
- Quiet NaNs, or `qNaNs`.
- Signaling NaNs, or `sNaNs`.
According to the `IEEE-754`, a comparison with `NaN` always returns
an unordered result even when compared with itself. As a result, a whole
Flatbuffers object will be not equal to itself if has one or more `NaN`.
Flatbuffers scalar fields that have the default value are not actually stored
in the serialized data but are generated in code (see [Writing a schema](@ref flatbuffers_guide_writing_schema)).
Scalar fields with `NaN` defaults break this behavior.
If a schema has a lot of `NaN` defaults the Flatbuffers can override
the unordered comparison by the ordered: `(NaN==NaN)->true`.
This ordered comparison is enabled when compiling a program with the symbol
`FLATBUFFERS_NAN_DEFAULTS` defined.
Additional computations added by `FLATBUFFERS_NAN_DEFAULTS` are very cheap
if GCC or Clang used. These compilers have a compile-time implementation
of `isnan` checking which MSVC does not.
<br>

175
docs/source/CsharpUsage.md Normal file
View File

@@ -0,0 +1,175 @@
Use in C# {#flatbuffers_guide_use_c-sharp}
==============
## Before you get started
Before diving into the FlatBuffers usage in C#, it should be noted that
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
general FlatBuffers usage in all of the supported languages (including C#).
This page is designed to cover the nuances of FlatBuffers usage,
specific to C#.
You should also have read the [Building](@ref flatbuffers_guide_building)
documentation to build `flatc` and should be familiar with
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
[Writing a schema](@ref flatbuffers_guide_writing_schema).
## FlatBuffers C-sharp code location
The code for the FlatBuffers C# library can be found at
`flatbuffers/net/FlatBuffers`. You can browse the library on the
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
FlatBuffers).
## Testing the FlatBuffers C-sharp libraries
The code to test the libraries can be found at `flatbuffers/tests`.
The test code for C# is located in the [FlatBuffers.Test](https://github.com/
google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
https://www.visualstudio.com), and compile/run the project.
Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
Once you have installed `Mono`, you can run the tests from the command line
by running the following commands from inside the `FlatBuffers.Test` folder:
~~~{.sh}
mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
mono Assert.exe
~~~
## Using the FlatBuffers C# library
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
example of how to use FlatBuffers in C#.*
FlatBuffers supports reading and writing binary FlatBuffers in C#.
To use FlatBuffers in your own code, first generate C# classes from your
schema with the `--csharp` option to `flatc`.
Then you can include both FlatBuffers and the generated code to read
or write a FlatBuffer.
For example, here is how you would read a FlatBuffer binary file in C#:
First, import the library and generated code. Then, you read a FlatBuffer binary
file into a `byte[]`. You then turn the `byte[]` into a `ByteBuffer`, which you
pass to the `GetRootAsMyRootType` function:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
using MyGame.Example;
using FlatBuffers;
// This snippet ignores exceptions for brevity.
byte[] data = File.ReadAllBytes("monsterdata_test.mon");
ByteBuffer bb = new ByteBuffer(data);
Monster monster = Monster.GetRootAsMonster(bb);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now you can access the data from the `Monster monster`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
short hp = monster.Hp;
Vec3 pos = monster.Pos;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C# code naming follows standard C# style with `PascalCasing` identifiers,
e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
available as properties instead of parameterless accessor methods.
The performance-enhancing methods to which you can pass an already created
object are prefixed with `Get`, e.g.:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
// property
var pos = monster.Pos;
// method filling a preconstructed object
var preconstructedPos = new Vec3();
monster.GetPos(preconstructedPos);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Storing dictionaries in a FlatBuffer
FlatBuffers doesn't support dictionaries natively, but there is support to
emulate their behavior with vectors and binary search, which means you
can have fast lookups directly from a FlatBuffer without having to unpack
your data into a `Dictionary` or similar.
To use it:
- Designate one of the fields in a table as the "key" field. You do this
by setting the `key` attribute on this field, e.g.
`name:string (key)`.
You may only have one key field, and it must be of string or scalar type.
- Write out tables of this type as usual, collect their offsets in an
array.
- Instead of calling standard generated method,
e.g.: `Monster.createTestarrayoftablesVector`,
call `CreateSortedVectorOfMonster` in C#
which will first sort all offsets such that the tables they refer to
are sorted by the key field, then serialize it.
- Now when you're accessing the FlatBuffer, you can use
the `ByKey` accessor to access elements of the vector, e.g.:
`monster.TestarrayoftablesByKey("Frodo")` in C#,
which returns an object of the corresponding table type,
or `null` if not found.
`ByKey` performs a binary search, so should have a similar
speed to `Dictionary`, though may be faster because of better caching.
`ByKey` only works if the vector has been sorted, it will
likely not find elements if it hasn't been sorted.
## Text parsing
There currently is no support for parsing text (Schema's and JSON) directly
from C#, though you could use the C++ parser through native call
interfaces available to each language. Please see the
C++ documentation for more on text parsing.
## Object based API
FlatBuffers is all about memory efficiency, which is why its base API is written
around using as little as possible of it. This does make the API clumsier
(requiring pre-order construction of all data, and making mutation harder).
For times when efficiency is less important a more convenient object based API
can be used (through `--gen-object-api`) that is able to unpack & pack a
FlatBuffer into objects and standard System.Collections.Generic containers, allowing for convenient
construction, access and mutation.
To use:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
// Deserialize from buffer into object.
MonsterT monsterobj = GetMonster(flatbuffer).UnPack();
// Update object directly like a C# class instance.
Console.WriteLine(monsterobj.Name);
monsterobj.Name = "Bob"; // Change the name.
// Serialize into new flatbuffer.
FlatBufferBuilder fbb = new FlatBufferBuilder(1);
fbb.Finish(Monster.Pack(fbb, monsterobj).Value);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Json Serialization
An additional feature of the object API is the ability to allow you to
serialize & deserialize a JSON text.
To use Json Serialization, add `--gen-json-serializer` option to `flatc` and
add `Newtonsoft.Json` nuget package to csproj.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
// Deserialize MonsterT from json
string jsonText = File.ReadAllText(@"Resources/monsterdata_test.json");
MonsterT mon = MonsterT.DeserializeFromJson(jsonText);
// Serialize MonsterT to json
string jsonText2 = mon.SerializeToJson();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Limitation
* `hash` attribute currentry not supported.
* NuGet package Dependency
* [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)
<br>

View File

@@ -4,7 +4,7 @@ FlatBuffers {#flatbuffers_index}
# Overview {#flatbuffers_overview}
[FlatBuffers](@ref flatbuffers_overview) is an efficient cross platform
serialization library for C++, C#, C, Go, Java, JavaScript, Lobster, Lua, TypeScript, PHP, Python, and Rust.
serialization library for C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift.
It was originally created at Google for game development and other
performance-critical applications.
@@ -51,7 +51,7 @@ under the Apache license, v2 (see LICENSE.txt).
needed (faster and more memory efficient than other JSON
parsers).
Java and Go code supports object-reuse. C# has efficient struct based
Java, Kotlin and Go code supports object-reuse. C# has efficient struct based
accessors.
- **Cross platform code with no dependencies** - C++ code will work
@@ -108,7 +108,7 @@ sections provide a more in-depth usage guide.
present for every object instance.
- Use `flatc` (the FlatBuffer compiler) to generate a C++ header (or
Java/C#/Go/Python.. classes) with helper classes to access and construct
Java/Kotlin/C#/Go/Python.. classes) with helper classes to access and construct
serialized data. This header (say `mydata_generated.h`) only depends on
`flatbuffers.h`, which defines the core functionality.
@@ -130,8 +130,12 @@ sections provide a more in-depth usage guide.
- How to [write a schema](@ref flatbuffers_guide_writing_schema).
- How to [use the generated C++ code](@ref flatbuffers_guide_use_cpp) in your
own programs.
- How to [use the generated Java/C# code](@ref flatbuffers_guide_use_java_c-sharp)
- How to [use the generated Java code](@ref flatbuffers_guide_use_java)
in your own programs.
- How to [use the generated C# code](@ref flatbuffers_guide_use_c-sharp)
in your own programs.
- How to [use the generated Kotlin code](@ref flatbuffers_guide_use_kotlin)
in your own programs.
- How to [use the generated Go code](@ref flatbuffers_guide_use_go) in your
own programs.
- How to [use the generated Lua code](@ref flatbuffers_guide_use_lua) in your
@@ -146,6 +150,8 @@ sections provide a more in-depth usage guide.
own programs.
- How to [use the generated Rust code](@ref flatbuffers_guide_use_rust) in your
own programs.
- How to [use the generated Swift code](@ref flatbuffers_guide_use_swift) in your
own programs.
- [Support matrix](@ref flatbuffers_support) for platforms/languages/features.
- Some [benchmarks](@ref flatbuffers_benchmarks) showing the advantage of
using FlatBuffers.
@@ -161,6 +167,7 @@ sections provide a more in-depth usage guide.
- [GitHub repository](http://github.com/google/flatbuffers)
- [Landing page](http://google.github.io/flatbuffers)
- [FlatBuffers Google Group](https://groups.google.com/forum/#!forum/flatbuffers)
- [Discord](https://discord.gg/6qgKs3R) and [Gitter](https://gitter.im/lobster_programming_language/community) chat.
- [FlatBuffers Issues Tracker](http://github.com/google/flatbuffers/issues)
- Independent implementations & tools:
- [FlatCC](https://github.com/dvidelabs/flatcc) Alternative FlatBuffers
@@ -176,3 +183,6 @@ sections provide a more in-depth usage guide.
- [FlatBuffers in Android](http://frogermcs.github.io/flatbuffers-in-android-introdution/)
- [Parsing JSON to FlatBuffers in Java](http://frogermcs.github.io/json-parsing-with-flatbuffers-in-android/)
- [FlatBuffers in Unity](http://exiin.com/blog/flatbuffers-for-unity-sample-code/)
- [FlexBuffers C#](https://github.com/mzaks/FlexBuffers-CSharp) and
[article](https://medium.com/@icex33/flexbuffers-for-unity3d-4d1ab5c53fbe?)
on its use.

View File

@@ -29,9 +29,7 @@ FlexBuffers is still slower than regular FlatBuffers though, so we recommend to
only use it if you need it.
# Usage
This is for C++, other languages may follow.
# Usage in C++
Include the header `flexbuffers.h`, which in turn depends on `flatbuffers.h`
and `util.h`.
@@ -98,10 +96,10 @@ allows a single type, and uses a bit less memory.
`IndirectFloat` is an interesting feature that allows you to store values
by offset rather than inline. Though that doesn't make any visible change
to the user, the consequence is that large values (especially doubles or
64 bit ints) that occur more than once can be shared. Another use case is
inside of vectors, where the largest element makes up the size of all elements
(e.g. a single double forces all elements to 64bit), so storing a lot of small
integers together with a double is more efficient if the double is indirect.
64 bit ints) that occur more than once can be shared (see ReuseValue).
Another use case is inside of vectors, where the largest element makes
up the size of all elements (e.g. a single double forces all elements to
64bit), so storing a lot of small integers together with a double is more efficient if the double is indirect.
Accessing it:
@@ -122,6 +120,46 @@ map["unknown"].IsNull(); // true
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Usage in Java
Java implementation follows the C++ one, closely.
For creating the equivalent of the same JSON `{ vec: [ -100, "Fred", 4.0 ], foo: 100 }`,
one could use the following code:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
int smap = builder.startMap();
int svec = builder.startVector();
builder.putInt(-100);
builder.putString("Fred");
builder.putFloat(4.0);
builder.endVector("vec", svec, false, false);
builder.putInt("foo", 100);
builder.endMap(null, smap);
ByteBuffer bb = builder.finish();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Similarly, to read the data, just:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
FlexBuffers.Map map = FlexBuffers.getRoot(bb).asMap();
map.size(); // 2
FlexBuffers.Vector vec = map.get("vec").asVector();
vec.size(); // 3
vec.get(0).asLong(); // -100;
vec.get(1).asString(); // "Fred";
vec.get(1).asLong(); // 0 (Number parsing failed).
vec.get(2).asFloat(); // 4.0
vec.get(2).asString().isEmpty(); // true (Wrong Type).
vec.get(2).asString(); // "" (This still works though).
vec.get(2).toString(); // "4.0" (Or have it converted).
map.get("foo").asUInt(); // 100
map.get("unknown").isNull(); // true
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Binary encoding
A description of how FlexBuffers are encoded is in the

View File

@@ -15,6 +15,12 @@ all commonly used CPUs today. FlatBuffers will also work on big-endian
machines, but will be slightly slower because of additional
byte-swap intrinsics.
It is assumed that the following conditions are met, to ensure
cross-platform interoperability:
- The binary `IEEE-754` format is used for floating-point numbers.
- The `two's complemented` representation is used for signed integers.
- The endianness is the same for floating-point numbers as for integers.
On purpose, the format leaves a lot of details about where exactly
things live in memory undefined, e.g. fields in a table can have any
order, and objects to some extent can be stored in many orders. This is

View File

@@ -1,41 +1,30 @@
Use in Java/C# {#flatbuffers_guide_use_java_c-sharp}
Use in Java {#flatbuffers_guide_use_java}
==============
## Before you get started
Before diving into the FlatBuffers usage in Java or C#, it should be noted that
Before diving into the FlatBuffers usage in Java, it should be noted that
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
general FlatBuffers usage in all of the supported languages (including both Java
and C#). This page is designed to cover the nuances of FlatBuffers usage,
specific to Java and C#.
general FlatBuffers usage in all of the supported languages (including Java).
This page is designed to cover the nuances of FlatBuffers usage,
specific to Java.
You should also have read the [Building](@ref flatbuffers_guide_building)
documentation to build `flatc` and should be familiar with
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
[Writing a schema](@ref flatbuffers_guide_writing_schema).
## FlatBuffers Java and C-sharp code location
#### Java
## FlatBuffers Java code location
The code for the FlatBuffers Java library can be found at
`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
java/com/google/flatbuffers).
#### C-sharp
The code for the FlatBuffers C# library can be found at
`flatbuffers/net/FlatBuffers`. You can browse the library on the
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
FlatBuffers).
## Testing the FlatBuffers Java and C-sharp libraries
## Testing the FlatBuffers Java libraries
The code to test the libraries can be found at `flatbuffers/tests`.
#### Java
The test code for Java is located in [JavaTest.java](https://github.com/google
/flatbuffers/blob/master/tests/JavaTest.java).
@@ -47,31 +36,15 @@ system.
*Note: These scripts require that [Java](https://www.oracle.com/java/index.html)
is installed.*
#### C-sharp
The test code for C# is located in the [FlatBuffers.Test](https://github.com/
google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
https://www.visualstudio.com), and compile/run the project.
Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
Once you have installed `Mono`, you can run the tests from the command line
by running the following commands from inside the `FlatBuffers.Test` folder:
~~~{.sh}
mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
mono Assert.exe
~~~
## Using the FlatBuffers Java (and C#) library
## Using the FlatBuffers Java library
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
example of how to use FlatBuffers in Java or C#.*
example of how to use FlatBuffers in Java.*
FlatBuffers supports reading and writing binary FlatBuffers in Java and C#.
FlatBuffers supports reading and writing binary FlatBuffers in Java.
To use FlatBuffers in your own code, first generate Java classes from your
schema with the `--java` option to `flatc`. (Or for C# with `--csharp`).
schema with the `--java` option to `flatc`.
Then you can include both FlatBuffers and the generated code to read
or write a FlatBuffer.
@@ -80,11 +53,6 @@ First, import the library and generated code. Then, you read a FlatBuffer binary
file into a `byte[]`. You then turn the `byte[]` into a `ByteBuffer`, which you
pass to the `getRootAsMyRootType` function:
*Note: The code here is written from the perspective of Java. Code for both
languages is both generated and used in nearly the exact same way, with only
minor differences. These differences are
[explained in a section below](#differences_in_c-sharp).*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
import MyGame.Example.*;
import com.google.flatbuffers.FlatBufferBuilder;
@@ -107,30 +75,6 @@ Now you can access the data from the `Monster monster`:
Vec3 pos = monster.pos();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<a name="differences_in_c-sharp">
#### Differences in C-sharp
</a>
C# code works almost identically to Java, with only a few minor differences.
You can see an example of C# code in
`tests/FlatBuffers.Test/FlatBuffersExampleTests.cs` or
`samples/SampleBinary.cs`.
First of all, naming follows standard C# style with `PascalCasing` identifiers,
e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
available as properties instead of parameterless accessor methods as in Java.
The performance-enhancing methods to which you can pass an already created
object are prefixed with `Get`, e.g.:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
// property
var pos = monster.Pos;
// method filling a preconstructed object
var preconstructedPos = new Vec3();
monster.GetPos(preconstructedPos);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Storing dictionaries in a FlatBuffer
FlatBuffers doesn't support dictionaries natively, but there is support to
@@ -147,14 +91,12 @@ To use it:
array.
- Instead of calling standard generated method,
e.g.: `Monster.createTestarrayoftablesVector`,
call `CreateSortedVectorOfMonster` in C# or
`createSortedVectorOfTables` (from the `FlatBufferBuilder` object) in Java,
call `createSortedVectorOfTables` (from the `FlatBufferBuilder` object).
which will first sort all offsets such that the tables they refer to
are sorted by the key field, then serialize it.
- Now when you're accessing the FlatBuffer, you can use
the `ByKey` accessor to access elements of the vector, e.g.:
`monster.testarrayoftablesByKey("Frodo")` in Java or
`monster.TestarrayoftablesByKey("Frodo")` in C#,
`monster.testarrayoftablesByKey("Frodo")`.
which returns an object of the corresponding table type,
or `null` if not found.
`ByKey` performs a binary search, so should have a similar
@@ -165,7 +107,7 @@ To use it:
## Text parsing
There currently is no support for parsing text (Schema's and JSON) directly
from Java or C#, though you could use the C++ parser through native call
from Java, though you could use the C++ parser through native call
interfaces available to each language. Please see the
C++ documentation for more on text parsing.

View File

@@ -0,0 +1,84 @@
Use in Kotlin {#flatbuffers_guide_use_kotlin}
==============
## Before you get started
Before diving into the FlatBuffers usage in Kotlin, it should be noted that
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
general FlatBuffers usage in all of the supported languages (including K).
This page is designed to cover the nuances of FlatBuffers usage, specific to Kotlin.
You should also have read the [Building](@ref flatbuffers_guide_building)
documentation to build `flatc` and should be familiar with
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
[Writing a schema](@ref flatbuffers_guide_writing_schema).
## Kotlin and FlatBuffers Java code location
Code generated for Kotlin currently uses the flatbuffers java runtime library. That means that Kotlin generated code can only have Java virtual machine as target architecture (which includes Android). Kotlin Native and Kotlin.js are currently not supported.
The code for the FlatBuffers Java library can be found at
`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
java/com/google/flatbuffers).
## Testing FlatBuffers Kotlin
The test code for Java is located in [KotlinTest.java](https://github.com/google
/flatbuffers/blob/master/tests/KotlinTest.kt).
To run the tests, use [KotlinTest.sh](https://github.com/google/
flatbuffers/blob/master/tests/KotlinTest.sh) shell script.
*Note: These scripts require that [Kotlin](https://kotlinlang.org/) is installed.*
## Using the FlatBuffers Kotlin library
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
example of how to use FlatBuffers in Kotlin.*
FlatBuffers supports reading and writing binary FlatBuffers in Kotlin.
To use FlatBuffers in your own code, first generate Java classes from your
schema with the `--kotlin` option to `flatc`.
Then you can include both FlatBuffers and the generated code to read
or write a FlatBuffer.
For example, here is how you would read a FlatBuffer binary file in Kotlin:
First, import the library and generated code. Then, you read a FlatBuffer binary
file into a `ByteArray`. You then turn the `ByteArray` into a `ByteBuffer`, which you
pass to the `getRootAsMyRootType` function:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
import MyGame.Example.*
import com.google.flatbuffers.FlatBufferBuilder
// This snippet ignores exceptions for brevity.
val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
val temp = ByteArray(it.length().toInt())
it.readFully(temp)
temp
}
val bb = ByteBuffer.wrap(data)
val monster = Monster.getRootAsMonster(bb)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now you can access the data from the `Monster monster`:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
val hp = monster.hp
val pos = monster.pos!!;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
## Differences between Kotlin and Java code
Kotlin generated code was designed to be as close as possible to the java counterpart, as for now, we only support kotlin on java virtual machine. So the differences in implementation and usage are basically the ones introduced by the Kotlin language itself. You can find more in-depth information [here](https://kotlinlang.org/docs/reference/comparison-to-java.html).
The most obvious ones are:
* Fields as accessed as Kotlin [properties](https://kotlinlang.org/docs/reference/properties.html)
* Static methods are accessed in [companion object](https://kotlinlang.org/docs/reference/classes.html#companion-objects)

View File

@@ -114,6 +114,27 @@ of same-size data where a `reinterpret_cast` would give you a desirable result,
e.g. you could change a `uint` to an `int` if no values in current data use the
high bit yet.
### Arrays
Arrays are a convenience short-hand for a fixed-length collection of elements.
Arrays can be used to replace the following schema:
struct Vec3 {
x:float;
y:float;
z:float;
}
with the following schema:
struct Vec3 {
v:[float:3];
}
Both representations are binary equivalent.
Arrays are currently only supported in a `struct`.
### (Default) Values
Values are a sequence of digits. Values may be optionally followed by a decimal
@@ -324,6 +345,9 @@ Current understood attributes:
Note: currently not guaranteed to have an effect when used with
`--object-api`, since that may allocate objects at alignments less than
what you specify with `force_align`.
- `force_align: size` (on a vector): force the alignment of this vector to be
something different than what the element size would normally dictate.
Note: Now only work for generated C++ code.
- `bit_flags` (on an unsigned enum): the values of this field indicate bits,
meaning that any unsigned value N specified in the schema will end up
representing 1<<N, or if you don't specify values at all, you'll get
@@ -418,14 +442,19 @@ numerical literals:
For example: `[0x123, +0x45, -0x67]` are equal to `[291, 69, -103]` decimals.
- The format of float-point numbers is fully compatible with C/C++ format.
If a modern C++ compiler is used the parser accepts hexadecimal and special
float-point literals as well:
floating-point literals as well:
`[-1.0, 2., .3e0, 3.e4, 0x21.34p-5, -inf, nan]`.
The exponent suffix of hexadecimal float-point number is mandatory.
Extended float-point support was tested with:
The following conventions for floating-point numbers are used:
- The exponent suffix of hexadecimal floating-point number is mandatory.
- Parsed `NaN` converted to unsigned IEEE-754 `quiet-NaN` value.
Extended floating-point support was tested with:
- x64 Windows: `MSVC2015` and higher.
- x64 Linux: `LLVM 6.0`, `GCC 4.9` and higher.
For details, see [Use in C++](@ref flatbuffers_guide_use_cpp) section.
- For compatibility with a JSON lint tool all numeric literals of scalar
fields can be wrapped to quoted string:
`"1", "2.0", "0x48A", "0x0C.0Ep-1", "-inf", "true"`.
@@ -537,7 +566,7 @@ with the new schema now cannot read nor write `a` anymore (any existing code
that tries to do so will result in compile errors), but can still read
old data (they will ignore the field).
table { c:int a:int; b:int; }
table { c:int; a:int; b:int; }
This is NOT ok, as this makes the schemas incompatible. Old code reading newer
data will interpret `c` as if it was `a`, and new code reading old data

View File

@@ -18,23 +18,23 @@ In general:
NOTE: this table is a start, it needs to be extended.
Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Dart | Lobster | Rust
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ----
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes
Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ?
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ?
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | No | ?
Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | evanw/ev* | kr* | mik* | ch* | dnfield | aard* | rw
Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Dart | Lobster | Rust | Swift
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ------- | ------
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes | Yes
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No | No
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No | No
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | No
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes | No
Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb | ?
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes | No
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ? | No
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ? | Yes
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | No | ? | No
Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | evanw/ev* | kr* | mik* | ch* | dnfield | aard* | rw | mi*/mz*
* aard = aardappel (previously: gwvo)
* ev = evolutional
@@ -42,5 +42,7 @@ Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | ev
* mik = mikkelfj
* ch = chobie
* kr = krojew
* mi = mustiikhalil
* mz = mzaks
<br>

91
docs/source/SwiftUsage.md Normal file
View File

@@ -0,0 +1,91 @@
Use in Swift {#flatbuffers_guide_use_swift}
=========
## Before you get started
Before diving into the FlatBuffers usage in Swift, it should be noted that
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide
to general FlatBuffers usage in all of the supported languages (including Swift).
This page is designed to cover the nuances of FlatBuffers usage, specific to
Swift.
You should also have read the [Building](@ref flatbuffers_guide_building)
documentation to build `flatc` and should be familiar with
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
[Writing a schema](@ref flatbuffers_guide_writing_schema).
## FlatBuffers Swift library code location
The code for the FlatBuffers Swift library can be found at
`flatbuffers/swift`. You can browse the library code on the [FlatBuffers
GitHub page](https://github.com/google/flatbuffers/tree/master/swift).
## Testing the FlatBuffers Swift library
The code to test the Swift library can be found at `flatbuffers/Flatbuffers.Test.Swift`.
The test code itself is located in [Flatbuffers.Test.Swift](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift).
To run the tests, use the [SwiftTest.sh](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift/SwiftTest.sh) shell script.
*Note: The shell script requires [Swift](https://swift.org) to
be installed.*
## Using the FlatBuffers Swift library
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
example of how to use FlatBuffers in Swift.*
FlatBuffers supports reading and writing binary FlatBuffers in Swift.
To use FlatBuffers in your own code, first generate Swift structs from your
schema with the `--swift` option to `flatc`. Then include FlatBuffers using `SPM` in
by adding the path to `FlatBuffers/swift` into it. The generated code should also be
added to xcode or the path of the package you will be using. Note: sometimes xcode cant
and wont see the generated files, so it's better that you copy them to xcode.
For example, here is how you would read a FlatBuffer binary file in Swift: First,
include the library and copy thegenerated code. Then read a FlatBuffer binary file or
a data object from the server, which you can pass into the `GetRootAsMonster` function.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
import FlatBuffers
typealias Monster1 = MyGame.Sample.Monster
typealias Vec3 = MyGame.Sample.Vec3
let path = FileManager.default.currentDirectoryPath
let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon")
guard let data = try? Data(contentsOf: url) else { return }
let monster = Monster.getRootAsMonster(bb: ByteBuffer(data: data))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Now you can access values like this:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
let hp = monster.hp
let pos = monster.pos
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In some cases it's necessary to modify values in an existing FlatBuffer in place (without creating a copy). For this reason, scalar fields of a Flatbuffer table or struct can be mutated.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
let monster = Monster.getRootAsMonster(bb: ByteBuffer(data: data))
if !monster.mutate(hp: 10) {
fatalError("couldn't mutate")
}
// mutate a struct field
let vec = monster.pos.mutate(z: 4)
// This mutation will fail because the mana field is not available in
// the buffer. It should be set when creating the buffer.
if !monster.mutate(mana: 20) {
fatalError("couldn't mutate")
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The term `mutate` is used instead of `set` to indicate that this is a special use case. All mutate functions return a boolean value which is false if the field we're trying to mutate is not available in the buffer.
<br>

View File

@@ -23,6 +23,7 @@ Please select your desired language for our quest:
<form>
<input type="radio" name="language" value="cpp" checked="checked">C++</input>
<input type="radio" name="language" value="java">Java</input>
<input type="radio" name="language" value="kotlin">Kotlin</input>
<input type="radio" name="language" value="csharp">C#</input>
<input type="radio" name="language" value="go">Go</input>
<input type="radio" name="language" value="python">Python</input>
@@ -34,6 +35,7 @@ Please select your desired language for our quest:
<input type="radio" name="language" value="lua">Lua</input>
<input type="radio" name="language" value="lobster">Lobster</input>
<input type="radio" name="language" value="rust">Rust</input>
<input type="radio" name="language" value="swift">Swift</input>
</form>
\endhtmlonly
@@ -115,6 +117,9 @@ For your chosen language, please cross-reference with:
<div class="language-java">
[SampleBinary.java](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.java)
</div>
<div class="language-kotlin">
[SampleBinary.kt](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.kt)
</div>
<div class="language-csharp">
[SampleBinary.cs](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.cs)
</div>
@@ -148,6 +153,9 @@ For your chosen language, please cross-reference with:
<div class="language-rust">
[sample_binary.rs](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs)
</div>
<div class="language-swift">
[sample_binary.swift](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.swift)
</div>
## Writing the Monsters' FlatBuffer Schema
@@ -284,6 +292,12 @@ Please be aware of the difference between `flatc` and `flatcc` tools.
./../flatc --java monster.fbs
~~~
</div>
<div class="language-kotlin">
~~~{.sh}
cd flatbuffers/samples
./../flatc --kotlin monster.fbs
~~~
</div>
<div class="language-csharp">
~~~{.sh}
cd flatbuffers/samples
@@ -353,6 +367,12 @@ Please be aware of the difference between `flatc` and `flatcc` tools.
./../flatc --rust monster.fbs
~~~
</div>
<div class="language-swift">
~~~{.sh}
cd flatbuffers/samples
./../flatc --swift monster.fbs
~~~
</div>
For a more complete guide to using the `flatc` compiler, please read the
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
@@ -382,6 +402,13 @@ The first step is to import/include the library, generated files, etc.
import com.google.flatbuffers.FlatBufferBuilder;
~~~
</div>
<div class="language-kotlin">
~~~{.kotlin}
import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
import com.google.flatbuffers.FlatBufferBuilder
~~~
</div>
<div class="language-csharp">
~~~{.cs}
using FlatBuffers;
@@ -424,7 +451,7 @@ The first step is to import/include the library, generated files, etc.
~~~
</div>
<div class="language-typescript">
// note: import flabuffers with your desired import method
// note: import flatbuffers with your desired import method
import { MyGame } from './monster_generated';
</div>
@@ -485,8 +512,8 @@ The first step is to import/include the library, generated files, etc.
</div>
<div class="language-lobster">
~~~{.lobster}
include from "../lobster/" // Where to find flatbuffers.lobster
include "monster_generated.lobster"
import from "../lobster/" // Where to find flatbuffers.lobster
import monster_generated
~~~
</div>
<div class="language-rust">
@@ -506,6 +533,21 @@ The first step is to import/include the library, generated files, etc.
~~~
</div>
<div class="language-swift">
~~~{.swift}
/**
// make sure that monster_generated.swift is included in your project
*/
import Flatbuffers
// typealiases for convenience
typealias Monster = MyGame1.Sample.Monster
typealias Weapon = MyGame1.Sample.Weapon
typealias Color = MyGame1.Sample.Color
typealias Vec3 = MyGame1.Sample.Vec3
~~~
</div>
Now we are ready to start building some buffers. In order to start, we need
to create an instance of the `FlatBufferBuilder`, which will contain the buffer
as it grows. You can pass an initial size of the buffer (here 1024 bytes),
@@ -525,6 +567,13 @@ which will grow automatically if needed:
FlatBufferBuilder builder = new FlatBufferBuilder(1024);
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
// Create a `FlatBufferBuilder`, which will be used to create our
// monsters' FlatBuffers.
val builder = FlatBufferBuilder(1024)
~~~
</div>
<div class="language-csharp">
~~~{.cs}
// Create a `FlatBufferBuilder`, which will be used to create our
@@ -592,7 +641,7 @@ which will grow automatically if needed:
</div>
<div class="language-lobster">
~~~{.lobster}
-- get access to the builder
// get access to the builder
let builder = flatbuffers_builder {}
~~~
</div>
@@ -603,6 +652,12 @@ which will grow automatically if needed:
let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(1024);
~~~
</div>
<div class="language-swift">
~~~{.swift}
// create a `FlatBufferBuilder`, which will be used to serialize objects
let builder = FlatBufferBuilder(initialSize: 1024)
~~~
</div>
After creating the `builder`, we can start serializing our data. Before we make
our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
@@ -633,6 +688,19 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
val weaponOneName = builder.createString("Sword")
val weaponOneDamage: Short = 3;
val weaponTwoName = builder.createString("Axe")
val weaponTwoDamage: Short = 5;
// Use the `createWeapon()` helper function to create the weapons, since we set every field.
val sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage)
val axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage)
~~~
</div>
<div class="language-csharp">
~~~{.cs}
var weaponOneName = builder.CreateString("Sword");
@@ -813,12 +881,13 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
let weapon_names = [ "Sword", "Axe" ]
let weapon_damages = [ 3, 5 ]
weapon_offsets := map(weapon_names) name, i:
let weapon_offsets = map(weapon_names) name, i:
let ns = builder.CreateString(name)
builder.MyGame_Sample_WeaponStart()
builder.MyGame_Sample_WeaponAddName(ns)
builder.MyGame_Sample_WeaponAddDamage(weapon_damages[i])
builder.MyGame_Sample_WeaponEnd()
MyGame_Sample_WeaponBuilder { b }
.start()
.add_name(ns)
.add_damage(weapon_damages[i])
.end()
~~~
</div>
<div class="language-rust">
@@ -840,6 +909,25 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
~~~
</div>
<div class="language-swift">
~~~{.swift}
let weapon1Name = builder.create(string: "Sword")
let weapon2Name = builder.create(string: "Axe")
// start creating the weapon by calling startWeapon
let weapon1Start = Weapon.startWeapon(builder)
Weapon.add(name: weapon1Name, builder)
Weapon.add(damage: 3, builder)
// end the object by passing the start point for the weapon 1
let sword = Weapon.endWeapon(builder, start: weapon1Start)
let weapon2Start = Weapon.startWeapon(builder)
Weapon.add(name: weapon2Name, builder)
Weapon.add(damage: 5, builder)
let axe = Weapon.endWeapon(builder, start: weapon2Start)
~~~
</div>
Now let's create our monster, the `orc`. For this `orc`, lets make him
`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him
a large pool of hit points with `300`. We can give him a vector of weapons
@@ -874,6 +962,17 @@ traversal. This is generally easy to do on any tree structures.
int inv = Monster.createInventoryVector(builder, treasure);
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
// Serialize a name for our monster, called "Orc".
val name = builder.createString("Orc")
// Create a `vector` representing the inventory of the Orc. Each number
// could correspond to an item that can be claimed after he is slain.
val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
val inv = Monster.createInventoryVector(builder, treasure)
~~~
</div>
<div class="language-csharp">
~~~{.cs}
// Serialize a name for our monster, called "Orc".
@@ -1019,6 +1118,16 @@ traversal. This is generally easy to do on any tree structures.
let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
~~~
</div>
<div class="language-swift">
~~~{.swift}
// Name of the Monster.
let name = builder.create(string: "Orc")
// create inventory
let inventory: [Byte] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
let inventoryOffset = builder.createVector(inventory)
~~~
</div>
We serialized two built-in data types (`string` and `vector`) and captured
their return values. These values are offsets into the serialized data,
@@ -1059,6 +1168,16 @@ offsets.
int weapons = Monster.createWeaponsVector(builder, weaps);
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
// Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
// create a FlatBuffer vector.
val weaps = intArrayOf(sword, axe)
// Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
val weapons = Monster.createWeaponsVector(builder, weaps)
~~~
</div>
<div class="language-csharp">
~~~{.cs}
var weaps = new Offset<Weapon>[2];
@@ -1153,6 +1272,13 @@ offsets.
let weapons = builder.create_vector(&[sword, axe]);
~~~
</div>
<div class="language-swift">
~~~{.swift}
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
// we created above.
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
~~~
</div>
<br>
Note there's additional convenience overloads of `CreateVector`, allowing you
@@ -1179,6 +1305,14 @@ for the `path` field above:
int path = fbb.endVector();
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
Monster.startPathVector(fbb, 2)
Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)
Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f)
val path = fbb.endVector()
~~~
</div>
<div class="language-csharp">
~~~{.cs}
Monster.StartPathVector(fbb, 2);
@@ -1281,6 +1415,15 @@ for the `path` field above:
// let path = builder.create_vector(&[&x, &y]);
~~~
</div>
<div class="language-swift">
~~~{.swift}
//
let points = builder.createVector(structs: [MyGame.Sample.createVec3(x: 1, y: 2, z: 3),
MyGame.Sample.createVec3(x: 4, y: 5, z: 6)],
type: Vec3.self)
~~~
</div>
We have now serialized the non-scalar components of the orc, so we
can serialize the monster itself:
@@ -1317,6 +1460,22 @@ can serialize the monster itself:
int orc = Monster.endMonster(builder);
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
// Create our monster using `startMonster()` and `endMonster()`.
Monster.startMonster(builder)
Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f))
Monster.addName(builder, name)
Monster.addColor(builder, Color.Red)
Monster.addHp(builder, 300.toShort())
Monster.addInventory(builder, inv)
Monster.addWeapons(builder, weapons)
Monster.addEquippedType(builder, Equipment.Weapon)
Monster.addEquipped(builder, axe)
Monster.addPath(builder, path)
val orc = Monster.endMonster(builder)
~~~
</div>
<div class="language-csharp">
~~~{.cs}
// Create our monster using `StartMonster()` and `EndMonster()`.
@@ -1503,17 +1662,18 @@ can serialize the monster itself:
</div>
<div class="language-lobster">
~~~{.lobster}
builder.MyGame_Sample_MonsterStart()
builder.MyGame_Sample_MonsterAddPos(builder.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
builder.MyGame_Sample_MonsterAddHp(300)
builder.MyGame_Sample_MonsterAddName(name)
builder.MyGame_Sample_MonsterAddInventory(inv)
builder.MyGame_Sample_MonsterAddColor(MyGame_Sample_Color_Red)
builder.MyGame_Sample_MonsterAddWeapons(weapons)
builder.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
builder.MyGame_Sample_MonsterAddEquipped(weapon_offsets[1])
builder.MyGame_Sample_MonsterAddPath(path)
let orc = builder.MyGame_Sample_MonsterEnd()
let orc = MyGame_Sample_MonsterBuilder { b }
.start()
.add_pos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
.add_hp(300)
.add_name(name)
.add_inventory(inv)
.add_color(MyGame_Sample_Color_Red)
.add_weapons(weapons)
.add_equipped_type(MyGame_Sample_Equipment_Weapon)
.add_equipped(weapon_offsets[1])
.add_path(path)
.end()
~~~
</div>
<div class="language-rust">
@@ -1537,6 +1697,19 @@ can serialize the monster itself:
});
~~~
</div>
<div class="language-swift">
~~~{.swift}
let orc = Monster.createMonster(builder,
offsetOfPos: pos,
hp: 300,
offsetOfName: name,
vectorOfInventory: inventoryOffset,
color: .red,
vectorOfWeapons: weaponsOffset,
equippedType: .weapon,
offsetOfEquipped: axe)
~~~
</div>
Note how we create `Vec3` struct in-line in the table. Unlike tables, structs
are simple combinations of scalars that are always stored inline, just like
@@ -1602,6 +1775,21 @@ a bit more flexibility.
~~~
</div>
<div class="language-swift">
~~~{.swift}
let start = Monster.startMonster(builder)
Monster.add(pos: pos, builder)
Monster.add(hp: 300, builder)
Monster.add(name: name, builder)
Monster.addVectorOf(inventory: inventoryOffset, builder)
Monster.add(color: .red, builder)
Monster.addVectorOf(weapons: weaponsOffset, builder)
Monster.add(equippedType: .weapon, builder)
Monster.add(equipped: axe, builder)
var orc = Monster.endMonster(builder, start: start)
~~~
</div>
Before finishing the serialization, let's take a quick look at FlatBuffer
`union Equipped`. There are two parts to each FlatBuffer `union`. The first, is
a hidden field `_type`, that is generated to hold the type of `table` referred
@@ -1625,6 +1813,12 @@ Here is a repetition these lines, to help highlight them more clearly:
Monster.addEquipped(axe); // Union data
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
Monster.addEquippedType(builder, Equipment.Weapon) // Union type
Monster.addEquipped(axe) // Union data
~~~
</div>
<div class="language-csharp">
~~~{.cs}
Monster.AddEquippedType(builder, Equipment.Weapon); // Union type
@@ -1687,8 +1881,8 @@ Here is a repetition these lines, to help highlight them more clearly:
</div>
<div class="language-lobster">
~~~{.lobster}
builder.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
builder.MyGame_Sample_MonsterAddEquipped(axe)
.add_equipped_type(MyGame_Sample_Equipment_Weapon)
.add_equipped(axe)
~~~
</div>
<div class="language-rust">
@@ -1699,6 +1893,13 @@ Here is a repetition these lines, to help highlight them more clearly:
monster_builder.add_equipped(axe.as_union_value()); // Union data
~~~
</div>
<div class="language-swift">
~~~{.swift}
Monster.add(equippedType: .weapon, builder) // Type of union
Monster.add(equipped: axe, builder) // Union data
~~~
</div>
After you have created your buffer, you will have the offset to the root of the
data in the `orc` variable, so you can finish the buffer by calling the
@@ -1720,6 +1921,12 @@ appropriate `finish` method.
builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
// Call `finish()` to instruct the builder that this monster is complete.
builder.finish(orc) // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
~~~
</div>
<div class="language-csharp">
~~~{.cs}
// Call `Finish()` to instruct the builder that this monster is complete.
@@ -1788,6 +1995,12 @@ appropriate `finish` method.
builder.finish(orc, None);
~~~
</div>
<div class="language-swift">
~~~{.swift}
// Call `finish(offset:)` to instruct the builder that this monster is complete.
builder.finish(offset: orc)
~~~
</div>
The buffer is now ready to be stored somewhere, sent over the network, be
compressed, or whatever you'd like to do with it. You can access the buffer
@@ -1812,6 +2025,17 @@ like so:
byte[] buf = builder.sizedByteArray();
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
// This must be called after `finish()`.
val buf = builder.dataBuffer()
// The data in this ByteBuffer does NOT start at 0, but at buf.position().
// The number of bytes is buf.remaining().
// Alternatively this copies the above data out of the ByteBuffer for you:
val buf = builder.sizedByteArray()
~~~
</div>
<div class="language-csharp">
~~~{.cs}
// This must be called after `Finish()`.
@@ -1905,6 +2129,15 @@ like so:
~~~
</div>
<div class="language-swift">
~~~{.swift}
// This must be called after `finish()`.
// `sizedByteArray` returns the finished buf of type [UInt8].
let buf = builder.sizedByteArray
// or you can use to get an object of type Data
let bufData = ByteBuffer(data: builder.data)
~~~
</div>
Now you can write the bytes to a file, send them over the network..
**Make sure your file mode (or transfer protocol) is set to BINARY, not text.**
@@ -1934,6 +2167,13 @@ before:
import com.google.flatbuffers.FlatBufferBuilder;
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
import com.google.flatbuffers.FlatBufferBuilder
~~~
</div>
<div class="language-csharp">
~~~{.cs}
using FlatBuffers;
@@ -2033,8 +2273,8 @@ import './monster_my_game.sample_generated.dart' as myGame;
</div>
<div class="language-lobster">
~~~{.lobster}
include from "../lobster/" // Where to find flatbuffers.lobster
include "monster_generated.lobster"
import from "../lobster/" // Where to find flatbuffers.lobster
import monster_generated
~~~
</div>
<div class="language-rust">
@@ -2082,6 +2322,15 @@ won't work**
Monster monster = Monster.getRootAsMonster(buf);
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
val bytes = /* the data you just read */
val buf = java.nio.ByteBuffer.wrap(bytes)
// Get an accessor to the root object inside the buffer.
Monster monster = Monster.getRootAsMonster(buf)
~~~
</div>
<div class="language-csharp">
~~~{.cs}
byte[] bytes = /* the data you just read */
@@ -2189,6 +2438,16 @@ myGame.Monster monster = new myGame.Monster(data);
~~~
</div>
<div class="language-swift">
~~~{.swift}
// create a ByteBuffer(:) from an [UInt8] or Data()
let buf = // Get your data
// Get an accessor to the root object inside the buffer.
let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
~~~
</div>
If you look in the generated files from the schema compiler, you will see it generated
accessors for all non-`deprecated` fields. For example:
@@ -2206,6 +2465,13 @@ accessors for all non-`deprecated` fields. For example:
String name = monster.name();
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
val hp = monster.hp
val mana = monster.mana
val name = monster.name
~~~
</div>
<div class="language-csharp">
~~~{.cs}
// For C#, unlike most other languages support by FlatBuffers, most values (except for
@@ -2289,6 +2555,14 @@ accessors for all non-`deprecated` fields. For example:
~~~
</div>
<div class="language-swift">
~~~{.swift}
let hp = monster.hp
let mana = monster.mana
let name = monster.name // returns an optional string
~~~
</div>
These should hold `300`, `150`, and `"Orc"` respectively.
*Note: The default value `150` wasn't stored in `mana`, but we are still able to retrieve it.*
@@ -2311,6 +2585,14 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
float z = pos.z();
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
val pos = monster.pos!!
val x = pos.x
val y = pos.y
val z = pos.z
~~~
</div>
<div class="language-csharp">
~~~{.cs}
var pos = monster.Pos.Value;
@@ -2406,6 +2688,15 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
~~~
</div>
<div class="language-swift">
~~~{.swift}
let pos = monster.pos
let x = pos.x
let y = pos.y
let z = pos.z
~~~
</div>
`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.
*Note: Had we not set `pos` during serialization, it would be a `NULL`-value.*
@@ -2417,7 +2708,7 @@ FlatBuffers `vector`.
<div class="language-cpp">
~~~{.cpp}
auto inv = monster->inventory(); // A pointer to a `flatbuffers::Vector<>`.
auto inv_len = inv->Length();
auto inv_len = inv->size();
auto third_item = inv->Get(2);
~~~
</div>
@@ -2427,6 +2718,12 @@ FlatBuffers `vector`.
byte thirdItem = monster.inventory(2);
~~~
</div>
<div class="language-kotlin">
~~~{.kotlin}
val invLength = monster.inventoryLength
val thirdItem = monster.inventory(2)!!
~~~
</div>
<div class="language-csharp">
~~~{.cs}
int invLength = monster.InventoryLength;
@@ -2500,13 +2797,27 @@ FlatBuffers `vector`.
~~~
</div>
<div class="language-swift">
~~~{.swift}
// Get a the count of objects in the vector
let count = monster.inventoryCount
// get item at index 4
let object = monster.inventory(at: 4)
// or you can fetch the entire array
let inv = monster.inventory
// inv[4] should equal object
~~~
</div>
For `vector`s of `table`s, you can access the elements like any other vector,
except your need to handle the result as a FlatBuffer `table`:
<div class="language-cpp">
~~~{.cpp}
auto weapons = monster->weapons(); // A pointer to a `flatbuffers::Vector<>`.
auto weapon_len = weapons->Length();
auto weapon_len = weapons->size();
auto second_weapon_name = weapons->Get(1)->name()->str();
auto second_weapon_damage = weapons->Get(1)->damage()
~~~
@@ -2518,6 +2829,13 @@ except your need to handle the result as a FlatBuffer `table`:
short secondWeaponDamage = monster.weapons(1).damage();
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
val weaponsLength = monster.weaponsLength
val secondWeaponName = monster.weapons(1)!!.name
val secondWeaponDamage = monster.weapons(1)!!.damage
~~~
</div>
<div class="language-csharp">
~~~{.cs}
int weaponsLength = monster.WeaponsLength;
@@ -2605,6 +2923,16 @@ except your need to handle the result as a FlatBuffer `table`:
let second_weapon_damage = wep2.damage();
~~~
</div>
<div class="language-swift">
~~~{.swift}
// Get the count of weapon objects
let wepsCount = monster.weaponsCount
let weapon2 = monster.weapons(at: 1)
let weaponName = weapon2.name
let weaponDmg = weapon2.damage
~~~
</div>
Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created
the `union`, we need to get both parts of the `union`: the type and the data.
@@ -2638,6 +2966,19 @@ We can access the type to dynamically cast the data as needed (since the
}
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
val unionType = monster.EquippedType
if (unionType == Equipment.Weapon) {
val weapon = monster.equipped(Weapon()) as Weapon // Requires explicit cast
// to `Weapon`.
val weaponName = weapon.name // "Axe"
val weaponDamage = weapon.damage // 5
}
~~~
</div>
<div class="language-csharp">
~~~{.cs}
var unionType = monster.EquippedType;
@@ -2779,6 +3120,17 @@ We can access the type to dynamically cast the data as needed (since the
~~~
</div>
<div class="language-swift">
~~~{.swift}
// Get and check if the monster has an equipped item
if monster.equippedType == .weapon {
let _weapon = monster.equipped(type: Weapon.self)
let name = _weapon.name // should return "Axe"
let dmg = _weapon.damage // should return 5
}
~~~
</div>
## Mutating FlatBuffers
As you saw above, typically once you have created a FlatBuffer, it is read-only
@@ -2814,6 +3166,14 @@ mutators like so:
monster.mutateInventory(0, 1); // Set vector element.
~~~
</div>
<div class="language-kotlin">
~~~{.kt}
val monster = Monster.getRootAsMonster(buf)
monster.mutateHp(10) // Set table field.
monster.pos!!.mutateZ(4) // Set struct field.
monster.mutateInventory(0, 1) // Set vector element.
~~~
</div>
<div class="language-csharp">
~~~{.cs}
var monster = Monster.GetRootAsMonster(buf);
@@ -2874,6 +3234,15 @@ mutators like so:
~~~
</div>
<div class="language-swift">
~~~{.swift}
let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
monster.mutate(hp: 10) // mutates a value in a table
monster.pos.mutate(z: 4) // mutates a value in a struct
monster.mutate(inventory: 6, at index: 0) // mutates a value in an Scalar array
~~~
</div>
We use the somewhat verbose term `mutate` instead of `set` to indicate that this
is a special use case, not to be confused with the default way of constructing
FlatBuffer data.
@@ -2897,16 +3266,18 @@ If this is not sufficient, other ways of mutating FlatBuffers may be supported
in your language through an object based API (`--gen-object-api`) or reflection.
See the individual language documents for support.
## JSON with FlatBuffers
## Using `flatc` as a JSON Conversion Tool
#### Using `flatc` as a Conversion Tool
This is often the preferred method to use JSON with FlatBuffers, as it doesn't
require you to add any new code to your program. It is also efficient, since you
can ship with the binary data. The drawback is that it requires an extra step
for your users/developers to perform (although it may be able to be automated
If you are working with C, C++, or Lobster, you can parse JSON at runtime.
If your language does not support JSON at the moment, `flatc` may provide an
alternative. Using `flatc` is often the preferred method, as it doesn't require you to
add any new code to your program. It is also efficient, since you can ship with
the binary data. The drawback is that it requires an extra step for your
users/developers to perform (although it may be able to be automated
as part of your compilation).
#### JSON to binary representation
Lets say you have a JSON file that describes your monster. In this example,
we will use the file `flatbuffers/samples/monsterdata.json`.
@@ -2915,16 +3286,31 @@ Here are the contents of the file:
~~~{.json}
{
pos: {
x: 1,
y: 2,
z: 3
x: 1.0,
y: 2.0,
z: 3.0
},
hp: 300,
name: "Orc"
name: "Orc",
weapons: [
{
name: "axe",
damage: 100
},
{
name: "bow",
damage: 90
}
],
equipped_type: "Weapon",
equipped: {
name: "bow",
damage: 90
}
}
~~~
You can run this file through the `flatc` compile with the `-b` flag and
You can run this file through the `flatc` compiler with the `-b` flag and
our `monster.fbs` schema to produce a FlatBuffer binary file.
~~~{.sh}
@@ -2953,6 +3339,30 @@ for `flatcc` to support this.*
Guide for more information.*
</div>
#### FlatBuffer binary to JSON
Converting from a FlatBuffer binary representation to JSON is supported as well:
~~~{.sh}
./../flatc --json --raw-binary monster.fbs -- monsterdata.bin
~~~
This will convert `monsterdata.bin` back to its original JSON representation.
You need to pass the corresponding FlatBuffers schema so that flatc knows how to
interpret the binary buffer. Since `monster.fbs` does not specify an explicit
`file_identifier` for binary buffers, `flatc` needs to be forced into reading
the `.bin` file using the `--raw-binary` option.
The FlatBuffer binary representation does not explicitly encode default values,
therefore they are not present in the resulting JSON unless you specify
`--defaults-json`.
If you intend to process the JSON with other tools, you may consider switching
on `--strict-json` so that identifiers are quoted properly.
*Note: The resulting JSON file is not necessarily identical with the original JSON.
If the binary representation contains floating point numbers, floats and doubles
are rounded to 6 and 12 digits, respectively, in order to represent them as
decimals in the JSON document. *
## Advanced Features for Each Language
Each language has a dedicated `Use in XXX` page in the Programmer's Guide
@@ -2964,10 +3374,13 @@ For your chosen language, see:
[Use in C++](@ref flatbuffers_guide_use_cpp)
</div>
<div class="language-java">
[Use in Java/C#](@ref flatbuffers_guide_use_java_c-sharp)
[Use in Java](@ref flatbuffers_guide_use_java)
</div>
<div class="language-kotlin">
[Use in Kotlin](@ref flatbuffers_guide_use_kotlin)
</div>
<div class="language-csharp">
[Use in Java/C#](@ref flatbuffers_guide_use_java_c-sharp)
[Use in C#](@ref flatbuffers_guide_use_c-sharp)
</div>
<div class="language-go">
[Use in Go](@ref flatbuffers_guide_use_go)
@@ -2999,5 +3412,7 @@ For your chosen language, see:
<div class="language-rust">
[Use in Rust](@ref flatbuffers_guide_use_rust)
</div>
<div class="language-swift">
[Use in Swift](@ref flatbuffers_guide_use_swift)
</div>
<br>

View File

@@ -43,7 +43,7 @@ First, include the library and generated code. Then read the file into an
the ByteBuffer to the `getRootAsMonster` function.
~~~{.ts}
// note: import flabuffers with your desired import method
// note: import flatbuffers with your desired import method
import { MyGame } from './monster_generated';

View File

@@ -778,7 +778,7 @@ INPUT = "FlatBuffers.md" \
"../../php/FlatbufferBuilder.php" \
"../../net/FlatBuffers/FlatBufferBuilder.cs" \
"../../include/flatbuffers/flatbuffers.h" \
"../../go/builder.go"
"../../go/builder.go" \
"../../rust/flatbuffers/src/builder.rs"
# This tag can be used to specify the character encoding of the source files

View File

@@ -29,8 +29,10 @@
title="Use in C"/>
<tab type="user" url="@ref flatbuffers_guide_use_go"
title="Use in Go"/>
<tab type="user" url="@ref flatbuffers_guide_use_java_c-sharp"
title="Use in Java/C#"/>
<tab type="user" url="@ref flatbuffers_guide_use_java"
title="Use in Java"/>
<tab type="user" url="@ref flatbuffers_guide_use_c-sharp"
title="Use in C#"/>
<tab type="user" url="@ref flatbuffers_guide_use_javascript"
title="Use in JavaScript"/>
<tab type="user" url="@ref flatbuffers_guide_use_typescript"
@@ -48,7 +50,7 @@
<tab type="user" url="@ref flatbuffers_guide_use_rust"
title="Use in Rust"/>
<tab type="user" url="@ref flexbuffers"
title="Schema-less version"/>
title="FlexBuffers (Schema-less version)"/>
<tab type="usergroup" url="" title="gRPC">
<tab type="user" url="@ref flatbuffers_grpc_guide_use_cpp"
title="Use in C++"/>

View File

@@ -1,5 +1,11 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
alias(
name = "go_default_library",
actual = ":go",
visibility = ["//visibility:public"],
)
go_library(
name = "go",
srcs = [

View File

@@ -17,6 +17,8 @@ type Builder struct {
head UOffsetT
nested bool
finished bool
sharedStrings map[string]UOffsetT
}
const fileIdentifierLength = 4
@@ -33,7 +35,6 @@ func NewBuilder(initialSize int) *Builder {
b.head = UOffsetT(initialSize)
b.minalign = 1
b.vtables = make([]UOffsetT, 0, 16) // sensible default capacity
return b
}
@@ -307,6 +308,20 @@ func (b *Builder) EndVector(vectorNumElems int) UOffsetT {
return b.Offset()
}
// CreateSharedString Checks if the string is already written
// to the buffer before calling CreateString
func (b *Builder) CreateSharedString(s string) UOffsetT {
if b.sharedStrings == nil {
b.sharedStrings = make(map[string]UOffsetT)
}
if v, ok := b.sharedStrings[s]; ok {
return v
}
off := b.CreateString(s)
b.sharedStrings[s] = off
return off
}
// CreateString writes a null-terminated string as a vector.
func (b *Builder) CreateString(s string) UOffsetT {
b.assertNotNested()

View File

@@ -3,21 +3,36 @@ package flatbuffers
// Codec implements gRPC-go Codec which is used to encode and decode messages.
var Codec = "flatbuffers"
// FlatbuffersCodec defines the interface gRPC uses to encode and decode messages. Note
// that implementations of this interface must be thread safe; a Codec's
// methods can be called from concurrent goroutines.
type FlatbuffersCodec struct{}
// Marshal returns the wire format of v.
func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
return v.(*Builder).FinishedBytes(), nil
}
// Unmarshal parses the wire format into v.
func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
v.(flatbuffersInit).Init(data, GetUOffsetT(data))
return nil
}
// String old gRPC Codec interface func
func (FlatbuffersCodec) String() string {
return Codec
}
// Name returns the name of the Codec implementation. The returned string
// will be used as part of content type in transmission. The result must be
// static; the result cannot change between calls.
//
// add Name() for ForceCodec interface
func (FlatbuffersCodec) Name() string {
return Codec
}
type flatbuffersInit interface {
Init(data []byte, i UOffsetT)
}

View File

@@ -5,7 +5,7 @@ grpc_1_15_1_githash=1a60e6971f428323245a930031ad267bb3142ba4
function build_grpc () {
git clone https://github.com/grpc/grpc.git google/grpc
cd google/grpc
git checkout ${grpc_1_15_1_githash}
git checkout ${grpc_1_15_1_githash}
git submodule update --init
make
make install prefix=`pwd`/install

View File

@@ -6,7 +6,7 @@
<parent>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-parent</artifactId>
<version>1.11.0</version>
<version>1.12.0</version>
</parent>
<artifactId>flatbuffers-java-grpc</artifactId>
<name>${project.artifactId}</name>
@@ -24,7 +24,7 @@
</developer>
</developers>
<properties>
<gRPC.version>1.11.0</gRPC.version>
<gRPC.version>1.12.0</gRPC.version>
</properties>
<dependencies>
<dependency>

View File

@@ -4,7 +4,7 @@
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-parent</artifactId>
<packaging>pom</packaging>
<version>1.11.0</version>
<version>1.12.0</version>
<name>flatbuffers-parent</name>
<description>parent pom for flatbuffers java artifacts</description>
<properties>
@@ -185,6 +185,12 @@
<goals>
<goal>sign</goal>
</goals>
<configuration>
<gpgArguments>
<arg>--pinentry-mode</arg>
<arg>loopback</arg>
</gpgArguments>
</configuration>
</execution>
</executions>
</plugin>

View File

@@ -12,7 +12,8 @@ class GreeterServiceImpl final : public Greeter::Service {
grpc::ServerContext *context,
const flatbuffers::grpc::Message<HelloRequest> *request_msg,
flatbuffers::grpc::Message<HelloReply> *response_msg) override {
// flatbuffers::grpc::MessageBuilder mb_;
flatbuffers::grpc::MessageBuilder mb_;
// We call GetRoot to "parse" the message. Verification is already
// performed by default. See the notes below for more details.
const HelloRequest *request = request_msg->GetRoot();

107
grpc/src/compiler/BUILD Normal file
View File

@@ -0,0 +1,107 @@
load("@rules_cc//cc:defs.bzl", "cc_library")
package(
default_visibility = ["//visibility:public"],
)
filegroup(
name = "common_headers",
srcs = [
"config.h",
"schema_interface.h",
],
)
cc_library(
name = "cpp_generator",
srcs = [
"cpp_generator.cc",
],
hdrs = [
"cpp_generator.h",
":common_headers",
],
include_prefix = "src/compiler",
strip_include_prefix = "/grpc/src/compiler",
deps = [
"//:flatbuffers",
],
)
cc_library(
name = "go_generator",
srcs = [
"go_generator.cc",
],
hdrs = [
"go_generator.h",
":common_headers",
],
include_prefix = "src/compiler",
strip_include_prefix = "/grpc/src/compiler",
deps = [
"//:flatbuffers",
],
)
cc_library(
name = "java_generator",
srcs = [
"java_generator.cc",
],
hdrs = [
"java_generator.h",
":common_headers",
],
include_prefix = "src/compiler",
strip_include_prefix = "/grpc/src/compiler",
deps = [
"//:flatbuffers",
],
)
cc_library(
name = "python_generator",
hdrs = [
"python_generator.h",
],
include_prefix = "src/compiler",
strip_include_prefix = "/grpc/src/compiler",
deps = [
":python_generator_private",
],
)
cc_library(
name = "python_generator_private",
srcs = [
"python_generator.cc",
],
hdrs = [
"python_generator.h",
"python_private_generator.h",
":common_headers",
],
include_prefix = "src/compiler",
strip_include_prefix = "/grpc/src/compiler",
visibility = ["//visibility:private"],
deps = [
"//:flatbuffers",
],
)
cc_library(
name = "swift_generator",
srcs = [
"swift_generator.cc",
],
hdrs = [
"swift_generator.h",
":common_headers",
],
include_prefix = "src/compiler",
strip_include_prefix = "/grpc/src/compiler",
deps = [
"//:flatbuffers",
],
)

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
#include "java_generator.h"
#include "src/compiler/java_generator.h"
#include <algorithm>
#include <iostream>

View File

@@ -0,0 +1,624 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <ostream>
#include <set>
#include <sstream>
#include <tuple>
#include <vector>
#include "flatbuffers/util.h"
#include "src/compiler/python_generator.h"
#include "src/compiler/python_private_generator.h"
using std::make_pair;
using std::map;
using std::pair;
using std::replace;
using std::tuple;
using std::vector;
using std::set;
namespace grpc_python_generator {
grpc::string generator_file_name;
typedef map<grpc::string, grpc::string> StringMap;
typedef vector<grpc::string> StringVector;
typedef tuple<grpc::string, grpc::string> StringPair;
typedef set<StringPair> StringPairSet;
// Provides RAII indentation handling. Use as:
// {
// IndentScope raii_my_indent_var_name_here(my_py_printer);
// // constructor indented my_py_printer
// ...
// // destructor called at end of scope, un-indenting my_py_printer
// }
class IndentScope {
public:
explicit IndentScope(grpc_generator::Printer* printer) : printer_(printer) {
printer_->Indent();
}
~IndentScope() { printer_->Outdent(); }
private:
grpc_generator::Printer* printer_;
};
inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
const grpc::string& to, bool replace_all) {
size_t pos = 0;
do {
pos = str.find(from, pos);
if (pos == grpc::string::npos) {
break;
}
str.replace(pos, from.length(), to);
pos += to.length();
} while (replace_all);
return str;
}
inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
const grpc::string& to) {
return StringReplace(str, from, to, true);
}
grpc::string ModuleName(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string basename = flatbuffers::StripExtension(filename);
basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", ".");
return import_prefix + basename + "_fb";
}
grpc::string ModuleAlias(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string module_name = ModuleName(filename, import_prefix);
// We can't have dots in the module name, so we replace each with _dot_.
// But that could lead to a collision between a.b and a_dot_b, so we also
// duplicate each underscore.
module_name = StringReplace(module_name, "_", "__");
module_name = StringReplace(module_name, ".", "_dot_");
return module_name;
}
PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config_,
const grpc_generator::File* file_)
: config(config_), file(file_) {}
void PrivateGenerator::PrintBetaServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class Beta$Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This class was "
"generated\n"
"only to ease transition from grpcio<0.15.0 to "
"grpcio>=0.15.0.\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
{
IndentScope raii_method_indent(out);
out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
}
}
}
}
void PrivateGenerator::PrintBetaStub(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class Beta$Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This class was "
"generated\n"
"only to ease transition from grpcio<0.15.0 to "
"grpcio>=0.15.0.\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print(method_dict,
"def $Method$(self, $ArgName$, timeout, metadata=None, "
"with_call=False, protocol_options=None):\n");
{
IndentScope raii_method_indent(out);
out->Print("raise NotImplementedError()\n");
}
if (!method->ServerStreaming()) {
out->Print(method_dict, "$Method$.future = None\n");
}
}
}
}
void PrivateGenerator::PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict,
"def beta_create_$Service$_server(servicer, pool=None, "
"pool_size=None, default_timeout=None, maximum_timeout=None):\n");
{
IndentScope raii_create_server_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This function was\n"
"generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
"\"\"\"\n");
StringMap method_implementation_constructors;
StringMap input_message_modules_and_classes;
StringMap output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
const grpc::string method_implementation_constructor =
grpc::string(method->ClientStreaming() ? "stream_" : "unary_") +
grpc::string(method->ServerStreaming() ? "stream_" : "unary_") +
"inline";
grpc::string input_message_module_and_class = method->get_fb_builder();
grpc::string output_message_module_and_class = method->get_fb_builder();
method_implementation_constructors.insert(
make_pair(method->name(), method_implementation_constructor));
input_message_modules_and_classes.insert(
make_pair(method->name(), input_message_module_and_class));
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
// out->Print("request_deserializers = {\n");
// for (StringMap::iterator name_and_input_module_class_pair =
// input_message_modules_and_classes.begin();
// name_and_input_module_class_pair !=
// input_message_modules_and_classes.end();
// name_and_input_module_class_pair++) {
// method_dict["MethodName"] = name_and_input_module_class_pair->first;
// method_dict["InputTypeModuleAndClass"] =
// name_and_input_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$InputTypeModuleAndClass$.FromString,\n");
// }
// out->Print("}\n");
// out->Print("response_serializers = {\n");
// for (StringMap::iterator name_and_output_module_class_pair =
// output_message_modules_and_classes.begin();
// name_and_output_module_class_pair !=
// output_message_modules_and_classes.end();
// name_and_output_module_class_pair++) {
// method_dict["MethodName"] = name_and_output_module_class_pair->first;
// method_dict["OutputTypeModuleAndClass"] =
// name_and_output_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$OutputTypeModuleAndClass$.SerializeToString,\n");
// }
// out->Print("}\n");
out->Print("method_implementations = {\n");
for (StringMap::iterator name_and_implementation_constructor =
method_implementation_constructors.begin();
name_and_implementation_constructor !=
method_implementation_constructors.end();
name_and_implementation_constructor++) {
method_dict["Method"] = name_and_implementation_constructor->first;
method_dict["Constructor"] = name_and_implementation_constructor->second;
IndentScope raii_descriptions_indent(out);
const grpc::string method_name =
name_and_implementation_constructor->first;
out->Print(method_dict,
"(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
"face_utilities.$Constructor$(servicer.$Method$),\n");
}
out->Print("}\n");
out->Print(
"server_options = beta_implementations.server_options("
"thread_pool=pool, thread_pool_size=pool_size, "
"default_timeout=default_timeout, "
"maximum_timeout=maximum_timeout)\n");
out->Print(
"return beta_implementations.server(method_implementations, "
"options=server_options)\n");
//"request_deserializers=request_deserializers, "
//"response_serializers=response_serializers, "
}
}
void PrivateGenerator::PrintBetaStubFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap dict;
dict["Service"] = service->name();
out->Print("\n\n");
out->Print(dict,
"def beta_create_$Service$_stub(channel, host=None,"
" metadata_transformer=None, pool=None, pool_size=None):\n");
{
IndentScope raii_create_server_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This function was\n"
"generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
"\"\"\"\n");
StringMap method_cardinalities;
StringMap input_message_modules_and_classes;
StringMap output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
const grpc::string method_cardinality =
grpc::string(method->ClientStreaming() ? "STREAM" : "UNARY") +
"_" +
grpc::string(method->ServerStreaming() ? "STREAM" : "UNARY");
grpc::string input_message_module_and_class = method->get_fb_builder();
grpc::string output_message_module_and_class = method->get_fb_builder();
method_cardinalities.insert(
make_pair(method->name(), method_cardinality));
input_message_modules_and_classes.insert(
make_pair(method->name(), input_message_module_and_class));
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
// out->Print("request_serializers = {\n");
// for (StringMap::iterator name_and_input_module_class_pair =
// input_message_modules_and_classes.begin();
// name_and_input_module_class_pair !=
// input_message_modules_and_classes.end();
// name_and_input_module_class_pair++) {
// method_dict["MethodName"] = name_and_input_module_class_pair->first;
// method_dict["InputTypeModuleAndClass"] =
// name_and_input_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$InputTypeModuleAndClass$.SerializeToString,\n");
// }
// out->Print("}\n");
// out->Print("response_deserializers = {\n");
// for (StringMap::iterator name_and_output_module_class_pair =
// output_message_modules_and_classes.begin();
// name_and_output_module_class_pair !=
// output_message_modules_and_classes.end();
// name_and_output_module_class_pair++) {
// method_dict["MethodName"] = name_and_output_module_class_pair->first;
// method_dict["OutputTypeModuleAndClass"] =
// name_and_output_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$OutputTypeModuleAndClass$.FromString,\n");
// }
// out->Print("}\n");
out->Print("cardinalities = {\n");
for (StringMap::iterator name_and_cardinality =
method_cardinalities.begin();
name_and_cardinality != method_cardinalities.end();
name_and_cardinality++) {
method_dict["Method"] = name_and_cardinality->first;
method_dict["Cardinality"] = name_and_cardinality->second;
IndentScope raii_descriptions_indent(out);
out->Print(method_dict,
"\'$Method$\': cardinality.Cardinality.$Cardinality$,\n");
}
out->Print("}\n");
out->Print(
"stub_options = beta_implementations.stub_options("
"host=host, metadata_transformer=metadata_transformer, "
"thread_pool=pool, thread_pool_size=pool_size)\n");
out->Print(method_dict,
"return beta_implementations.dynamic_stub(channel, "
"\'$PackageQualifiedServiceName$\', "
"cardinalities, options=stub_options)\n");
// "request_serializers=request_serializers, "
//"response_deserializers=response_deserializers, "
}
}
void PrivateGenerator::PrintStub(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap dict;
dict["Service"] = service->name();
out->Print("\n\n");
out->Print(dict, "class $Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print("\n");
out->Print("def __init__(self, channel):\n");
{
IndentScope raii_init_indent(out);
out->Print("\"\"\"Constructor.\n");
out->Print("\n");
out->Print("Args:\n");
{
IndentScope raii_args_indent(out);
out->Print("channel: A grpc.Channel.\n");
}
out->Print("\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string multi_callable_constructor =
grpc::string(method->ClientStreaming() ? "stream" : "unary") +
"_" +
grpc::string(method->ServerStreaming() ? "stream" : "unary");
grpc::string request_module_and_class = method->get_fb_builder();
grpc::string response_module_and_class = method->get_fb_builder();
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["MultiCallableConstructor"] = multi_callable_constructor;
out->Print(method_dict,
"self.$Method$ = channel.$MultiCallableConstructor$(\n");
{
method_dict["PackageQualifiedService"] =
package_qualified_service_name;
method_dict["RequestModuleAndClass"] = request_module_and_class;
method_dict["ResponseModuleAndClass"] = response_module_and_class;
IndentScope raii_first_attribute_indent(out);
IndentScope raii_second_attribute_indent(out);
out->Print(method_dict, "'/$PackageQualifiedService$/$Method$',\n");
out->Print(method_dict,"\n");
out->Print(
method_dict,"\n");
out->Print(")\n");
}
}
}
}
}
void PrivateGenerator::PrintServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class $Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print("\n");
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
{
IndentScope raii_method_indent(out);
out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
out->Print("context.set_details('Method not implemented!')\n");
out->Print("raise NotImplementedError('Method not implemented!')\n");
}
}
}
}
void PrivateGenerator::PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict,
"def add_$Service$Servicer_to_server(servicer, server):\n");
{
IndentScope raii_class_indent(out);
out->Print("rpc_method_handlers = {\n");
{
IndentScope raii_dict_first_indent(out);
IndentScope raii_dict_second_indent(out);
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string method_handler_constructor =
grpc::string(method->ClientStreaming() ? "stream" : "unary") +
"_" +
grpc::string(method->ServerStreaming() ? "stream" : "unary") +
"_rpc_method_handler";
grpc::string request_module_and_class = method->get_fb_builder();
grpc::string response_module_and_class = method->get_fb_builder();
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["MethodHandlerConstructor"] = method_handler_constructor;
method_dict["RequestModuleAndClass"] = request_module_and_class;
method_dict["ResponseModuleAndClass"] = response_module_and_class;
out->Print(method_dict,
"'$Method$': grpc.$MethodHandlerConstructor$(\n");
{
IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out);
out->Print(method_dict, "servicer.$Method$,\n");
out->Print(
method_dict,"\n");
out->Print(
method_dict,
"\n");
}
out->Print("),\n");
}
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
out->Print("}\n");
out->Print("generic_handler = grpc.method_handlers_generic_handler(\n");
{
IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out);
out->Print(method_dict,
"'$PackageQualifiedServiceName$', rpc_method_handlers)\n");
}
out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
}
}
void PrivateGenerator::PrintBetaPreamble(grpc_generator::Printer* out) {
StringMap var;
var["Package"] = config.beta_package_root;
out->Print(var,
"from $Package$ import implementations as beta_implementations\n");
out->Print(var, "from $Package$ import interfaces as beta_interfaces\n");
out->Print("from grpc.framework.common import cardinality\n");
out->Print(
"from grpc.framework.interfaces.face import utilities as "
"face_utilities\n");
}
void PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
StringMap var;
var["Package"] = config.grpc_package_root;
out->Print(var, "import $Package$\n");
out->Print("\n");
StringPairSet imports_set;
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
for (int j = 0; j < service->method_count(); ++j) {
auto method = service.get()->method(j);
grpc::string input_type_file_name = method->get_fb_builder();
grpc::string input_module_name =
ModuleName(input_type_file_name, config.import_prefix);
grpc::string input_module_alias =
ModuleAlias(input_type_file_name, config.import_prefix);
imports_set.insert(
std::make_tuple(input_module_name, input_module_alias));
grpc::string output_type_file_name = method->get_fb_builder();
grpc::string output_module_name =
ModuleName(output_type_file_name, config.import_prefix);
grpc::string output_module_alias =
ModuleAlias(output_type_file_name, config.import_prefix);
imports_set.insert(
std::make_tuple(output_module_name, output_module_alias));
}
}
for (StringPairSet::iterator it = imports_set.begin();
it != imports_set.end(); ++it) {
var["ModuleName"] = std::get<0>(*it);
var["ModuleAlias"] = std::get<1>(*it);
out->Print(var, "import $ModuleName$ as $ModuleAlias$\n");
}
}
void PrivateGenerator::PrintGAServices(grpc_generator::Printer* out) {
grpc::string package = file->package();
if (!package.empty()) {
package = package.append(".");
}
out->Print(file->additional_headers().c_str());
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
grpc::string package_qualified_service_name = package + service->name();
PrintStub(package_qualified_service_name, service.get(), out);
PrintServicer(service.get(), out);
PrintAddServicerToServer(package_qualified_service_name, service.get(),
out);
}
}
void PrivateGenerator::PrintBetaServices(grpc_generator::Printer* out) {
grpc::string package = file->package();
if (!package.empty()) {
package = package.append(".");
}
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
grpc::string package_qualified_service_name = package + service->name();
PrintBetaServicer(service.get(), out);
PrintBetaStub(service.get(), out);
PrintBetaServerFactory(package_qualified_service_name, service.get(), out);
PrintBetaStubFactory(package_qualified_service_name, service.get(), out);
}
}
grpc::string PrivateGenerator::GetGrpcServices() {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
auto out = file->CreatePrinter(&output);
out->Print(
"# Generated by the gRPC Python protocol compiler plugin. "
"DO NOT EDIT!\n");
StringMap var;
var["Package"] = config.grpc_package_root;
out->Print(var, "import $Package$\n");
PrintGAServices(out.get());
out->Print("try:\n");
{
IndentScope raii_dict_try_indent(out.get());
out->Print(
"# THESE ELEMENTS WILL BE DEPRECATED.\n"
"# Please use the generated *_pb2_grpc.py files instead.\n");
out->Print(var, "import $Package$\n");
PrintBetaPreamble(out.get());
PrintGAServices(out.get());
PrintBetaServices(out.get());
}
out->Print("except ImportError:\n");
{
IndentScope raii_dict_except_indent(out.get());
out->Print("pass");
}
}
return output;
}
} // namespace grpc_python_generator

View File

@@ -0,0 +1,40 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
#include <utility>
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {
// Data pertaining to configuration of the generator with respect to anything
// that may be used internally at Google.
struct GeneratorConfiguration {
grpc::string grpc_package_root;
// TODO(https://github.com/grpc/grpc/issues/8622): Drop this.
grpc::string beta_package_root;
// TODO(https://github.com/google/protobuf/issues/888): Drop this.
grpc::string import_prefix;
};
} // namespace grpc_python_generator
#endif // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H

View File

@@ -0,0 +1,72 @@
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
#include <iostream>
#include <vector>
#include "src/compiler/python_generator.h"
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {
// Tucks all generator state in an anonymous namespace away from
// PythonGrpcGenerator and the header file, mostly to encourage future changes
// to not require updates to the grpcio-tools C++ code part. Assumes that it is
// only ever used from a single thread.
struct PrivateGenerator {
const GeneratorConfiguration& config;
const grpc_generator::File* file;
PrivateGenerator(const GeneratorConfiguration& config,
const grpc_generator::File* file);
grpc::string GetGrpcServices();
private:
void PrintPreamble(grpc_generator::Printer* out);
void PrintBetaPreamble(grpc_generator::Printer* out);
void PrintGAServices(grpc_generator::Printer* out);
void PrintBetaServices(grpc_generator::Printer* out);
void PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out);
void PrintServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintStub(const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out);
void PrintBetaStub(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service,
grpc_generator::Printer* out);
};
} // namespace grpc_python_generator
#endif // GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H

View File

@@ -1,44 +1,29 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
* Copyright 2015 gRPC authors.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* http://www.apache.org/licenses/LICENSE-2.0
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#include "src/compiler/config.h"
#include <memory>
#include <vector>
#include "src/compiler/config.h"
#ifndef GRPC_CUSTOM_STRING
# include <string>
# define GRPC_CUSTOM_STRING std::string
@@ -79,6 +64,9 @@ struct Method : public CommentHolder {
virtual grpc::string get_input_type_name() const = 0;
virtual grpc::string get_output_type_name() const = 0;
virtual grpc::string get_fb_builder() const = 0;
virtual bool NoStreaming() const = 0;
virtual bool ClientStreaming() const = 0;
virtual bool ServerStreaming() const = 0;

View File

@@ -0,0 +1,308 @@
/*
* Copyright 2020 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* NOTE: The following implementation is a translation for the Swift-grpc
* generator since flatbuffers doesnt allow plugins for now. if an issue arises
* please open an issue in the flatbuffers repository. This file should always
* be maintained according to the Swift-grpc repository
*/
#include <map>
#include <sstream>
#include "flatbuffers/util.h"
#include "src/compiler/schema_interface.h"
#include "src/compiler/swift_generator.h"
namespace grpc_swift_generator {
grpc::string GenerateMessage(const grpc::string &name) {
return "Message<" + name + ">";
}
// MARK: - Client
grpc::string GenerateClientFuncName(const grpc_generator::Method *method) {
if (method->NoStreaming()) {
return "$GenAccess$ func $MethodName$(_ request: $Input$"
", callOptions: CallOptions?$isNil$) -> UnaryCall<$Input$,$Output$>";
}
if (method->ClientStreaming()) {
return "$GenAccess$ func $MethodName$"
"(callOptions: CallOptions?$isNil$) -> "
"ClientStreamingCall<$Input$,$Output$>";
}
if (method->ServerStreaming()) {
return "$GenAccess$ func $MethodName$(_ request: $Input$"
", callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
") -> Void) -> ServerStreamingCall<$Input$, $Output$>";
}
return "$GenAccess$ func $MethodName$"
"(callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
") -> Void) -> BidirectionalStreamingCall<$Input$, $Output$>";
}
grpc::string GenerateClientFuncBody(const grpc_generator::Method *method) {
if (method->NoStreaming()) {
return "return self.makeUnaryCall(path: "
"\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
"callOptions: callOptions ?? self.defaultCallOptions)";
}
if (method->ClientStreaming()) {
return "return self.makeClientStreamingCall(path: "
"\"/$PATH$$ServiceName$/$MethodName$\", callOptions: callOptions ?? "
"self.defaultCallOptions)";
}
if (method->ServerStreaming()) {
return "return self.makeServerStreamingCall(path: "
"\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
"callOptions: callOptions ?? self.defaultCallOptions, handler: "
"handler)";
}
return "return self.makeBidirectionalStreamingCall(path: "
"\"/$PATH$$ServiceName$/$MethodName$\", callOptions: callOptions ?? "
"self.defaultCallOptions, handler: handler)";
}
void GenerateClientProtocol(const grpc_generator::Service *service,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> *dictonary) {
auto vars = *dictonary;
printer->Print(vars, "$ACCESS$ protocol $ServiceName$Service {\n");
vars["GenAccess"] = "";
for (auto it = 0; it < service->method_count(); it++) {
auto method = service->method(it);
vars["Input"] = GenerateMessage(method->get_input_type_name());
vars["Output"] = GenerateMessage(method->get_output_type_name());
vars["MethodName"] = method->name();
vars["isNil"] = "";
printer->Print("\t");
auto func = GenerateClientFuncName(method.get());
printer->Print(vars, func.c_str());
printer->Print("\n");
}
printer->Print("}\n\n");
}
void GenerateClientClass(const grpc_generator::Service *service,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> *dictonary) {
auto vars = *dictonary;
printer->Print(vars,
"$ACCESS$ final class $ServiceName$ServiceClient: GRPCClient, "
"$ServiceName$Service {\n");
printer->Print(vars, "\t$ACCESS$ let connection: ClientConnection\n");
printer->Print(vars, "\t$ACCESS$ var defaultCallOptions: CallOptions\n");
printer->Print("\n");
printer->Print(vars,
"\t$ACCESS$ init(connection: ClientConnection, "
"defaultCallOptions: CallOptions = CallOptions()) {\n");
printer->Print("\t\tself.connection = connection\n");
printer->Print("\t\tself.defaultCallOptions = defaultCallOptions\n");
printer->Print("\t}");
printer->Print("\n");
vars["GenAccess"] = "public";
for (auto it = 0; it < service->method_count(); it++) {
auto method = service->method(it);
vars["Input"] = GenerateMessage(method->get_input_type_name());
vars["Output"] = GenerateMessage(method->get_output_type_name());
vars["MethodName"] = method->name();
vars["isNil"] = " = nil";
printer->Print("\n\t");
auto func = GenerateClientFuncName(method.get());
printer->Print(vars, func.c_str());
printer->Print(" {\n");
auto body = GenerateClientFuncBody(method.get());
printer->Print("\t\t");
printer->Print(vars, body.c_str());
printer->Print("\n\t}\n");
}
printer->Print("}\n");
}
// MARK: - Server
grpc::string GenerateServerFuncName(const grpc_generator::Method *method) {
if (method->NoStreaming()) {
return "func $MethodName$(_ request: $Input$"
", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>";
}
if (method->ClientStreaming()) {
return "func $MethodName$(context: UnaryResponseCallContext<$Output$>) -> "
"EventLoopFuture<(StreamEvent<$Input$"
">) -> Void>";
}
if (method->ServerStreaming()) {
return "func $MethodName$(request: $Input$"
", context: StreamingResponseCallContext<$Output$>) -> "
"EventLoopFuture<GRPCStatus>";
}
return "func $MethodName$(context: StreamingResponseCallContext<$Output$>) "
"-> EventLoopFuture<(StreamEvent<$Input$>) -> Void>";
}
grpc::string GenerateServerExtensionBody(const grpc_generator::Method *method) {
grpc::string start = "\t\tcase \"$MethodName$\":\n\t\t";
if (method->NoStreaming()) {
return start +
"return UnaryCallHandler(callHandlerContext: callHandlerContext) { "
"context in"
"\n\t\t\t"
"return { request in"
"\n\t\t\t\t"
"self.$MethodName$(request, context: context)"
"\n\t\t\t}"
"\n\t\t}";
}
if (method->ClientStreaming()) {
return start +
"return ClientStreamingCallHandler(callHandlerContext: "
"callHandlerContext) { context in"
"\n\t\t\t"
"return { request in"
"\n\t\t\t\t"
"self.$MethodName$(request: request, context: context)"
"\n\t\t\t}"
"\n\t\t}";
}
if (method->ServerStreaming()) {
return start +
"return ServerStreamingCallHandler(callHandlerContext: "
"callHandlerContext) { context in"
"\n\t\t\t"
"return { request in"
"\n\t\t\t\t"
"self.$MethodName$(request: request, context: context)"
"\n\t\t\t}"
"\n\t\t}";
}
if (method->BidiStreaming()) {
return start +
"return BidirectionalStreamingCallHandler(callHandlerContext: "
"callHandlerContext) { context in"
"\n\t\t\t"
"return { request in"
"\n\t\t\t\t"
"self.$MethodName$(request: request, context: context)"
"\n\t\t\t}"
"\n\t\t}";
}
return "";
}
void GenerateServerProtocol(const grpc_generator::Service *service,
grpc_generator::Printer *printer,
std::map<grpc::string, grpc::string> *dictonary) {
auto vars = *dictonary;
printer->Print(
vars, "$ACCESS$ protocol $ServiceName$Provider: CallHandlerProvider {\n");
for (auto it = 0; it < service->method_count(); it++) {
auto method = service->method(it);
vars["Input"] = GenerateMessage(method->get_input_type_name());
vars["Output"] = GenerateMessage(method->get_output_type_name());
vars["MethodName"] = method->name();
printer->Print("\t");
auto func = GenerateServerFuncName(method.get());
printer->Print(vars, func.c_str());
printer->Print("\n");
}
printer->Print("}\n\n");
printer->Print(vars, "$ACCESS$ extension $ServiceName$Provider {\n");
printer->Print(vars,
"\tvar serviceName: String { return "
"\"$PATH$$ServiceName$\" }\n");
printer->Print(
"\tfunc handleMethod(_ methodName: String, callHandlerContext: "
"CallHandlerContext) -> GRPCCallHandler? {\n");
printer->Print("\t\tswitch methodName {\n");
for (auto it = 0; it < service->method_count(); it++) {
auto method = service->method(it);
vars["Input"] = GenerateMessage(method->get_input_type_name());
vars["Output"] = GenerateMessage(method->get_output_type_name());
vars["MethodName"] = method->name();
auto body = GenerateServerExtensionBody(method.get());
printer->Print(vars, body.c_str());
printer->Print("\n");
}
printer->Print("\t\tdefault: return nil;\n");
printer->Print("\t\t}\n");
printer->Print("\t}\n\n");
printer->Print("}\n\n");
}
grpc::string Generate(grpc_generator::File *file,
const grpc_generator::Service *service) {
grpc::string output;
std::map<grpc::string, grpc::string> vars;
vars["PATH"] = file->package();
if (!file->package().empty()) { vars["PATH"].append("."); }
vars["ServiceName"] = service->name();
vars["ACCESS"] = "public";
auto printer = file->CreatePrinter(&output);
printer->Print(vars,
"/// Usage: instantiate $ServiceName$ServiceClient, then call "
"methods of this protocol to make API calls.\n");
GenerateClientProtocol(service, &*printer, &vars);
GenerateClientClass(service, &*printer, &vars);
printer->Print("\n");
GenerateServerProtocol(service, &*printer, &vars);
return output;
}
grpc::string GenerateHeader() {
grpc::string code;
code +=
"/// The following code is generated by the Flatbuffers library which "
"might not be in sync with grpc-swift\n";
code +=
"/// in case of an issue please open github issue, though it would be "
"maintained\n";
code += "import Foundation\n";
code += "import GRPC\n";
code += "import NIO\n";
code += "import NIOHTTP1\n";
code += "import FlatBuffers\n";
code += "\n";
code +=
"public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage "
"{}\n";
code += "public extension GRPCFlatBufPayload {\n";
code += " init(serializedByteBuffer: inout NIO.ByteBuffer) throws {\n";
code +=
" self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: "
"serializedByteBuffer.readableBytesView, count: "
"serializedByteBuffer.readableBytes))\n";
code += " }\n";
code += " func serialize(into buffer: inout NIO.ByteBuffer) throws {\n";
code +=
" let buf = UnsafeRawBufferPointer(start: self.rawPointer, count: "
"Int(self.size))\n";
code += " buffer.writeBytes(buf)\n";
code += " }\n";
code += "}\n";
code += "extension Message: GRPCFlatBufPayload {}\n";
return code;
}
} // namespace grpc_swift_generator

View File

@@ -0,0 +1,55 @@
/*
*
* Copyright 2020, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <memory>
#include <vector>
#include "src/compiler/config.h"
#include "src/compiler/schema_interface.h"
#ifndef GRPC_CUSTOM_STRING
# include <string>
# define GRPC_CUSTOM_STRING std::string
#endif
namespace grpc {
typedef GRPC_CUSTOM_STRING string;
} // namespace grpc
namespace grpc_swift_generator {
grpc::string Generate(grpc_generator::File *file,
const grpc_generator::Service *service);
grpc::string GenerateHeader();
} // namespace grpc_swift_generator

View File

@@ -96,7 +96,7 @@ public class JavaGrpcTest {
if (monster.hp() > maxHp.get()) {
// Found a monster of higher hit points.
maxHp.set(monster.hp());
maxHpMonsterName.set(monster.name());
maxHpMonsterName.set(monster.name());
maxHpCount.set(1);
}
else if (monster.hp() == maxHp.get()) {
@@ -141,7 +141,7 @@ public class JavaGrpcTest {
channel = ManagedChannelBuilder.forAddress("localhost", port)
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
// needing certificates.
.usePlaintext(true)
.usePlaintext()
.directExecutor()
.build();
blockingStub = MonsterStorageGrpc.newBlockingStub(channel);
@@ -177,7 +177,7 @@ public class JavaGrpcTest {
final CountDownLatch streamAlive = new CountDownLatch(1);
StreamObserver<Stat> statObserver = new StreamObserver<Stat>() {
public void onCompleted() {
public void onCompleted() {
streamAlive.countDown();
}
public void onError(Throwable ex) { }

View File

@@ -14,17 +14,17 @@
* limitations under the License.
*/
#include <thread>
#include <grpc++/grpc++.h>
#include <thread>
#include "monster_test.grpc.fb.h"
#include "monster_test_generated.h"
#include "test_assert.h"
using namespace MyGame::Example;
using flatbuffers::grpc::MessageBuilder;
using flatbuffers::FlatBufferBuilder;
using flatbuffers::grpc::MessageBuilder;
void message_builder_tests();
@@ -97,8 +97,7 @@ void RunServer() {
server_instance->Wait();
}
template <class Builder>
void StoreRPC(MonsterStorage::Stub *stub) {
template<class Builder> void StoreRPC(MonsterStorage::Stub *stub) {
Builder fbb;
grpc::ClientContext context;
// Build a request with the name set.
@@ -119,8 +118,7 @@ void StoreRPC(MonsterStorage::Stub *stub) {
}
}
template <class Builder>
void RetrieveRPC(MonsterStorage::Stub *stub) {
template<class Builder> void RetrieveRPC(MonsterStorage::Stub *stub) {
Builder fbb;
grpc::ClientContext context;
fbb.Clear();
@@ -155,7 +153,6 @@ int grpc_server_test() {
RetrieveRPC<MessageBuilder>(stub.get());
RetrieveRPC<FlatBufferBuilder>(stub.get());
#if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
{
// Test that an invalid request errors out correctly
@@ -181,7 +178,7 @@ int grpc_server_test() {
return 0;
}
int main(int /*argc*/, const char * /*argv*/ []) {
int main(int /*argc*/, const char * /*argv*/[]) {
message_builder_tests();
grpc_server_test();
@@ -193,4 +190,3 @@ int main(int /*argc*/, const char * /*argv*/ []) {
return 1;
}
}

174
grpc/tests/grpctest.py Normal file
View File

@@ -0,0 +1,174 @@
from __future__ import print_function
import os
import sys
import grpc
import flatbuffers
from concurrent import futures
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'tests'))
import MyGame.Example.Monster as Monster
import MyGame.Example.Stat as Stat
import MyGame.Example.Vec3 as Vec3
import MyGame.Example.Test as Test
import MyGame.Example.monster_test_grpc_fb as monster_grpc_fb
test_stat_id = "test_stat_id"
test_stat_val = 8
test_stat_count = 1
test_monster_name1 = "test_monster_name1"
test_monster_name2 = "test_monster_name2"
test_string = "test_string"
test_color = 2
test_X = 3.0
test_Y = 2.0
test_Z = 6.0
test_test1 = 4.0
test_a = 8
test_b = 5
test_hp = 67
test_inventory = [1, 1, 2, 3, 5, 8]
test_testtype = 4
test_monsters_name_retrieve = ["big_monster", "small_monster"]
test_no_of_monsters = 2
class MonsterStorage(monster_grpc_fb.MonsterStorageServicer):
def Store(self, request, context):
m = Monster.Monster().GetRootAsMonster(request, 0)
assert m.Name().decode("utf-8") == test_monster_name1
assert m.Pos().X() == test_X
assert m.Pos().Y() == test_Y
assert m.Pos().Z() == test_Z
assert m.Pos().Test1() == test_test1
assert m.Pos().Test2() == test_color
test3 = Test.Test()
assert m.Pos().Test3(test3).A() == test_a
assert m.Pos().Test3(test3).B() == test_b
assert m.Hp() == test_hp
assert m.Color() == test_color
assert m.InventoryLength() == len(test_inventory)
for i in range(0, len(test_inventory)):
assert m.Inventory(i) == test_inventory[len(test_inventory)-i -1]
assert m.TestType() == test_testtype
assert m.Test() is not None
table = m.Test()
m2 = Monster.Monster()
m2.Init(table.Bytes, table.Pos)
assert m2.Name().decode("utf-8") == test_monster_name2
m3 = m.Enemy()
assert m3.Name().decode("utf-8") == test_monster_name2
assert m.Testarrayofstring(0).decode("utf-8") == test_string
b = flatbuffers.Builder(0)
i = b.CreateString(test_stat_id)
Stat.StatStart(b)
Stat.StatAddId(b, i)
Stat.StatAddVal(b, test_stat_val)
Stat.StatAddCount(b, test_stat_count)
b.Finish(Stat.StatEnd(b))
return bytes(b.Output())
def Retrieve(self, request, context):
s = Stat.Stat().GetRootAsStat(request, 0)
no_of_monsters = test_no_of_monsters
for i in range(0, no_of_monsters):
b = flatbuffers.Builder(0)
i = b.CreateString(test_monsters_name_retrieve[i])
Monster.MonsterStart(b)
Monster.MonsterAddName(b, i)
b.Finish(Monster.MonsterEnd(b))
yield bytes(b.Output())
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
monster_grpc_fb.add_MonsterStorageServicer_to_server(MonsterStorage(), server)
server.add_insecure_port('[::]:50051')
server.start()
run()
def run():
channel = grpc.insecure_channel('127.0.0.1:50051')
stub = monster_grpc_fb.MonsterStorageStub(channel)
b = flatbuffers.Builder(0)
name2 = b.CreateString(test_monster_name2)
name1 = b.CreateString(test_monster_name1)
Monster.MonsterStart(b)
Monster.MonsterAddName(b, name2)
monster2 = Monster.MonsterEnd(b)
test1 = b.CreateString(test_string)
Monster.MonsterStartInventoryVector(b, len(test_inventory))
for i in range(0, len(test_inventory)):
b.PrependByte(test_inventory[i])
inv = b.EndVector(len(test_inventory))
Monster.MonsterStartTest4Vector(b, 2)
Test.CreateTest(b, 10, 20)
Test.CreateTest(b, 30, 40)
test4 = b.EndVector(2)
Monster.MonsterStartTestarrayofstringVector(b, 1)
b.PrependUOffsetTRelative(test1)
test_array_of_string = b.EndVector(1)
Monster.MonsterStart(b)
Monster.MonsterAddHp(b, test_hp)
Monster.MonsterAddName(b, name1)
Monster.MonsterAddColor(b, test_color)
pos = Vec3.CreateVec3(b, test_X, test_Y, test_Z, test_test1, test_color, test_a, test_b)
Monster.MonsterAddPos(b, pos)
Monster.MonsterAddInventory(b, inv)
Monster.MonsterAddTestType(b, test_testtype)
Monster.MonsterAddTest(b, monster2)
Monster.MonsterAddTest4(b, test4)
Monster.MonsterAddEnemy(b, monster2)
Monster.MonsterAddTestarrayofstring(b, test_array_of_string)
monster = Monster.MonsterEnd(b)
b.Finish(monster)
stat_response = stub.Store(bytes(b.Output()))
s = Stat.Stat().GetRootAsStat(stat_response, 0)
assert s.Id().decode("utf-8") == test_stat_id
assert s.Val() == test_stat_val
assert s.Count() == test_stat_count
monster_reponses = stub.Retrieve(stat_response)
count = 0
for monster_reponse in monster_reponses:
m = Monster.Monster().GetRootAsMonster(monster_reponse, 0)
assert m.Name().decode("utf-8") == test_monsters_name_retrieve[count]
count = count + 1
if __name__ == '__main__':
serve()

View File

@@ -3,22 +3,28 @@
#include "test_assert.h"
#include "test_builder.h"
using MyGame::Example::Vec3;
using MyGame::Example::CreateStat;
using MyGame::Example::Any_NONE;
using MyGame::Example::CreateStat;
using MyGame::Example::Vec3;
bool verify(flatbuffers::grpc::Message<Monster> &msg, const std::string &expected_name, Color color) {
bool verify(flatbuffers::grpc::Message<Monster> &msg,
const std::string &expected_name, Color expected_color) {
const Monster *monster = msg.GetRoot();
return (monster->name()->str() == expected_name) && (monster->color() == color);
const auto name = monster->name()->str();
const auto color = monster->color();
TEST_EQ(name, expected_name);
TEST_EQ(color, expected_color);
return (name == expected_name) && (color == expected_color);
}
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color) {
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
const std::string &expected_name, Color expected_color) {
flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
const Monster *monster = msg.GetRoot();
return (monster->name()->str() == expected_name) && (monster->color() == color);
return verify(msg, expected_name, expected_color);
}
void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder dst) {
void builder_move_assign_after_releaseraw_test(
flatbuffers::grpc::MessageBuilder dst) {
auto root_offset1 = populate1(dst);
dst.Finish(root_offset1);
size_t size, offset;
@@ -31,17 +37,16 @@ void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder
// Move into a released builder.
dst = std::move(src);
TEST_EQ(dst.GetSize(), src_size);
TEST_ASSERT(release_n_verify(dst, m2_name, m2_color));
TEST_ASSERT(release_n_verify(dst, m2_name(), m2_color()));
TEST_EQ(src.GetSize(), 0);
grpc_slice_unref(slice);
}
template <class SrcBuilder>
template<class SrcBuilder>
struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
static void builder_reusable_after_release_message_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) {
return;
}
static void builder_reusable_after_release_message_test(
TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) { return; }
flatbuffers::grpc::MessageBuilder mb;
std::vector<flatbuffers::grpc::Message<Monster>> buffers;
@@ -49,17 +54,15 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
auto root_offset1 = populate1(mb);
mb.Finish(root_offset1);
buffers.push_back(mb.ReleaseMessage<Monster>());
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
}
}
static void builder_reusable_after_release_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE)) {
return;
}
if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in SliceAllocator::allocate
// in the second iteration.
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in
// SliceAllocator::allocate in the second iteration.
flatbuffers::grpc::MessageBuilder mb;
std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -67,14 +70,12 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
auto root_offset1 = populate1(mb);
mb.Finish(root_offset1);
buffers.push_back(mb.Release());
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
}
}
static void builder_reusable_after_releaseraw_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
return;
}
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
flatbuffers::grpc::MessageBuilder mb;
for (int i = 0; i < 5; ++i) {
@@ -83,18 +84,18 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
size_t size, offset;
grpc_slice slice;
const uint8_t *buf = mb.ReleaseRaw(size, offset, slice);
TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
grpc_slice_unref(slice);
}
}
static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
return;
}
static void builder_reusable_after_release_and_move_assign_test(
TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
// FIXME: Release-move_assign loop fails assert(p == GRPC_SLICE_START_PTR(slice_))
// in DetachedBuffer destructor after all the iterations
// FIXME: Release-move_assign loop fails assert(p ==
// GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the
// iterations
flatbuffers::grpc::MessageBuilder dst;
std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -103,7 +104,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
auto root_offset1 = populate1(dst);
dst.Finish(root_offset1);
buffers.push_back(dst.Release());
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
// bring dst back to life.
SrcBuilder src;
@@ -113,7 +114,8 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
}
}
static void builder_reusable_after_release_message_and_move_assign_test(TestSelector selector) {
static void builder_reusable_after_release_message_and_move_assign_test(
TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
return;
}
@@ -125,7 +127,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
auto root_offset1 = populate1(dst);
dst.Finish(root_offset1);
buffers.push_back(dst.ReleaseMessage<Monster>());
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
// bring dst back to life.
SrcBuilder src;
@@ -135,10 +137,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
}
}
static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
return;
}
static void builder_reusable_after_releaseraw_and_move_assign_test(
TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
flatbuffers::grpc::MessageBuilder dst;
for (int i = 0; i < 5; ++i) {
@@ -147,7 +148,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
size_t size, offset;
grpc_slice slice = grpc_empty_slice();
const uint8_t *buf = dst.ReleaseRaw(size, offset, slice);
TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
grpc_slice_unref(slice);
SrcBuilder src;
@@ -175,11 +176,11 @@ void slice_allocator_tests() {
uint8_t *buf = sa1.allocate(size);
TEST_ASSERT_FUNC(buf != 0);
buf[0] = 100;
buf[size-1] = 200;
buf[size - 1] = 200;
flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
// buf should not be deleted after move-construct
TEST_EQ_FUNC(buf[0], 100);
TEST_EQ_FUNC(buf[size-1], 200);
TEST_EQ_FUNC(buf[size - 1], 200);
// buf is freed here
}
@@ -194,13 +195,16 @@ void slice_allocator_tests() {
}
}
/// This function does not populate exactly the first half of the table. But it could.
void populate_first_half(MyGame::Example::MonsterBuilder &wrapper, flatbuffers::Offset<flatbuffers::String> name_offset) {
/// This function does not populate exactly the first half of the table. But it
/// could.
void populate_first_half(MyGame::Example::MonsterBuilder &wrapper,
flatbuffers::Offset<flatbuffers::String> name_offset) {
wrapper.add_name(name_offset);
wrapper.add_color(m1_color);
wrapper.add_color(m1_color());
}
/// This function does not populate exactly the second half of the table. But it could.
/// This function does not populate exactly the second half of the table. But it
/// could.
void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
wrapper.add_hp(77);
wrapper.add_mana(88);
@@ -208,114 +212,138 @@ void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
wrapper.add_pos(&vec3);
}
/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in the MonsterBuilder object.
/// This function will break if fbb_ is not the first member in MonsterBuilder. In that case, some offset must be added.
/// This function is used exclusively for testing correctness of move operations between FlatBufferBuilders.
/// If MonsterBuilder had a fbb_ pointer, this hack would be unnecessary. That involves a code-generator change though.
void test_only_hack_update_fbb_reference(MyGame::Example::MonsterBuilder &monsterBuilder,
flatbuffers::grpc::MessageBuilder &mb) {
/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in
/// the MonsterBuilder object. This function will break if fbb_ is not the first
/// member in MonsterBuilder. In that case, some offset must be added. This
/// function is used exclusively for testing correctness of move operations
/// between FlatBufferBuilders. If MonsterBuilder had a fbb_ pointer, this hack
/// would be unnecessary. That involves a code-generator change though.
void test_only_hack_update_fbb_reference(
MyGame::Example::MonsterBuilder &monsterBuilder,
flatbuffers::grpc::MessageBuilder &mb) {
*reinterpret_cast<flatbuffers::FlatBufferBuilder **>(&monsterBuilder) = &mb;
}
/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
/// of the table is constructed using a MessageBuilder.
/// This test validates correctness of move conversion of FlatBufferBuilder to a
/// MessageBuilder DURING a table construction. Half of the table is constructed
/// using FlatBufferBuilder and the other half of the table is constructed using
/// a MessageBuilder.
void builder_move_ctor_conversion_before_finish_half_n_half_table_test() {
for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
for (size_t initial_size = 4; initial_size <= 2048; initial_size *= 2) {
flatbuffers::FlatBufferBuilder fbb(initial_size);
auto name_offset = fbb.CreateString(m1_name);
MyGame::Example::MonsterBuilder monsterBuilder(fbb); // starts a table in FlatBufferBuilder
auto name_offset = fbb.CreateString(m1_name());
MyGame::Example::MonsterBuilder monsterBuilder(
fbb); // starts a table in FlatBufferBuilder
populate_first_half(monsterBuilder, name_offset);
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
populate_second_half(monsterBuilder);
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
/// This test populates a COMPLETE inner table before move conversion and later
/// populates more members in the outer table.
void builder_move_ctor_conversion_before_finish_test() {
for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
for (size_t initial_size = 1; initial_size <= 2048; initial_size += 1) {
flatbuffers::FlatBufferBuilder fbb(initial_size);
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
auto monster_offset =
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset);
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
{
auto mon = flatbuffers::GetRoot<Monster>(mb.GetBufferPointer());
TEST_NOTNULL(mon);
TEST_NOTNULL(mon->name());
TEST_EQ_STR(mon->name()->c_str(), m1_name().c_str());
TEST_EQ(mon->color(), m1_color());
}
TEST_EQ(1, MyGame::Example::Color_Red);
TEST_EQ(1, m1_color());
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
/// of the table is constructed using a MessageBuilder.
/// This test validates correctness of move conversion of FlatBufferBuilder to a
/// MessageBuilder DURING a table construction. Half of the table is constructed
/// using FlatBufferBuilder and the other half of the table is constructed using
/// a MessageBuilder.
void builder_move_assign_conversion_before_finish_half_n_half_table_test() {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb;
for (int i = 0;i < 5; ++i) {
for (int i = 0; i < 5; ++i) {
flatbuffers::FlatBufferBuilder fbb;
auto name_offset = fbb.CreateString(m1_name);
MyGame::Example::MonsterBuilder monsterBuilder(fbb); // starts a table in FlatBufferBuilder
auto name_offset = fbb.CreateString(m1_name());
MyGame::Example::MonsterBuilder monsterBuilder(
fbb); // starts a table in FlatBufferBuilder
populate_first_half(monsterBuilder, name_offset);
mb = std::move(fbb);
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
populate_second_half(monsterBuilder);
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
/// This test populates a COMPLETE inner table before move conversion and later
/// populates more members in the outer table.
void builder_move_assign_conversion_before_finish_test() {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb;
for (int i = 0;i < 5; ++i) {
for (int i = 0; i < 5; ++i) {
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
mb = std::move(fbb);
auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
auto monster_offset =
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset);
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
/// This test populates data, finishes the buffer, and does move conversion after.
/// This test populates data, finishes the buffer, and does move conversion
/// after.
void builder_move_ctor_conversion_after_finish_test() {
flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(populate1(fbb));
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
/// This test populates data, finishes the buffer, and does move conversion after.
/// This test populates data, finishes the buffer, and does move conversion
/// after.
void builder_move_assign_conversion_after_finish_test() {
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb;
for (int i = 0;i < 5; ++i) {
for (int i = 0; i < 5; ++i) {
fbb.Finish(populate1(fbb));
mb = std::move(fbb);
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
TEST_EQ_FUNC(fbb.GetSize(), 0);
}
}
void message_builder_tests() {
using flatbuffers::grpc::MessageBuilder;
using flatbuffers::FlatBufferBuilder;
using flatbuffers::grpc::MessageBuilder;
slice_allocator_tests();
#ifndef __APPLE__
builder_move_ctor_conversion_before_finish_half_n_half_table_test();
builder_move_assign_conversion_before_finish_half_n_half_table_test();
#endif // __APPLE__
#endif // __APPLE__
builder_move_ctor_conversion_before_finish_test();
builder_move_assign_conversion_before_finish_test();
@@ -326,15 +354,18 @@ void message_builder_tests() {
BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests();
BuilderReuseTestSelector tests[6] = {
//REUSABLE_AFTER_RELEASE, // Assertion failed: (GRPC_SLICE_IS_EMPTY(slice_))
//REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p == GRPC_SLICE_START_PTR(slice_)
// REUSABLE_AFTER_RELEASE, // Assertion failed:
// (GRPC_SLICE_IS_EMPTY(slice_))
// REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p ==
// GRPC_SLICE_START_PTR(slice_)
REUSABLE_AFTER_RELEASE_RAW,
REUSABLE_AFTER_RELEASE_MESSAGE,
REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE,
REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
};
BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(TestSelector(tests, tests+6));
BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+6));
BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(
TestSelector(tests, tests + 6));
BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(
TestSelector(tests, tests + 6));
}

View File

@@ -4,13 +4,13 @@
<parent>
<groupId>com.google.flatbuffers</groupId>
<artifactId>flatbuffers-parent</artifactId>
<version>1.11.0</version>
<version>1.12.0</version>
</parent>
<artifactId>grpc-test</artifactId>
<description>Example/Test project demonstrating usage of flatbuffers with GRPC-Java instead of protobufs
</description>
<properties>
<gRPC.version>1.11.0</gRPC.version>
<gRPC.version>1.12.0</gRPC.version>
</properties>
<dependencies>
<dependency>

View File

@@ -55,6 +55,10 @@
#include "flatbuffers/stl_emulation.h"
#if defined(__ICCARM__)
#include <intrinsics.h>
#endif
// Note the __clang__ check is needed, because clang presents itself
// as an older GNUC compiler (4.2).
// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
@@ -95,7 +99,7 @@
#if !defined(__clang__) && \
defined(__GNUC__) && \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
// Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr
// Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr
// and constexpr keywords. Note the __clang__ check is needed, because clang
// presents itself as an older GNUC compiler.
#ifndef nullptr_t
@@ -117,7 +121,7 @@
#define FLATBUFFERS_LITTLEENDIAN 0
#endif // __s390x__
#if !defined(FLATBUFFERS_LITTLEENDIAN)
#if defined(__GNUC__) || defined(__clang__)
#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
#if (defined(__BIG_ENDIAN__) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define FLATBUFFERS_LITTLEENDIAN 0
@@ -136,10 +140,14 @@
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
#define FLATBUFFERS_VERSION_MAJOR 1
#define FLATBUFFERS_VERSION_MINOR 11
#define FLATBUFFERS_VERSION_MINOR 12
#define FLATBUFFERS_VERSION_REVISION 0
#define FLATBUFFERS_STRING_EXPAND(X) #X
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
namespace flatbuffers {
// Returns version as string "MAJOR.MINOR.REVISION".
const char* FLATBUFFERS_VERSION();
}
#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \
@@ -191,7 +199,7 @@
// to detect a header that provides an implementation
#if defined(__has_include)
// Check for std::string_view (in c++17)
#if __has_include(<string_view>) && (__cplusplus >= 201606 || _HAS_CXX17)
#if __has_include(<string_view>) && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17))
#include <string_view>
namespace flatbuffers {
typedef std::string_view string_view;
@@ -204,6 +212,13 @@
typedef std::experimental::string_view string_view;
}
#define FLATBUFFERS_HAS_STRING_VIEW 1
// Check for absl::string_view
#elif __has_include("absl/strings/string_view.h")
#include "absl/strings/string_view.h"
namespace flatbuffers {
typedef absl::string_view string_view;
}
#define FLATBUFFERS_HAS_STRING_VIEW 1
#endif
#endif // __has_include
#endif // !FLATBUFFERS_HAS_STRING_VIEW
@@ -234,7 +249,7 @@
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
// - __supress_ubsan__("undefined")
// - __supress_ubsan__("signed-integer-overflow")
#if defined(__clang__)
#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))
#define __supress_ubsan__(type) __attribute__((no_sanitize(type)))
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
#define __supress_ubsan__(type) __attribute__((no_sanitize_undefined))
@@ -288,7 +303,7 @@ typedef uint16_t voffset_t;
typedef uintmax_t largest_scalar_t;
// In 32bits, this evaluates to 2GB - 1
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1)
// We support aligning the contents of buffers up to this size.
#define FLATBUFFERS_MAX_ALIGNMENT 16
@@ -303,6 +318,11 @@ template<typename T> T EndianSwap(T t) {
#define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
#define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
#define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
#elif defined(__ICCARM__)
#define FLATBUFFERS_BYTESWAP16 __REV16
#define FLATBUFFERS_BYTESWAP32 __REV
#define FLATBUFFERS_BYTESWAP64(x) \
((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U)
#else
#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
// __builtin_bswap16 was missing prior to GCC 4.8.
@@ -317,22 +337,20 @@ template<typename T> T EndianSwap(T t) {
if (sizeof(T) == 1) { // Compile-time if-then's.
return t;
} else if (sizeof(T) == 2) {
union { T t; uint16_t i; } u;
u.t = t;
union { T t; uint16_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP16(u.i);
return u.t;
} else if (sizeof(T) == 4) {
union { T t; uint32_t i; } u;
u.t = t;
union { T t; uint32_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP32(u.i);
return u.t;
} else if (sizeof(T) == 8) {
union { T t; uint64_t i; } u;
u.t = t;
union { T t; uint64_t i; } u = { t };
u.i = FLATBUFFERS_BYTESWAP64(u.i);
return u.t;
} else {
FLATBUFFERS_ASSERT(0);
return t;
}
}
@@ -371,6 +389,7 @@ template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Of
// Computes how many bytes you'd have to pad to be able to write an
// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
// memory).
__supress_ubsan__("unsigned-integer-overflow")
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
return ((~buf_size) + 1) & (scalar_size - 1);
}

View File

@@ -19,6 +19,7 @@
#include <map>
#include <sstream>
#include "flatbuffers/idl.h"
namespace flatbuffers {
@@ -26,7 +27,7 @@ namespace flatbuffers {
// Utility class to assist in generating code through use of text templates.
//
// Example code:
// CodeWriter code;
// CodeWriter code("\t");
// code.SetValue("NAME", "Foo");
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
// code.SetValue("NAME", "Bar");
@@ -38,7 +39,8 @@ namespace flatbuffers {
// void Bar() { printf("%s", "Bar"); }
class CodeWriter {
public:
CodeWriter() {}
CodeWriter(std::string pad = std::string())
: pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {}
// Clears the current "written" code.
void Clear() {
@@ -53,6 +55,11 @@ class CodeWriter {
value_map_[key] = value;
}
std::string GetValue(const std::string &key) const {
const auto it = value_map_.find(key);
return it == value_map_.end() ? "" : it->second;
}
// Appends the given text to the generated code as well as a newline
// character. Any text within {{ and }} delimeters is replaced by values
// previously stored in the CodeWriter by calling SetValue above. The newline
@@ -62,9 +69,22 @@ class CodeWriter {
// Returns the current contents of the CodeWriter as a std::string.
std::string ToString() const { return stream_.str(); }
// Increase ident level for writing code
void IncrementIdentLevel() { cur_ident_lvl_++; }
// Decrease ident level for writing code
void DecrementIdentLevel() {
if (cur_ident_lvl_) cur_ident_lvl_--;
}
private:
std::map<std::string, std::string> value_map_;
std::stringstream stream_;
std::string pad_;
int cur_ident_lvl_;
bool ignore_ident_;
// Add ident padding (tab or space) based on ident level
void AppendIdent(std::stringstream &stream);
};
class BaseGenerator {
@@ -74,16 +94,20 @@ class BaseGenerator {
static std::string NamespaceDir(const Parser &parser, const std::string &path,
const Namespace &ns);
std::string GeneratedFileName(const std::string &path,
const std::string &file_name,
const IDLOptions &options) const;
protected:
BaseGenerator(const Parser &parser, const std::string &path,
const std::string &file_name,
const std::string qualifying_start,
const std::string qualifying_separator)
const std::string &file_name, std::string qualifying_start,
std::string qualifying_separator, std::string default_extension)
: parser_(parser),
path_(path),
file_name_(file_name),
qualifying_start_(qualifying_start),
qualifying_separator_(qualifying_separator) {}
qualifying_separator_(qualifying_separator),
default_extension_(default_extension) {}
virtual ~BaseGenerator() {}
// No copy/assign.
@@ -104,8 +128,9 @@ class BaseGenerator {
// which works for js and php
virtual const Namespace *CurrentNameSpace() const { return nullptr; }
// Ensure that a type is prefixed with its namespace whenever it is used
// outside of its namespace.
// Ensure that a type is prefixed with its namespace even within
// its own namespace to avoid conflict between generated method
// names and similarly named classes or structs
std::string WrapInNameSpace(const Namespace *ns,
const std::string &name) const;
@@ -118,6 +143,7 @@ class BaseGenerator {
const std::string &file_name_;
const std::string qualifying_start_;
const std::string qualifying_separator_;
const std::string default_extension_;
};
struct CommentConfig {

View File

@@ -20,24 +20,43 @@
#include "flatbuffers/base.h"
#if defined(FLATBUFFERS_NAN_DEFAULTS)
#include <cmath>
# include <cmath>
#endif
namespace flatbuffers {
// Generic 'operator==' with conditional specialisations.
// T e - new value of a scalar field.
// T def - default of scalar (is known at compile-time).
template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
(!defined(_MSC_VER) || _MSC_VER >= 1800)
defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Like `operator==(e, def)` with weak NaN if T=(float|double).
template<typename T> inline bool IsFloatTheSameAs(T e, T def) {
return (e == def) || ((def != def) && (e != e));
}
template<> inline bool IsTheSameAs<float>(float e, float def) {
return (e == def) || (std::isnan(def) && std::isnan(e));
return IsFloatTheSameAs(e, def);
}
template<> inline bool IsTheSameAs<double>(double e, double def) {
return (e == def) || (std::isnan(def) && std::isnan(e));
return IsFloatTheSameAs(e, def);
}
#endif
// Check 'v' is out of closed range [low; high].
// Workaround for GCC warning [-Werror=type-limits]:
// comparison is always true due to limited range of data type.
template<typename T>
inline bool IsOutRange(const T &v, const T &low, const T &high) {
return (v < low) || (high < v);
}
// Check 'v' is in closed range [low; high].
template<typename T>
inline bool IsInRange(const T &v, const T &low, const T &high) {
return !IsOutRange(v, low, high);
}
// Wrapper for uoffset_t to allow safe template specialization.
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
template<typename T> struct Offset {
@@ -198,17 +217,18 @@ template<typename T, typename IT> struct VectorIterator {
const uint8_t *data_;
};
template<typename Iterator> struct VectorReverseIterator :
public std::reverse_iterator<Iterator> {
template<typename Iterator>
struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
explicit VectorReverseIterator(Iterator iter)
: std::reverse_iterator<Iterator>(iter) {}
explicit VectorReverseIterator(Iterator iter) : iter_(iter) {}
typename Iterator::value_type operator*() const {
return *(std::reverse_iterator<Iterator>::current);
}
typename Iterator::value_type operator*() const { return *(iter_ - 1); }
typename Iterator::value_type operator->() const { return *(iter_ - 1); }
private:
Iterator iter_;
typename Iterator::value_type operator->() const {
return *(std::reverse_iterator<Iterator>::current);
}
};
struct String;
@@ -269,11 +289,15 @@ template<typename T> class Vector {
iterator end() { return iterator(Data(), size()); }
const_iterator end() const { return const_iterator(Data(), size()); }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end() - 1);
}
reverse_iterator rend() { return reverse_iterator(end()); }
const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin() - 1); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin() - 1);
}
const_iterator cbegin() const { return begin(); }
@@ -341,6 +365,7 @@ template<typename T> class Vector {
// This class is a pointer. Copying will therefore create an invalid object.
// Private and unimplemented copy constructor.
Vector(const Vector &);
Vector &operator=(const Vector &);
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
const K *key = reinterpret_cast<const K *>(ap);
@@ -371,6 +396,7 @@ class VectorOfAny {
private:
VectorOfAny(const VectorOfAny &);
VectorOfAny &operator=(const VectorOfAny &);
};
#ifndef FLATBUFFERS_CPP98_STL
@@ -393,6 +419,131 @@ template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
return v ? v->size() : 0;
}
// This is used as a helper type for accessing arrays.
template<typename T, uint16_t length> class Array {
typedef
typename flatbuffers::integral_constant<bool,
flatbuffers::is_scalar<T>::value>
scalar_tag;
typedef
typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type
IndirectHelperType;
public:
typedef typename IndirectHelper<IndirectHelperType>::return_type return_type;
typedef VectorIterator<T, return_type> const_iterator;
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; }
return_type Get(uoffset_t i) const {
FLATBUFFERS_ASSERT(i < size());
return IndirectHelper<IndirectHelperType>::Read(Data(), i);
}
return_type operator[](uoffset_t i) const { return Get(i); }
// If this is a Vector of enums, T will be its storage type, not the enum
// type. This function makes it convenient to retrieve value with enum
// type E.
template<typename E> E GetEnum(uoffset_t i) const {
return static_cast<E>(Get(i));
}
const_iterator begin() const { return const_iterator(Data(), 0); }
const_iterator end() const { return const_iterator(Data(), size()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
const_iterator cbegin() const { return begin(); }
const_iterator cend() const { return end(); }
const_reverse_iterator crbegin() const { return rbegin(); }
const_reverse_iterator crend() const { return rend(); }
// Get a mutable pointer to elements inside this array.
// This method used to mutate arrays of structs followed by a @p Mutate
// operation. For primitive types use @p Mutate directly.
// @warning Assignments and reads to/from the dereferenced pointer are not
// automatically converted to the correct endianness.
typename flatbuffers::conditional<scalar_tag::value, void, T *>::type
GetMutablePointer(uoffset_t i) const {
FLATBUFFERS_ASSERT(i < size());
return const_cast<T *>(&data()[i]);
}
// Change elements if you have a non-const pointer to this object.
void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); }
// The raw data in little endian format. Use with care.
const uint8_t *Data() const { return data_; }
uint8_t *Data() { return data_; }
// Similarly, but typed, much like std::vector::data
const T *data() const { return reinterpret_cast<const T *>(Data()); }
T *data() { return reinterpret_cast<T *>(Data()); }
protected:
void MutateImpl(flatbuffers::integral_constant<bool, true>, uoffset_t i,
const T &val) {
FLATBUFFERS_ASSERT(i < size());
WriteScalar(data() + i, val);
}
void MutateImpl(flatbuffers::integral_constant<bool, false>, uoffset_t i,
const T &val) {
*(GetMutablePointer(i)) = val;
}
// This class is only used to access pre-existing data. Don't ever
// try to construct these manually.
// 'constexpr' allows us to use 'size()' at compile time.
// @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on
// a constructor.
#if defined(__cpp_constexpr)
constexpr Array();
#else
Array();
#endif
uint8_t data_[length * sizeof(T)];
private:
// This class is a pointer. Copying will therefore create an invalid object.
// Private and unimplemented copy constructor.
Array(const Array &);
Array &operator=(const Array &);
};
// Specialization for Array[struct] with access using Offset<void> pointer.
// This specialization used by idl_gen_text.cpp.
template<typename T, uint16_t length> class Array<Offset<T>, length> {
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
public:
typedef const void *return_type;
const uint8_t *Data() const { return data_; }
// Make idl_gen_text.cpp::PrintContainer happy.
return_type operator[](uoffset_t) const {
FLATBUFFERS_ASSERT(false);
return nullptr;
}
private:
// This class is only used to access pre-existing data.
Array();
Array(const Array &);
Array &operator=(const Array &);
uint8_t data_[1];
};
// Lexicographically compare two strings (possibly containing nulls), and
// return true if the first is less than the second.
static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
@@ -420,13 +571,13 @@ struct String : public Vector<char> {
// Convenience function to get std::string from a String returning an empty
// string on null pointer.
static inline std::string GetString(const String * str) {
static inline std::string GetString(const String *str) {
return str ? str->str() : "";
}
// Convenience function to get char* from a String returning an empty string on
// null pointer.
static inline const char * GetCstring(const String * str) {
static inline const char *GetCstring(const String *str) {
return str ? str->c_str() : "";
}
@@ -463,9 +614,9 @@ class Allocator {
// to `new_p` of `new_size`. Only memory of size `in_use_front` and
// `in_use_back` will be copied from the front and back of the old memory
// allocation.
void memcpy_downward(uint8_t *old_p, size_t old_size,
uint8_t *new_p, size_t new_size,
size_t in_use_back, size_t in_use_front) {
void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
size_t new_size, size_t in_use_back,
size_t in_use_front) {
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
in_use_back);
memcpy(new_p, old_p, in_use_front);
@@ -479,13 +630,9 @@ class DefaultAllocator : public Allocator {
return new uint8_t[size];
}
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE {
delete[] p;
}
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
static void dealloc(void *p, size_t) {
delete[] static_cast<uint8_t *>(p);
}
static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
};
// These functions allow for a null allocator to mean use the default allocator,
@@ -498,18 +645,19 @@ inline uint8_t *Allocate(Allocator *allocator, size_t size) {
}
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
if (allocator) allocator->deallocate(p, size);
else DefaultAllocator().deallocate(p, size);
if (allocator)
allocator->deallocate(p, size);
else
DefaultAllocator().deallocate(p, size);
}
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
size_t old_size, size_t new_size,
size_t in_use_back, size_t in_use_front) {
return allocator
? allocator->reallocate_downward(old_p, old_size, new_size,
in_use_back, in_use_front)
: DefaultAllocator().reallocate_downward(old_p, old_size, new_size,
in_use_back, in_use_front);
return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
in_use_back, in_use_front)
: DefaultAllocator().reallocate_downward(
old_p, old_size, new_size, in_use_back, in_use_front);
}
// DetachedBuffer is a finished flatbuffer memory region, detached from its
@@ -554,6 +702,8 @@ class DetachedBuffer {
#if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
DetachedBuffer &operator=(DetachedBuffer &&other) {
if (this == &other) return *this;
destroy();
allocator_ = other.allocator_;
@@ -610,7 +760,7 @@ class DetachedBuffer {
#endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on
protected:
protected:
Allocator *allocator_;
bool own_allocator_;
uint8_t *buf_;
@@ -642,10 +792,8 @@ protected:
// Essentially, this supports 2 std::vectors in a single buffer.
class vector_downward {
public:
explicit vector_downward(size_t initial_size,
Allocator *allocator,
bool own_allocator,
size_t buffer_minalign)
explicit vector_downward(size_t initial_size, Allocator *allocator,
bool own_allocator, size_t buffer_minalign)
: allocator_(allocator),
own_allocator_(own_allocator),
initial_size_(initial_size),
@@ -661,15 +809,15 @@ class vector_downward {
#else
vector_downward(vector_downward &other)
#endif // defined(FLATBUFFERS_CPP98_STL)
// clang-format on
: allocator_(other.allocator_),
own_allocator_(other.own_allocator_),
initial_size_(other.initial_size_),
buffer_minalign_(other.buffer_minalign_),
reserved_(other.reserved_),
buf_(other.buf_),
cur_(other.cur_),
scratch_(other.scratch_) {
// clang-format on
: allocator_(other.allocator_),
own_allocator_(other.own_allocator_),
initial_size_(other.initial_size_),
buffer_minalign_(other.buffer_minalign_),
reserved_(other.reserved_),
buf_(other.buf_),
cur_(other.cur_),
scratch_(other.scratch_) {
// No change in other.allocator_
// No change in other.initial_size_
// No change in other.buffer_minalign_
@@ -713,9 +861,7 @@ class vector_downward {
clear_scratch();
}
void clear_scratch() {
scratch_ = buf_;
}
void clear_scratch() { scratch_ = buf_; }
void clear_allocator() {
if (own_allocator_ && allocator_) { delete allocator_; }
@@ -801,7 +947,7 @@ class vector_downward {
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
void push(const uint8_t *bytes, size_t num) {
memcpy(make_space(num), bytes, num);
if (num > 0) { memcpy(make_space(num), bytes, num); }
}
// Specialized version of push() that avoids memcpy call for small data.
@@ -824,6 +970,7 @@ class vector_downward {
}
// Version for when we know the size is larger.
// Precondition: zero_pad_bytes > 0
void fill_big(size_t zero_pad_bytes) {
memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
}
@@ -867,8 +1014,8 @@ class vector_downward {
auto old_reserved = reserved_;
auto old_size = size();
auto old_scratch_size = scratch_size();
reserved_ += (std::max)(len,
old_reserved ? old_reserved / 2 : initial_size_);
reserved_ +=
(std::max)(len, old_reserved ? old_reserved / 2 : initial_size_);
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
if (buf_) {
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
@@ -890,10 +1037,16 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
template<typename T, typename Alloc>
const T *data(const std::vector<T, Alloc> &v) {
return v.empty() ? nullptr : &v.front();
// Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior.
static uint8_t t;
return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
}
template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
return v.empty() ? nullptr : &v.front();
// Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior.
static uint8_t t;
return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
}
/// @endcond
@@ -920,11 +1073,10 @@ class FlatBufferBuilder {
/// minimum alignment upon reallocation. Only needed if you intend to store
/// types with custom alignment AND you wish to read the buffer in-place
/// directly after creation.
explicit FlatBufferBuilder(size_t initial_size = 1024,
Allocator *allocator = nullptr,
bool own_allocator = false,
size_t buffer_minalign =
AlignOf<largest_scalar_t>())
explicit FlatBufferBuilder(
size_t initial_size = 1024, Allocator *allocator = nullptr,
bool own_allocator = false,
size_t buffer_minalign = AlignOf<largest_scalar_t>())
: buf_(initial_size, allocator, own_allocator, buffer_minalign),
num_field_loc(0),
max_voffset_(0),
@@ -1027,8 +1179,8 @@ class FlatBufferBuilder {
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
/// @return A `FlatBuffer` that owns the buffer and its allocator and
/// behaves similar to a `unique_ptr` with a deleter.
FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer
ReleaseBufferPointer() {
FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead"))
DetachedBuffer ReleaseBufferPointer() {
Finished();
return buf_.release();
}
@@ -1041,13 +1193,14 @@ class FlatBufferBuilder {
}
/// @brief Get the released pointer to the serialized buffer.
/// @param The size of the memory block containing
/// @param size The size of the memory block containing
/// the serialized `FlatBuffer`.
/// @param The offset from the released pointer where the finished
/// @param offset The offset from the released pointer where the finished
/// `FlatBuffer` starts.
/// @return A raw pointer to the start of the memory block containing
/// the serialized `FlatBuffer`.
/// @remark If the allocator is owned, it gets deleted when the destructor is called..
/// @remark If the allocator is owned, it gets deleted when the destructor is
/// called..
uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
Finished();
return buf_.release_raw(size, offset);
@@ -1076,12 +1229,13 @@ class FlatBufferBuilder {
/// @brief In order to save space, fields that are set to their default value
/// don't get serialized into the buffer.
/// @param[in] bool fd When set to `true`, always serializes default values that are set.
/// Optional fields which are not set explicitly, will still not be serialized.
/// @param[in] fd When set to `true`, always serializes default values that
/// are set. Optional fields which are not set explicitly, will still not be
/// serialized.
void ForceDefaults(bool fd) { force_defaults_ = fd; }
/// @brief By default vtables are deduped in order to save space.
/// @param[in] bool dedup When set to `true`, dedup vtables.
/// @param[in] dedup When set to `true`, dedup vtables.
void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
/// @cond FLATBUFFERS_INTERNAL
@@ -1235,7 +1389,7 @@ class FlatBufferBuilder {
it += sizeof(uoffset_t)) {
auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
auto vt2_size = *vt2;
auto vt2_size = ReadScalar<voffset_t>(vt2);
if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
vt_use = *vt_offset_ptr;
buf_.pop(GetSize() - vtableoffsetloc);
@@ -1562,17 +1716,16 @@ class FlatBufferBuilder {
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
size_t len) {
extern T Pack(const S &);
typedef T (*Pack_t)(const S &);
std::vector<T> vv(len);
std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack));
return CreateVectorOfStructs<T>(vv.data(), vv.size());
std::transform(v, v + len, vv.begin(), Pack);
return CreateVectorOfStructs<T>(data(vv), vv.size());
}
// clang-format off
#ifndef FLATBUFFERS_CPP98_STL
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
/// @tparam T The data type of the struct array elements.
/// @param[in] f A function that takes the current iteration 0..vector_size-1
/// @param[in] filler A function that takes the current iteration 0..vector_size-1
/// and a pointer to the struct that must be filled.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1612,7 +1765,7 @@ class FlatBufferBuilder {
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
/// @tparam T The data type of the `std::vector` struct elements.
/// @param[in]] v A const reference to the `std::vector` of structs to
/// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1626,7 +1779,7 @@ class FlatBufferBuilder {
/// `vector`.
/// @tparam T The data type of the `std::vector` struct elements.
/// @tparam S The data type of the `std::vector` native struct elements.
/// @param[in]] v A const reference to the `std::vector` of structs to
/// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1650,7 +1803,7 @@ class FlatBufferBuilder {
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`
/// in sorted order.
/// @tparam T The data type of the `std::vector` struct elements.
/// @param[in]] v A const reference to the `std::vector` of structs to
/// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1663,7 +1816,7 @@ class FlatBufferBuilder {
/// `vector` in sorted order.
/// @tparam T The data type of the `std::vector` struct elements.
/// @tparam S The data type of the `std::vector` native struct elements.
/// @param[in]] v A const reference to the `std::vector` of structs to
/// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored.
@@ -1702,13 +1855,14 @@ class FlatBufferBuilder {
extern T Pack(const S &);
typedef T (*Pack_t)(const S &);
std::vector<T> vv(len);
std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack));
std::transform(v, v + len, vv.begin(), static_cast<Pack_t &>(Pack));
return CreateVectorOfSortedStructs<T>(vv, len);
}
/// @cond FLATBUFFERS_INTERNAL
template<typename T> struct TableKeyComparator {
TableKeyComparator(vector_downward &buf) : buf_(buf) {}
TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {}
bool operator()(const Offset<T> &a, const Offset<T> &b) const {
auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
@@ -1717,7 +1871,10 @@ class FlatBufferBuilder {
vector_downward &buf_;
private:
TableKeyComparator &operator=(const TableKeyComparator &);
TableKeyComparator &operator=(const TableKeyComparator &other) {
buf_ = other.buf_;
return *this;
}
};
/// @endcond
@@ -1783,12 +1940,12 @@ class FlatBufferBuilder {
}
template<typename T>
Offset<Vector<const T*>> CreateUninitializedVectorOfStructs(size_t len, T **buf) {
Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
T **buf) {
return CreateUninitializedVector(len, sizeof(T),
reinterpret_cast<uint8_t **>(buf));
}
// @brief Create a vector of scalar type T given as input a vector of scalar
// type U, useful with e.g. pre "enum class" enums, or any existing scalar
// data of the wrong type.
@@ -1837,8 +1994,7 @@ class FlatBufferBuilder {
buf_.swap_allocator(other.buf_);
}
protected:
protected:
// You shouldn't really be copying instances of this class.
FlatBufferBuilder(const FlatBufferBuilder &);
FlatBufferBuilder &operator=(const FlatBufferBuilder &);
@@ -1891,8 +2047,8 @@ protected:
bool operator()(const Offset<String> &a, const Offset<String> &b) const {
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
return StringLessThan(stra->data(), stra->size(),
strb->data(), strb->size());
return StringLessThan(stra->data(), stra->size(), strb->data(),
strb->size());
}
const vector_downward *buf_;
};
@@ -1956,13 +2112,15 @@ const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
/// This function is UNDEFINED for FlatBuffers whose schema does not include
/// a file_identifier (likely points at padding or the start of a the root
/// vtable).
inline const char *GetBufferIdentifier(const void *buf, bool size_prefixed = false) {
inline const char *GetBufferIdentifier(const void *buf,
bool size_prefixed = false) {
return reinterpret_cast<const char *>(buf) +
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
}
// Helper to see if the identifier in a buffer has the expected value.
inline bool BufferHasIdentifier(const void *buf, const char *identifier, bool size_prefixed = false) {
inline bool BufferHasIdentifier(const void *buf, const char *identifier,
bool size_prefixed = false) {
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
FlatBufferBuilder::kFileIdentifierLength) == 0;
}
@@ -1979,8 +2137,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
num_tables_(0),
max_tables_(_max_tables),
upper_bound_(0),
check_alignment_(_check_alignment)
{
check_alignment_(_check_alignment) {
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
}
@@ -2011,7 +2168,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
}
template<typename T> bool VerifyAlignment(size_t elem) const {
return (elem & (sizeof(T) - 1)) == 0 || !check_alignment_;
return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_);
}
// Verify a range indicated by sizeof(T).
@@ -2019,13 +2176,18 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T));
}
bool VerifyFromPointer(const uint8_t *p, size_t len) {
auto o = static_cast<size_t>(p - buf_);
return Verify(o, len);
}
// Verify relative to a known-good base pointer.
bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
}
template<typename T> bool Verify(const uint8_t *base, voffset_t elem_off)
const {
template<typename T>
bool Verify(const uint8_t *base, voffset_t elem_off) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
}
@@ -2048,16 +2210,15 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
// Verify a pointer (may be NULL) to string.
bool VerifyString(const String *str) const {
size_t end;
return !str ||
(VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
1, &end) &&
Verify(end, 1) && // Must have terminator
Check(buf_[end] == '\0')); // Terminating byte must be 0.
return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
1, &end) &&
Verify(end, 1) && // Must have terminator
Check(buf_[end] == '\0')); // Terminating byte must be 0.
}
// Common code between vectors and strings.
bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size,
size_t *end = nullptr) const {
size_t *end = nullptr) const {
auto veco = static_cast<size_t>(vec - buf_);
// Check we can read the size field.
if (!Verify<uoffset_t>(veco)) return false;
@@ -2092,11 +2253,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return true;
}
bool VerifyTableStart(const uint8_t *table) {
__supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
const uint8_t *table) {
// Check the vtable offset.
auto tableo = static_cast<size_t>(table - buf_);
if (!Verify<soffset_t>(tableo)) return false;
// This offset may be signed, but doing the substraction unsigned always
// This offset may be signed, but doing the subtraction unsigned always
// gives the result we want.
auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
// Check the vtable size field, then check vtable fits in its entirety.
@@ -2107,9 +2269,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
template<typename T>
bool VerifyBufferFromStart(const char *identifier, size_t start) {
if (identifier &&
(size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
!BufferHasIdentifier(buf_ + start, identifier))) {
if (identifier && (size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
!BufferHasIdentifier(buf_ + start, identifier))) {
return false;
}
@@ -2241,6 +2402,12 @@ class Struct FLATBUFFERS_FINAL_CLASS {
uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
private:
// private constructor & copy constructor: you obtain instances of this
// class by pointing to existing data only
Struct();
Struct(const Struct &);
Struct &operator=(const Struct &);
uint8_t data_[1];
};
@@ -2353,12 +2520,13 @@ class Table {
// class by pointing to existing data only
Table();
Table(const Table &other);
Table &operator=(const Table &);
uint8_t data_[1];
};
template<typename T> void FlatBufferBuilder::Required(Offset<T> table,
voffset_t field) {
template<typename T>
void FlatBufferBuilder::Required(Offset<T> table, voffset_t field) {
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
// If this fails, the caller will show what field needs to be set.
@@ -2405,7 +2573,9 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
}
/// @brief This return the prefixed size of a FlatBuffer.
inline uoffset_t GetPrefixedSize(const uint8_t* buf){ return ReadScalar<uoffset_t>(buf); }
inline uoffset_t GetPrefixedSize(const uint8_t *buf) {
return ReadScalar<uoffset_t>(buf);
}
// Base class for native objects (FlatBuffer data de-serialized into native
// C++ data structures).
@@ -2473,7 +2643,7 @@ inline int LookupEnum(const char **names, const char *name) {
#define FLATBUFFERS_STRUCT_END(name, size) \
__pragma(pack()) \
static_assert(sizeof(name) == size, "compiler breaks packing rules")
#elif defined(__GNUC__) || defined(__clang__)
#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
#define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
_Pragma("pack(1)") \
struct __attribute__((aligned(alignment)))
@@ -2548,10 +2718,10 @@ typedef const TypeTable *(*TypeFunction)();
struct TypeTable {
SequenceType st;
size_t num_elems; // of type_codes, values, names (but not type_refs).
const TypeCode *type_codes; // num_elems count
const TypeCode *type_codes; // num_elems count
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
const int64_t *values; // Only set for non-consecutive enum/union or structs.
const char * const *names; // Only set if compiled with --reflect-names.
const char *const *names; // Only set if compiled with --reflect-names.
};
// String which identifies the current version of FlatBuffers.

View File

@@ -14,18 +14,22 @@
* limitations under the License.
*/
#ifndef FLATBUFFERS_FLATC_H_
#define FLATBUFFERS_FLATC_H_
#include <functional>
#include <limits>
#include <string>
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#ifndef FLATC_H_
# define FLATC_H_
namespace flatbuffers {
extern void LogCompilerWarn(const std::string &warn);
extern void LogCompilerError(const std::string &err);
class FlatCompiler {
public:
// Output generator for the various programming languages and formats we
@@ -93,4 +97,4 @@ class FlatCompiler {
} // namespace flatbuffers
#endif // FLATC_H_
#endif // FLATBUFFERS_FLATC_H_

View File

@@ -65,7 +65,9 @@ enum Type {
FBT_VECTOR_UINT = 12,
FBT_VECTOR_FLOAT = 13,
FBT_VECTOR_KEY = 14,
FBT_VECTOR_STRING = 15,
// DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead.
// Read test.cpp/FlexBuffersDeprecatedTest() for details on why.
FBT_VECTOR_STRING_DEPRECATED = 15,
FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field).
FBT_VECTOR_UINT2 = 17,
FBT_VECTOR_FLOAT2 = 18,
@@ -88,7 +90,7 @@ inline bool IsTypedVectorElementType(Type t) {
}
inline bool IsTypedVector(Type t) {
return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING) ||
return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING_DEPRECATED) ||
t == FBT_VECTOR_BOOL;
}
@@ -212,26 +214,40 @@ class Object {
uint8_t byte_width_;
};
// Stores size in `byte_width_` bytes before data_ pointer.
// Object that has a size, obtained either from size prefix, or elsewhere.
class Sized : public Object {
public:
Sized(const uint8_t *data, uint8_t byte_width) : Object(data, byte_width) {}
size_t size() const {
// Size prefix.
Sized(const uint8_t *data, uint8_t byte_width)
: Object(data, byte_width), size_(read_size()) {}
// Manual size.
Sized(const uint8_t *data, uint8_t byte_width, size_t sz)
: Object(data, byte_width), size_(sz) {}
size_t size() const { return size_; }
// Access size stored in `byte_width_` bytes before data_ pointer.
size_t read_size() const {
return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
}
protected:
size_t size_;
};
class String : public Sized {
public:
// Size prefix.
String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
// Manual size.
String(const uint8_t *data, uint8_t byte_width, size_t sz)
: Sized(data, byte_width, sz) {}
size_t length() const { return size(); }
const char *c_str() const { return reinterpret_cast<const char *>(data_); }
std::string str() const { return std::string(c_str(), length()); }
std::string str() const { return std::string(c_str(), size()); }
static String EmptyString() {
static const uint8_t empty_string[] = { 0 /*len*/, 0 /*terminator*/ };
return String(empty_string + 1, 1);
static const char *empty_string = "";
return String(reinterpret_cast<const uint8_t *>(empty_string), 1, 0);
}
bool IsTheEmptyString() const { return data_ == EmptyString().data_; }
};
@@ -279,6 +295,8 @@ class TypedVector : public Sized {
Type ElementType() { return type_; }
friend Reference;
private:
Type type_;
@@ -339,16 +357,22 @@ class Map : public Vector {
template<typename T>
void AppendToString(std::string &s, T &&v, bool keys_quoted) {
s += "[ ";
for (size_t i = 0; i < v.size(); i++) {
if (i) s += ", ";
v[i].ToString(true, keys_quoted, s);
}
s += " ]";
s += "[ ";
for (size_t i = 0; i < v.size(); i++) {
if (i) s += ", ";
v[i].ToString(true, keys_quoted, s);
}
s += " ]";
}
class Reference {
public:
Reference()
: data_(nullptr),
parent_width_(0),
byte_width_(BIT_WIDTH_8),
type_(FBT_NULL) {}
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
Type type)
: data_(data),
@@ -378,15 +402,19 @@ class Reference {
bool IsString() const { return type_ == FBT_STRING; }
bool IsKey() const { return type_ == FBT_KEY; }
bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
bool IsUntypedVector() const { return type_ == FBT_VECTOR; }
bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
bool IsFixedTypedVector() const { return flexbuffers::IsFixedTypedVector(type_); }
bool IsAnyVector() const { return (IsTypedVector() || IsFixedTypedVector() || IsVector());}
bool IsFixedTypedVector() const {
return flexbuffers::IsFixedTypedVector(type_);
}
bool IsAnyVector() const {
return (IsTypedVector() || IsFixedTypedVector() || IsVector());
}
bool IsMap() const { return type_ == FBT_MAP; }
bool IsBlob() const { return type_ == FBT_BLOB; }
bool AsBool() const {
return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_)
: AsUInt64()) != 0;
: AsUInt64()) != 0;
}
// Reads any type as a int64_t. Never fails, does most sensible conversion.
@@ -464,7 +492,11 @@ class Reference {
case FBT_INDIRECT_UINT:
return static_cast<double>(ReadUInt64(Indirect(), byte_width_));
case FBT_NULL: return 0.0;
case FBT_STRING: return strtod(AsString().c_str(), nullptr);
case FBT_STRING: {
double d;
flatbuffers::StringToNumber(AsString().c_str(), &d);
return d;
}
case FBT_VECTOR: return static_cast<double>(AsVector().size());
case FBT_BOOL:
return static_cast<double>(ReadUInt64(data_, parent_width_));
@@ -477,17 +509,22 @@ class Reference {
float AsFloat() const { return static_cast<float>(AsDouble()); }
const char *AsKey() const {
if (type_ == FBT_KEY) {
if (type_ == FBT_KEY || type_ == FBT_STRING) {
return reinterpret_cast<const char *>(Indirect());
} else {
return "";
}
}
// This function returns the empty string if you try to read a not-string.
// This function returns the empty string if you try to read something that
// is not a string or key.
String AsString() const {
if (type_ == FBT_STRING) {
return String(Indirect(), byte_width_);
} else if (type_ == FBT_KEY) {
auto key = Indirect();
return String(key, byte_width_,
strlen(reinterpret_cast<const char *>(key)));
} else {
return String::EmptyString();
}
@@ -549,7 +586,8 @@ class Reference {
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
} else if (IsBlob()) {
auto blob = AsBlob();
flatbuffers::EscapeString(reinterpret_cast<const char*>(blob.data()), blob.size(), &s, true, false);
flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
blob.size(), &s, true, false);
} else {
s += "(?)";
}
@@ -577,8 +615,18 @@ class Reference {
TypedVector AsTypedVector() const {
if (IsTypedVector()) {
return TypedVector(Indirect(), byte_width_,
ToTypedVectorElementType(type_));
auto tv =
TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_));
if (tv.type_ == FBT_STRING) {
// These can't be accessed as strings, since we don't know the bit-width
// of the size field, see the declaration of
// FBT_VECTOR_STRING_DEPRECATED above for details.
// We change the type here to be keys, which are a subtype of strings,
// and will ignore the size field. This will truncate strings with
// embedded nulls.
tv.type_ = FBT_KEY;
}
return tv;
} else {
return TypedVector::EmptyTypedVector();
}
@@ -723,9 +771,15 @@ template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); }
template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
template<> inline uint16_t Reference::As<uint16_t>() const { return AsUInt16(); }
template<> inline uint32_t Reference::As<uint32_t>() const { return AsUInt32(); }
template<> inline uint64_t Reference::As<uint64_t>() const { return AsUInt64(); }
template<> inline uint16_t Reference::As<uint16_t>() const {
return AsUInt16();
}
template<> inline uint32_t Reference::As<uint32_t>() const {
return AsUInt32();
}
template<> inline uint64_t Reference::As<uint64_t>() const {
return AsUInt64();
}
template<> inline double Reference::As<double>() const { return AsDouble(); }
template<> inline float Reference::As<float>() const { return AsFloat(); }
@@ -1046,7 +1100,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
for (auto key = start; key < stack_.size(); key += 2) {
FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY);
}
// Now sort values, so later we can do a binary seach lookup.
// Now sort values, so later we can do a binary search lookup.
// We want to sort 2 array elements at a time.
struct TwoValue {
Value key;
@@ -1194,6 +1248,24 @@ class Builder FLATBUFFERS_FINAL_CLASS {
EndMap(start);
}
// If you wish to share a value explicitly (a value not shared automatically
// through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these
// functions. Or if you wish to turn those flags off for performance reasons
// and still do some explicit sharing. For example:
// builder.IndirectDouble(M_PI);
// auto id = builder.LastValue(); // Remember where we stored it.
// .. more code goes here ..
// builder.ReuseValue(id); // Refers to same double by offset.
// LastValue works regardless of wether the value has a key or not.
// Works on any data type.
struct Value;
Value LastValue() { return stack_.back(); }
void ReuseValue(Value v) { stack_.push_back(v); }
void ReuseValue(const char *key, Value v) {
Key(key);
ReuseValue(v);
}
// Overloaded Add that tries to call the correct function above.
void Add(int8_t i) { Int(i); }
void Add(int16_t i) { Int(i); }
@@ -1319,6 +1391,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
: FBT_INT);
}
public:
// This was really intended to be private, except for LastValue/ReuseValue.
struct Value {
union {
int64_t i_;
@@ -1388,6 +1462,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
}
};
private:
void WriteAny(const Value &val, uint8_t byte_width) {
switch (val.type_) {
case FBT_NULL:
@@ -1420,6 +1495,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// TODO: instead of asserting, could write vector with larger elements
// instead, though that would be wasteful.
FLATBUFFERS_ASSERT(WidthU(len) <= bit_width);
Align(bit_width);
if (!fixed) Write<uint64_t>(len, byte_width);
auto vloc = buf_.size();
for (size_t i = 0; i < len; i++) Write(elems[i], byte_width);
@@ -1431,7 +1507,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
bool fixed, const Value *keys = nullptr) {
FLATBUFFERS_ASSERT(!fixed || typed); // typed=false, fixed=true combination is not supported.
FLATBUFFERS_ASSERT(
!fixed ||
typed); // typed=false, fixed=true combination is not supported.
// Figure out smallest bit width we can store this vector with.
auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
auto prefix_elems = 1;
@@ -1511,7 +1589,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
typedef std::pair<size_t, size_t> StringOffset;
struct StringOffsetCompare {
explicit StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
explicit StringOffsetCompare(const std::vector<uint8_t> &buf)
: buf_(&buf) {}
bool operator()(const StringOffset &a, const StringOffset &b) const {
auto stra = reinterpret_cast<const char *>(
flatbuffers::vector_data(*buf_) + a.first);
@@ -1531,8 +1610,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
} // namespace flexbuffers
# if defined(_MSC_VER)
# pragma warning(pop)
# endif
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif // FLATBUFFERS_FLEXBUFFERS_H_

View File

@@ -88,8 +88,7 @@ class SliceAllocator : public Allocator {
SliceAllocator(const SliceAllocator &other) = delete;
SliceAllocator &operator=(const SliceAllocator &other) = delete;
SliceAllocator(SliceAllocator &&other)
: slice_(grpc_empty_slice()) {
SliceAllocator(SliceAllocator &&other) : slice_(grpc_empty_slice()) {
// default-construct and swap idiom
swap(other);
}
@@ -164,34 +163,36 @@ class MessageBuilder : private detail::SliceAllocatorMember,
public FlatBufferBuilder {
public:
explicit MessageBuilder(uoffset_t initial_size = 1024)
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
MessageBuilder(const MessageBuilder &other) = delete;
MessageBuilder &operator=(const MessageBuilder &other) = delete;
MessageBuilder(MessageBuilder &&other)
: FlatBufferBuilder(1024, &slice_allocator_, false) {
: FlatBufferBuilder(1024, &slice_allocator_, false) {
// Default construct and swap idiom.
Swap(other);
}
/// Create a MessageBuilder from a FlatBufferBuilder.
explicit MessageBuilder(FlatBufferBuilder &&src, void (*dealloc)(void*, size_t) = &DefaultAllocator::dealloc)
: FlatBufferBuilder(1024, &slice_allocator_, false) {
explicit MessageBuilder(FlatBufferBuilder &&src,
void (*dealloc)(void *,
size_t) = &DefaultAllocator::dealloc)
: FlatBufferBuilder(1024, &slice_allocator_, false) {
src.Swap(*this);
src.SwapBufAllocator(*this);
if (buf_.capacity()) {
uint8_t *buf = buf_.scratch_data(); // pointer to memory
size_t capacity = buf_.capacity(); // size of memory
uint8_t *buf = buf_.scratch_data(); // pointer to memory
size_t capacity = buf_.capacity(); // size of memory
slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
}
else {
} else {
slice_allocator_.slice_ = grpc_empty_slice();
}
}
/// Move-assign a FlatBufferBuilder to a MessageBuilder.
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is supported.
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is
/// supported.
MessageBuilder &operator=(FlatBufferBuilder &&src) {
// Move construct a temporary and swap
MessageBuilder temp(std::move(src));
@@ -209,10 +210,11 @@ class MessageBuilder : private detail::SliceAllocatorMember,
void Swap(MessageBuilder &other) {
slice_allocator_.swap(other.slice_allocator_);
FlatBufferBuilder::Swap(other);
// After swapping the FlatBufferBuilder, we swap back the allocator, which restores
// the original allocator back in place. This is necessary because MessageBuilder's
// allocator is its own member (SliceAllocatorMember). The allocator passed to
// FlatBufferBuilder::vector_downward must point to this member.
// After swapping the FlatBufferBuilder, we swap back the allocator, which
// restores the original allocator back in place. This is necessary because
// MessageBuilder's allocator is its own member (SliceAllocatorMember). The
// allocator passed to FlatBufferBuilder::vector_downward must point to this
// member.
buf_.swap_allocator(other.buf_);
}
@@ -232,10 +234,10 @@ class MessageBuilder : private detail::SliceAllocatorMember,
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
// ownership.
template<class T> Message<T> GetMessage() {
auto buf_data = buf_.scratch_data(); // pointer to memory
auto buf_size = buf_.capacity(); // size of memory
auto msg_data = buf_.data(); // pointer to msg
auto msg_size = buf_.size(); // size of msg
auto buf_data = buf_.scratch_data(); // pointer to memory
auto buf_size = buf_.capacity(); // size of memory
auto msg_data = buf_.data(); // pointer to msg
auto msg_size = buf_.size(); // size of msg
// Do some sanity checks on data/size
FLATBUFFERS_ASSERT(msg_data);
FLATBUFFERS_ASSERT(msg_size);
@@ -274,7 +276,7 @@ template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
grpc_byte_buffer **buffer, bool *own_buffer) {
// We are passed in a `Message<T>`, which is a wrapper around a
// `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast
// is necesary because the `grpc_raw_byte_buffer_create` func expects
// is necessary because the `grpc_raw_byte_buffer_create` func expects
// non-const slices in order to increment their refcounts.
grpc_slice *slice = const_cast<grpc_slice *>(&msg.BorrowSlice());
// Now use `grpc_raw_byte_buffer_create` to package the single slice into a
@@ -306,7 +308,7 @@ template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
grpc_byte_buffer_reader_init(&reader, buffer);
grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
grpc_byte_buffer_reader_destroy(&reader);
// We wrap a `Message<T>` around the slice, but dont increment refcount
// We wrap a `Message<T>` around the slice, but don't increment refcount
*msg = flatbuffers::grpc::Message<T>(slice, false);
}
grpc_byte_buffer_destroy(buffer);

View File

@@ -57,17 +57,17 @@ template<typename T> T HashFnv1a(const char *input) {
return hash;
}
template <> inline uint16_t HashFnv1<uint16_t>(const char *input) {
template<> inline uint16_t HashFnv1<uint16_t>(const char *input) {
uint32_t hash = HashFnv1<uint32_t>(input);
return (hash >> 16) ^ (hash & 0xffff);
}
template <> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
template<> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
uint32_t hash = HashFnv1a<uint32_t>(input);
return (hash >> 16) ^ (hash & 0xffff);
}
template <typename T> struct NamedHashFunction {
template<typename T> struct NamedHashFunction {
const char *name;
typedef T (*HashFunction)(const char *);
@@ -75,7 +75,7 @@ template <typename T> struct NamedHashFunction {
};
const NamedHashFunction<uint16_t> kHashFunctions16[] = {
{ "fnv1_16", HashFnv1<uint16_t> },
{ "fnv1_16", HashFnv1<uint16_t> },
{ "fnv1a_16", HashFnv1a<uint16_t> },
};

View File

@@ -47,25 +47,26 @@ namespace flatbuffers {
// of type tokens.
// clang-format off
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8) \
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8) /* begin scalar/int */ \
TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool) \
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8) \
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8) \
TD(SHORT, "short", int16_t, short, int16, short, int16, i16) \
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16) \
TD(INT, "int", int32_t, int, int32, int, int32, i32) \
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32) \
TD(LONG, "long", int64_t, long, int64, long, int64, i64) \
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64) /* end int */ \
TD(FLOAT, "float", float, float, float32, float, float32, f32) /* begin float */ \
TD(DOUBLE, "double", double, double, float64, double, float64, f64) /* end float/scalar */
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) /* begin scalar/int */ \
TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean, Bool) \
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte, Int8) \
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \
TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short, Int16) \
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort, UInt16) \
TD(INT, "int", int32_t, int, int32, int, int32, i32, Int, Int32) \
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt, UInt32) \
TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long, Int64) \
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong, UInt64) /* end int */ \
TD(FLOAT, "float", float, float, float32, float, float32, f32, Float, Float32) /* begin float */ \
TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double, Double) /* end float/scalar */
#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused) \
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused) \
TD(STRUCT, "", Offset<void>, int, int, int, int, unused) \
TD(UNION, "", Offset<void>, int, int, int, int, unused)
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int, Offset<String>) \
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>) \
TD(STRUCT, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>) \
TD(UNION, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>)
#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \
TD(ARRAY, "", int, int, int, int, int, unused, Int, Offset<UOffset>)
// The fields are:
// - enum
// - FlatBuffers schema type.
@@ -75,13 +76,28 @@ namespace flatbuffers {
// - C# / .Net type.
// - Python type.
// - Rust type.
// - Kotlin type.
// using these macros, we can now write code dealing with types just once, e.g.
/*
switch (type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
RTYPE) \
RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \
// do something specific to CTYPE here
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
}
*/
// If not all FLATBUFFERS_GEN_() arguments are necessary for implementation
// of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed).
// In the above example, only CTYPE is used to generate the code, it can be rewritten:
/*
switch (type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
case BASE_TYPE_ ## ENUM: \
// do something specific to CTYPE here
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
@@ -91,24 +107,23 @@ switch (type) {
#define FLATBUFFERS_GEN_TYPES(TD) \
FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
FLATBUFFERS_GEN_TYPES_POINTER(TD)
FLATBUFFERS_GEN_TYPES_POINTER(TD) \
FLATBUFFERS_GEN_TYPE_ARRAY(TD)
// Create an enum for all the types above.
#ifdef __GNUC__
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
#endif
enum BaseType {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
RTYPE) \
BASE_TYPE_ ## ENUM,
#define FLATBUFFERS_TD(ENUM, ...) \
BASE_TYPE_ ## ENUM,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
};
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
RTYPE) \
static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
"define largest_scalar_t as " #CTYPE);
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
"define largest_scalar_t as " #CTYPE);
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
@@ -123,6 +138,13 @@ inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; }
inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE &&
t <= BASE_TYPE_UCHAR; }
inline bool IsUnsigned(BaseType t) {
return (t == BASE_TYPE_UTYPE) || (t == BASE_TYPE_UCHAR) ||
(t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT) ||
(t == BASE_TYPE_ULONG);
}
// clang-format on
extern const char *const kTypeNames[];
@@ -138,18 +160,21 @@ class Parser;
// and additional information for vectors/structs_.
struct Type {
explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
EnumDef *_ed = nullptr)
EnumDef *_ed = nullptr, uint16_t _fixed_length = 0)
: base_type(_base_type),
element(BASE_TYPE_NONE),
struct_def(_sd),
enum_def(_ed) {}
enum_def(_ed),
fixed_length(_fixed_length) {}
bool operator==(const Type &o) {
return base_type == o.base_type && element == o.element &&
struct_def == o.struct_def && enum_def == o.enum_def;
}
Type VectorType() const { return Type(element, struct_def, enum_def); }
Type VectorType() const {
return Type(element, struct_def, enum_def, fixed_length);
}
Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;
@@ -160,6 +185,7 @@ struct Type {
StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT
EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
// or for an integral type derived from an enum.
uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY
};
// Represents a parsed scalar value, it's type, and field offset.
@@ -224,6 +250,15 @@ struct Namespace {
size_t from_table; // Part of the namespace corresponds to a message/table.
};
inline bool operator<(const Namespace &a, const Namespace &b) {
size_t min_size = std::min(a.components.size(), b.components.size());
for (size_t i = 0; i < min_size; ++i) {
if (a.components[i] != b.components[i])
return a.components[i] < b.components[i];
}
return a.components.size() < b.components.size();
}
// Base class for all definition types (fields, structs_, enums_).
struct Definition {
Definition()
@@ -315,64 +350,138 @@ struct StructDef : public Definition {
flatbuffers::unique_ptr<std::string> original_location;
};
inline bool IsStruct(const Type &type) {
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
}
inline size_t InlineSize(const Type &type) {
return IsStruct(type) ? type.struct_def->bytesize : SizeOf(type.base_type);
}
inline size_t InlineAlignment(const Type &type) {
return IsStruct(type) ? type.struct_def->minalign : SizeOf(type.base_type);
}
struct EnumDef;
struct EnumValBuilder;
struct EnumVal {
EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
EnumVal() : value(0) {}
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(const Parser &parser, const reflection::EnumVal *val);
uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); }
int64_t GetAsInt64() const { return value; }
bool IsZero() const { return 0 == value; }
bool IsNonZero() const { return !IsZero(); }
std::string name;
std::vector<std::string> doc_comment;
int64_t value;
Type union_type;
private:
friend EnumDef;
friend EnumValBuilder;
friend bool operator==(const EnumVal &lhs, const EnumVal &rhs);
EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
EnumVal() : value(0) {}
int64_t value;
};
struct EnumDef : public Definition {
EnumDef() : is_union(false), uses_multiple_type_instances(false) {}
EnumVal *ReverseLookup(int64_t enum_idx, bool skip_union_default = true) {
for (auto it = Vals().begin() +
static_cast<int>(is_union && skip_union_default);
it != Vals().end(); ++it) {
if ((*it)->value == enum_idx) { return *it; }
}
return nullptr;
}
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::Enum *values);
template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val);
void SortByValue();
void RemoveDuplicates();
std::string AllFlags() const;
const EnumVal *MinValue() const;
const EnumVal *MaxValue() const;
// Returns the number of integer steps from v1 to v2.
uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const;
// Returns the number of integer steps from Min to Max.
uint64_t Distance() const { return Distance(MinValue(), MaxValue()); }
EnumVal *ReverseLookup(int64_t enum_idx,
bool skip_union_default = false) const;
EnumVal *FindByValue(const std::string &constant) const;
std::string ToString(const EnumVal &ev) const {
return IsUInt64() ? NumToString(ev.GetAsUInt64())
: NumToString(ev.GetAsInt64());
}
size_t size() const { return vals.vec.size(); }
const std::vector<EnumVal *> &Vals() const {
return vals.vec;
}
SymbolTable<EnumVal> vals;
const EnumVal *Lookup(const std::string &enum_name) const {
return vals.Lookup(enum_name);
}
bool is_union;
// Type is a union which uses type aliases where at least one type is
// available under two different names.
bool uses_multiple_type_instances;
Type underlying_type;
private:
bool IsUInt64() const {
return (BASE_TYPE_ULONG == underlying_type.base_type);
}
friend EnumValBuilder;
SymbolTable<EnumVal> vals;
};
inline bool IsStruct(const Type &type) {
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
}
inline bool IsUnion(const Type &type) {
return type.enum_def != nullptr && type.enum_def->is_union;
}
inline bool IsVector(const Type &type) {
return type.base_type == BASE_TYPE_VECTOR;
}
inline bool IsArray(const Type &type) {
return type.base_type == BASE_TYPE_ARRAY;
}
inline bool IsSeries(const Type &type) {
return IsVector(type) || IsArray(type);
}
inline bool IsEnum(const Type &type) {
return type.enum_def != nullptr && IsInteger(type.base_type);
}
inline size_t InlineSize(const Type &type) {
return IsStruct(type)
? type.struct_def->bytesize
: (IsArray(type)
? InlineSize(type.VectorType()) * type.fixed_length
: SizeOf(type.base_type));
}
inline size_t InlineAlignment(const Type &type) {
if (IsStruct(type)) {
return type.struct_def->minalign;
} else if (IsArray(type)) {
return IsStruct(type.VectorType()) ? type.struct_def->minalign
: SizeOf(type.element);
} else {
return SizeOf(type.base_type);
}
}
inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) {
return lhs.value == rhs.value;
}
inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) {
return !(lhs == rhs);
}
inline bool EqualByName(const Type &a, const Type &b) {
return a.base_type == b.base_type && a.element == b.element &&
(a.struct_def == b.struct_def ||
@@ -381,7 +490,8 @@ inline bool EqualByName(const Type &a, const Type &b) {
}
struct RPCCall : public Definition {
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::RPCCall *call);
@@ -389,7 +499,8 @@ struct RPCCall : public Definition {
};
struct ServiceDef : public Definition {
Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::Service *service);
SymbolTable<RPCCall> calls;
@@ -397,6 +508,8 @@ struct ServiceDef : public Definition {
// Container of options that may apply to any of the source/text generators.
struct IDLOptions {
// Use flexbuffers instead for binary and text generation
bool use_flexbuffers;
bool strict_json;
bool skip_js_exports;
bool use_goog_js_export_format;
@@ -420,6 +533,7 @@ struct IDLOptions {
std::string cpp_object_api_string_type;
bool cpp_object_api_string_flexible_constructor;
bool gen_nullable;
bool java_checkerframework;
bool gen_generated;
std::string object_prefix;
std::string object_suffix;
@@ -430,6 +544,7 @@ struct IDLOptions {
bool keep_include_path;
bool binary_schema_comments;
bool binary_schema_builtins;
bool binary_schema_gen_embed;
bool skip_flatbuffers_import;
std::string go_import;
std::string go_namespace;
@@ -439,6 +554,13 @@ struct IDLOptions {
bool size_prefixed;
std::string root_type;
bool force_defaults;
bool java_primitive_has_method;
bool cs_gen_json_serializer;
std::vector<std::string> cpp_includes;
std::string cpp_std;
std::string proto_namespace_suffix;
std::string filename_suffix;
std::string filename_extension;
// Possible options for the more general generator below.
enum Language {
@@ -457,6 +579,8 @@ struct IDLOptions {
kLua = 1 << 12,
kLobster = 1 << 13,
kRust = 1 << 14,
kKotlin = 1 << 15,
kSwift = 1 << 16,
kMAX
};
@@ -470,12 +594,17 @@ struct IDLOptions {
// for code generation.
unsigned long lang_to_generate;
// If set (default behavior), empty string and vector fields will be set to
// nullptr to make the flatbuffer more compact.
bool set_empty_to_null;
// If set (default behavior), empty string fields will be set to nullptr to
// make the flatbuffer more compact.
bool set_empty_strings_to_null;
// If set (default behavior), empty vector fields will be set to nullptr to
// make the flatbuffer more compact.
bool set_empty_vectors_to_null;
IDLOptions()
: strict_json(false),
: use_flexbuffers(false),
strict_json(false),
skip_js_exports(false),
use_goog_js_export_format(false),
use_ES6_js_export_format(false),
@@ -497,6 +626,7 @@ struct IDLOptions {
cpp_object_api_pointer_type("std::unique_ptr"),
cpp_object_api_string_flexible_constructor(false),
gen_nullable(false),
java_checkerframework(false),
gen_generated(false),
object_suffix("T"),
union_value_namespacing(true),
@@ -505,16 +635,22 @@ struct IDLOptions {
keep_include_path(false),
binary_schema_comments(false),
binary_schema_builtins(false),
binary_schema_gen_embed(false),
skip_flatbuffers_import(false),
reexport_ts_modules(true),
js_ts_short_names(false),
protobuf_ascii_alike(false),
size_prefixed(false),
force_defaults(false),
java_primitive_has_method(false),
cs_gen_json_serializer(false),
filename_suffix("_generated"),
filename_extension(),
lang(IDLOptions::kJava),
mini_reflect(IDLOptions::kNone),
lang_to_generate(0),
set_empty_to_null(true) {}
set_empty_strings_to_null(true),
set_empty_vectors_to_null(true) {}
};
// This encapsulates where the parser is in the current source file.
@@ -607,15 +743,14 @@ class Parser : public ParserState {
explicit Parser(const IDLOptions &options = IDLOptions())
: current_namespace_(nullptr),
empty_namespace_(nullptr),
flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL),
root_struct_def_(nullptr),
opts(options),
uses_flexbuffers_(false),
source_(nullptr),
anonymous_counter(0),
recurse_protection_counter(0) {
if (opts.force_defaults) {
builder_.ForceDefaults(true);
}
if (opts.force_defaults) { builder_.ForceDefaults(true); }
// Start out with the empty namespace being current.
empty_namespace_ = new Namespace();
namespaces_.push_back(empty_namespace_);
@@ -686,9 +821,9 @@ class Parser : public ParserState {
// Fills internal structure as if the schema passed had been loaded by parsing
// with Parse except that included filenames will not be populated.
bool Deserialize(const reflection::Schema* schema);
bool Deserialize(const reflection::Schema *schema);
Type* DeserializeType(const reflection::Type* type);
Type *DeserializeType(const reflection::Type *type);
// Checks that the schema represented by this parser is a safe evolution
// of the schema provided. Returns non-empty error on any problems.
@@ -701,7 +836,7 @@ class Parser : public ParserState {
StructDef *LookupStruct(const std::string &id) const;
std::string UnqualifiedName(std::string fullQualifiedName);
std::string UnqualifiedName(const std::string &fullQualifiedName);
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
@@ -738,20 +873,26 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
std::string *value, uoffset_t *ovalue);
void SerializeStruct(const StructDef &struct_def, const Value &val);
void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def,
const Value &val);
template<typename F>
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body);
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
FieldDef *field, size_t fieldn);
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field,
size_t fieldn,
const StructDef *parent_struct_def);
FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
Value &val, FieldDef *field, size_t fieldn,
const StructDef *parent_struct_def);
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, bool check, Value &e,
BaseType req, bool *destmatch);
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
bool check, Value &e, BaseType req,
bool *destmatch);
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field);
FLATBUFFERS_CHECKED_ERROR TokenError();
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, bool check_now);
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, std::string *result);
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
bool check_now);
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
std::string *result);
StructDef *LookupCreateStruct(const std::string &name,
bool create_if_new = true,
bool definition = false);
@@ -759,8 +900,7 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR ParseNamespace();
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
StructDef **dest);
FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name,
bool is_union,
FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
EnumDef **dest);
FLATBUFFERS_CHECKED_ERROR ParseDecl();
FLATBUFFERS_CHECKED_ERROR ParseService();
@@ -776,18 +916,18 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
const char *source_filename);
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
const char **include_paths,
const char *source_filename);
const char **include_paths,
const char *source_filename);
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
const char **include_paths,
const char *source_filename,
const char *include_filename);
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
const char **include_paths,
const char *source_filename,
const char *include_filename);
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
StructDef *struct_def,
const char *suffix,
BaseType baseType);
const char *suffix, BaseType baseType);
bool SupportsAdvancedUnionFeatures() const;
bool SupportsAdvancedArrayFeatures() const;
Namespace *UniqueNamespace(Namespace *ns);
FLATBUFFERS_CHECKED_ERROR RecurseError();
@@ -801,9 +941,11 @@ class Parser : public ParserState {
std::vector<Namespace *> namespaces_;
Namespace *current_namespace_;
Namespace *empty_namespace_;
std::string error_; // User readable error_ if Parse() == false
std::string error_; // User readable error_ if Parse() == false
FlatBufferBuilder builder_; // any data contained in the file
flexbuffers::Builder flex_builder_;
flexbuffers::Reference flex_root_;
StructDef *root_struct_def_;
std::string file_identifier_;
std::string file_extension_;
@@ -832,6 +974,8 @@ class Parser : public ParserState {
extern std::string MakeCamel(const std::string &in, bool first = true);
extern std::string MakeScreamingCamel(const std::string &in);
// Generate text (JSON) from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// If ident_step is 0, no indentation will be generated. Additionally,
@@ -840,156 +984,154 @@ extern std::string MakeCamel(const std::string &in, bool first = true);
// strict_json adds "quotes" around field names if true.
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
// byte arrays in String values), returns false.
extern bool GenerateTextFromTable(const Parser &parser,
const void *table,
extern bool GenerateTextFromTable(const Parser &parser, const void *table,
const std::string &tablename,
std::string *text);
extern bool GenerateText(const Parser &parser,
const void *flatbuffer,
extern bool GenerateText(const Parser &parser, const void *flatbuffer,
std::string *text);
extern bool GenerateTextFile(const Parser &parser,
const std::string &path,
extern bool GenerateTextFile(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate binary files from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema.
// See idl_gen_general.cpp.
extern bool GenerateBinary(const Parser &parser,
const std::string &path,
// See code_generators.cpp.
extern bool GenerateBinary(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a C++ header from the definitions in the Parser object.
// See idl_gen_cpp.
extern bool GenerateCPP(const Parser &parser,
const std::string &path,
extern bool GenerateCPP(const Parser &parser, const std::string &path,
const std::string &file_name);
extern bool GenerateDart(const Parser &parser,
const std::string &path,
// Generate C# files from the definitions in the Parser object.
// See idl_gen_csharp.cpp.
extern bool GenerateCSharp(const Parser &parser, const std::string &path,
const std::string &file_name);
extern bool GenerateDart(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate JavaScript or TypeScript code from the definitions in the Parser object.
// See idl_gen_js.
extern bool GenerateJSTS(const Parser &parser,
const std::string &path,
const std::string &file_name);
// Generate Java files from the definitions in the Parser object.
// See idl_gen_java.cpp.
extern bool GenerateJava(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate JavaScript or TypeScript code from the definitions in the Parser
// object. See idl_gen_js.
extern bool GenerateJSTS(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Go files from the definitions in the Parser object.
// See idl_gen_go.cpp.
extern bool GenerateGo(const Parser &parser,
const std::string &path,
extern bool GenerateGo(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Php code from the definitions in the Parser object.
// See idl_gen_php.
extern bool GeneratePhp(const Parser &parser,
const std::string &path,
extern bool GeneratePhp(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Python files from the definitions in the Parser object.
// See idl_gen_python.cpp.
extern bool GeneratePython(const Parser &parser,
const std::string &path,
extern bool GeneratePython(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Lobster files from the definitions in the Parser object.
// See idl_gen_lobster.cpp.
extern bool GenerateLobster(const Parser &parser,
const std::string &path,
extern bool GenerateLobster(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Lua files from the definitions in the Parser object.
// See idl_gen_lua.cpp.
extern bool GenerateLua(const Parser &parser,
const std::string &path,
const std::string &file_name);
extern bool GenerateLua(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Rust files from the definitions in the Parser object.
// See idl_gen_rust.cpp.
extern bool GenerateRust(const Parser &parser,
const std::string &path,
extern bool GenerateRust(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Json schema file
// See idl_gen_json_schema.cpp.
extern bool GenerateJsonSchema(const Parser &parser,
const std::string &path,
extern bool GenerateJsonSchema(const Parser &parser, const std::string &path,
const std::string &file_name);
extern bool GenerateKotlin(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Java/C#/.. files from the definitions in the Parser object.
// See idl_gen_general.cpp.
extern bool GenerateGeneral(const Parser &parser,
const std::string &path,
const std::string &file_name);
// Generate Swift classes.
// See idl_gen_swift.cpp
extern bool GenerateSwift(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a schema file from the internal representation, useful after
// parsing a .proto schema.
extern std::string GenerateFBS(const Parser &parser,
const std::string &file_name);
extern bool GenerateFBS(const Parser &parser,
const std::string &path,
extern bool GenerateFBS(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated JavaScript or TypeScript code.
// See idl_gen_js.cpp.
extern std::string JSTSMakeRule(const Parser &parser,
const std::string &path,
const std::string &file_name);
extern std::string JSTSMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated C++ header.
// See idl_gen_cpp.cpp.
extern std::string CPPMakeRule(const Parser &parser,
const std::string &path,
extern std::string CPPMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated Dart code
// see idl_gen_dart.cpp
extern std::string DartMakeRule(const Parser &parser,
const std::string &path,
extern std::string DartMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated Rust code.
// See idl_gen_rust.cpp.
extern std::string RustMakeRule(const Parser &parser,
const std::string &path,
extern std::string RustMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated Java/C#/... files.
// See idl_gen_general.cpp.
extern std::string GeneralMakeRule(const Parser &parser,
const std::string &path,
const std::string &file_name);
// Generate a make rule for generated Java or C# files.
// See code_generators.cpp.
extern std::string JavaCSharpMakeRule(const Parser &parser,
const std::string &path,
const std::string &file_name);
// Generate a make rule for the generated text (JSON) files.
// See idl_gen_text.cpp.
extern std::string TextMakeRule(const Parser &parser,
const std::string &path,
extern std::string TextMakeRule(const Parser &parser, const std::string &path,
const std::string &file_names);
// Generate a make rule for the generated binary files.
// See idl_gen_general.cpp.
extern std::string BinaryMakeRule(const Parser &parser,
const std::string &path,
// See code_generators.cpp.
extern std::string BinaryMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate GRPC Cpp interfaces.
// See idl_gen_grpc.cpp.
bool GenerateCppGRPC(const Parser &parser,
const std::string &path,
bool GenerateCppGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate GRPC Go interfaces.
// See idl_gen_grpc.cpp.
bool GenerateGoGRPC(const Parser &parser,
const std::string &path,
bool GenerateGoGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate GRPC Java classes.
// See idl_gen_grpc.cpp
bool GenerateJavaGRPC(const Parser &parser,
const std::string &path,
bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate GRPC Python interfaces.
// See idl_gen_grpc.cpp.
bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate GRPC Swift interfaces.
// See idl_gen_grpc.cpp.
extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
const std::string &file_name);
} // namespace flatbuffers
#endif // FLATBUFFERS_IDL_H_

View File

@@ -88,7 +88,8 @@ inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
switch (type_table->st) {
case ST_TABLE:
case ST_UNION: return 4;
case ST_STRUCT: return static_cast<size_t>(type_table->values[type_table->num_elems]);
case ST_STRUCT:
return static_cast<size_t>(type_table->values[type_table->num_elems]);
default: FLATBUFFERS_ASSERT(false); return 1;
}
default: FLATBUFFERS_ASSERT(false); return 1;

View File

@@ -228,7 +228,7 @@ inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
template<typename T>
T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
return reinterpret_cast<T*>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
return reinterpret_cast<T *>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
}
// Get the inline-address of a vector element. Useful for Structs (pass Struct

View File

@@ -9,22 +9,31 @@
namespace reflection {
struct Type;
struct TypeBuilder;
struct KeyValue;
struct KeyValueBuilder;
struct EnumVal;
struct EnumValBuilder;
struct Enum;
struct EnumBuilder;
struct Field;
struct FieldBuilder;
struct Object;
struct ObjectBuilder;
struct RPCCall;
struct RPCCallBuilder;
struct Service;
struct ServiceBuilder;
struct Schema;
struct SchemaBuilder;
enum BaseType {
None = 0,
@@ -43,10 +52,11 @@ enum BaseType {
String = 13,
Vector = 14,
Obj = 15,
Union = 16
Union = 16,
Array = 17
};
inline const BaseType (&EnumValuesBaseType())[17] {
inline const BaseType (&EnumValuesBaseType())[18] {
static const BaseType values[] = {
None,
UType,
@@ -64,13 +74,14 @@ inline const BaseType (&EnumValuesBaseType())[17] {
String,
Vector,
Obj,
Union
Union,
Array
};
return values;
}
inline const char * const *EnumNamesBaseType() {
static const char * const names[] = {
static const char * const names[19] = {
"None",
"UType",
"Bool",
@@ -88,53 +99,64 @@ inline const char * const *EnumNamesBaseType() {
"Vector",
"Obj",
"Union",
"Array",
nullptr
};
return names;
}
inline const char *EnumNameBaseType(BaseType e) {
if (e < None || e > Union) return "";
if (flatbuffers::IsOutRange(e, None, Array)) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesBaseType()[index];
}
struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef TypeBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_BASE_TYPE = 4,
VT_ELEMENT = 6,
VT_INDEX = 8
VT_INDEX = 8,
VT_FIXED_LENGTH = 10
};
BaseType base_type() const {
return static_cast<BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
reflection::BaseType base_type() const {
return static_cast<reflection::BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
}
BaseType element() const {
return static_cast<BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
reflection::BaseType element() const {
return static_cast<reflection::BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
}
int32_t index() const {
return GetField<int32_t>(VT_INDEX, -1);
}
uint16_t fixed_length() const {
return GetField<uint16_t>(VT_FIXED_LENGTH, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int8_t>(verifier, VT_BASE_TYPE) &&
VerifyField<int8_t>(verifier, VT_ELEMENT) &&
VerifyField<int32_t>(verifier, VT_INDEX) &&
VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) &&
verifier.EndTable();
}
};
struct TypeBuilder {
typedef Type Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_base_type(BaseType base_type) {
void add_base_type(reflection::BaseType base_type) {
fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0);
}
void add_element(BaseType element) {
void add_element(reflection::BaseType element) {
fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0);
}
void add_index(int32_t index) {
fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1);
}
void add_fixed_length(uint16_t fixed_length) {
fbb_.AddElement<uint16_t>(Type::VT_FIXED_LENGTH, fixed_length, 0);
}
explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
@@ -149,17 +171,20 @@ struct TypeBuilder {
inline flatbuffers::Offset<Type> CreateType(
flatbuffers::FlatBufferBuilder &_fbb,
BaseType base_type = None,
BaseType element = None,
int32_t index = -1) {
reflection::BaseType base_type = reflection::None,
reflection::BaseType element = reflection::None,
int32_t index = -1,
uint16_t fixed_length = 0) {
TypeBuilder builder_(_fbb);
builder_.add_index(index);
builder_.add_fixed_length(fixed_length);
builder_.add_element(element);
builder_.add_base_type(base_type);
return builder_.Finish();
}
struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef KeyValueBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_KEY = 4,
VT_VALUE = 6
@@ -187,6 +212,7 @@ struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct KeyValueBuilder {
typedef KeyValue Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_key(flatbuffers::Offset<flatbuffers::String> key) {
@@ -231,6 +257,7 @@ inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
}
struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef EnumValBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_VALUE = 6,
@@ -250,11 +277,11 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(int64_t val) const {
return static_cast<int>(value() > val) - static_cast<int>(value() < val);
}
const Object *object() const {
return GetPointer<const Object *>(VT_OBJECT);
const reflection::Object *object() const {
return GetPointer<const reflection::Object *>(VT_OBJECT);
}
const Type *union_type() const {
return GetPointer<const Type *>(VT_UNION_TYPE);
const reflection::Type *union_type() const {
return GetPointer<const reflection::Type *>(VT_UNION_TYPE);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -276,6 +303,7 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct EnumValBuilder {
typedef EnumVal Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
@@ -284,10 +312,10 @@ struct EnumValBuilder {
void add_value(int64_t value) {
fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0);
}
void add_object(flatbuffers::Offset<Object> object) {
void add_object(flatbuffers::Offset<reflection::Object> object) {
fbb_.AddOffset(EnumVal::VT_OBJECT, object);
}
void add_union_type(flatbuffers::Offset<Type> union_type) {
void add_union_type(flatbuffers::Offset<reflection::Type> union_type) {
fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -310,8 +338,8 @@ inline flatbuffers::Offset<EnumVal> CreateEnumVal(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
int64_t value = 0,
flatbuffers::Offset<Object> object = 0,
flatbuffers::Offset<Type> union_type = 0,
flatbuffers::Offset<reflection::Object> object = 0,
flatbuffers::Offset<reflection::Type> union_type = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
EnumValBuilder builder_(_fbb);
builder_.add_value(value);
@@ -326,8 +354,8 @@ inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
int64_t value = 0,
flatbuffers::Offset<Object> object = 0,
flatbuffers::Offset<Type> union_type = 0,
flatbuffers::Offset<reflection::Object> object = 0,
flatbuffers::Offset<reflection::Type> union_type = 0,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
@@ -341,6 +369,7 @@ inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
}
struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef EnumBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_VALUES = 6,
@@ -358,17 +387,17 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
const flatbuffers::Vector<flatbuffers::Offset<EnumVal>> *values() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<EnumVal>> *>(VT_VALUES);
const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES);
}
bool is_union() const {
return GetField<uint8_t>(VT_IS_UNION, 0) != 0;
}
const Type *underlying_type() const {
return GetPointer<const Type *>(VT_UNDERLYING_TYPE);
const reflection::Type *underlying_type() const {
return GetPointer<const reflection::Type *>(VT_UNDERLYING_TYPE);
}
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -394,21 +423,22 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct EnumBuilder {
typedef Enum Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(Enum::VT_NAME, name);
}
void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<EnumVal>>> values) {
void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values) {
fbb_.AddOffset(Enum::VT_VALUES, values);
}
void add_is_union(bool is_union) {
fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0);
}
void add_underlying_type(flatbuffers::Offset<Type> underlying_type) {
void add_underlying_type(flatbuffers::Offset<reflection::Type> underlying_type) {
fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type);
}
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -432,10 +462,10 @@ struct EnumBuilder {
inline flatbuffers::Offset<Enum> CreateEnum(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<EnumVal>>> values = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values = 0,
bool is_union = false,
flatbuffers::Offset<Type> underlying_type = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
flatbuffers::Offset<reflection::Type> underlying_type = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
EnumBuilder builder_(_fbb);
builder_.add_documentation(documentation);
@@ -450,14 +480,14 @@ inline flatbuffers::Offset<Enum> CreateEnum(
inline flatbuffers::Offset<Enum> CreateEnumDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
const std::vector<flatbuffers::Offset<EnumVal>> *values = nullptr,
std::vector<flatbuffers::Offset<reflection::EnumVal>> *values = nullptr,
bool is_union = false,
flatbuffers::Offset<Type> underlying_type = 0,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
flatbuffers::Offset<reflection::Type> underlying_type = 0,
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto values__ = values ? _fbb.CreateVector<flatbuffers::Offset<EnumVal>>(*values) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto values__ = values ? _fbb.CreateVectorOfSortedTables<reflection::EnumVal>(values) : 0;
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateEnum(
_fbb,
@@ -470,6 +500,7 @@ inline flatbuffers::Offset<Enum> CreateEnumDirect(
}
struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef FieldBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_TYPE = 6,
@@ -492,8 +523,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
const Type *type() const {
return GetPointer<const Type *>(VT_TYPE);
const reflection::Type *type() const {
return GetPointer<const reflection::Type *>(VT_TYPE);
}
uint16_t id() const {
return GetField<uint16_t>(VT_ID, 0);
@@ -516,8 +547,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
bool key() const {
return GetField<uint8_t>(VT_KEY, 0) != 0;
}
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -546,12 +577,13 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct FieldBuilder {
typedef Field Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(Field::VT_NAME, name);
}
void add_type(flatbuffers::Offset<Type> type) {
void add_type(flatbuffers::Offset<reflection::Type> type) {
fbb_.AddOffset(Field::VT_TYPE, type);
}
void add_id(uint16_t id) {
@@ -575,7 +607,7 @@ struct FieldBuilder {
void add_key(bool key) {
fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0);
}
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -598,7 +630,7 @@ struct FieldBuilder {
inline flatbuffers::Offset<Field> CreateField(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
flatbuffers::Offset<Type> type = 0,
flatbuffers::Offset<reflection::Type> type = 0,
uint16_t id = 0,
uint16_t offset = 0,
int64_t default_integer = 0,
@@ -606,7 +638,7 @@ inline flatbuffers::Offset<Field> CreateField(
bool deprecated = false,
bool required = false,
bool key = false,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
FieldBuilder builder_(_fbb);
builder_.add_default_real(default_real);
@@ -626,7 +658,7 @@ inline flatbuffers::Offset<Field> CreateField(
inline flatbuffers::Offset<Field> CreateFieldDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
flatbuffers::Offset<Type> type = 0,
flatbuffers::Offset<reflection::Type> type = 0,
uint16_t id = 0,
uint16_t offset = 0,
int64_t default_integer = 0,
@@ -634,10 +666,10 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
bool deprecated = false,
bool required = false,
bool key = false,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateField(
_fbb,
@@ -655,6 +687,7 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
}
struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef ObjectBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_FIELDS = 6,
@@ -673,8 +706,8 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
const flatbuffers::Vector<flatbuffers::Offset<Field>> *fields() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Field>> *>(VT_FIELDS);
const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS);
}
bool is_struct() const {
return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0;
@@ -685,8 +718,8 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int32_t bytesize() const {
return GetField<int32_t>(VT_BYTESIZE, 0);
}
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -712,12 +745,13 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct ObjectBuilder {
typedef Object Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(Object::VT_NAME, name);
}
void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Field>>> fields) {
void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields) {
fbb_.AddOffset(Object::VT_FIELDS, fields);
}
void add_is_struct(bool is_struct) {
@@ -729,7 +763,7 @@ struct ObjectBuilder {
void add_bytesize(int32_t bytesize) {
fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0);
}
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -752,11 +786,11 @@ struct ObjectBuilder {
inline flatbuffers::Offset<Object> CreateObject(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Field>>> fields = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields = 0,
bool is_struct = false,
int32_t minalign = 0,
int32_t bytesize = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
ObjectBuilder builder_(_fbb);
builder_.add_documentation(documentation);
@@ -772,15 +806,15 @@ inline flatbuffers::Offset<Object> CreateObject(
inline flatbuffers::Offset<Object> CreateObjectDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
const std::vector<flatbuffers::Offset<Field>> *fields = nullptr,
std::vector<flatbuffers::Offset<reflection::Field>> *fields = nullptr,
bool is_struct = false,
int32_t minalign = 0,
int32_t bytesize = 0,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto fields__ = fields ? _fbb.CreateVector<flatbuffers::Offset<Field>>(*fields) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto fields__ = fields ? _fbb.CreateVectorOfSortedTables<reflection::Field>(fields) : 0;
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateObject(
_fbb,
@@ -794,6 +828,7 @@ inline flatbuffers::Offset<Object> CreateObjectDirect(
}
struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef RPCCallBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_REQUEST = 6,
@@ -810,14 +845,14 @@ struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
const Object *request() const {
return GetPointer<const Object *>(VT_REQUEST);
const reflection::Object *request() const {
return GetPointer<const reflection::Object *>(VT_REQUEST);
}
const Object *response() const {
return GetPointer<const Object *>(VT_RESPONSE);
const reflection::Object *response() const {
return GetPointer<const reflection::Object *>(VT_RESPONSE);
}
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -841,18 +876,19 @@ struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct RPCCallBuilder {
typedef RPCCall Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(RPCCall::VT_NAME, name);
}
void add_request(flatbuffers::Offset<Object> request) {
void add_request(flatbuffers::Offset<reflection::Object> request) {
fbb_.AddOffset(RPCCall::VT_REQUEST, request);
}
void add_response(flatbuffers::Offset<Object> response) {
void add_response(flatbuffers::Offset<reflection::Object> response) {
fbb_.AddOffset(RPCCall::VT_RESPONSE, response);
}
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -876,9 +912,9 @@ struct RPCCallBuilder {
inline flatbuffers::Offset<RPCCall> CreateRPCCall(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
flatbuffers::Offset<Object> request = 0,
flatbuffers::Offset<Object> response = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
flatbuffers::Offset<reflection::Object> request = 0,
flatbuffers::Offset<reflection::Object> response = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
RPCCallBuilder builder_(_fbb);
builder_.add_documentation(documentation);
@@ -892,12 +928,12 @@ inline flatbuffers::Offset<RPCCall> CreateRPCCall(
inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
flatbuffers::Offset<Object> request = 0,
flatbuffers::Offset<Object> response = 0,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
flatbuffers::Offset<reflection::Object> request = 0,
flatbuffers::Offset<reflection::Object> response = 0,
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateRPCCall(
_fbb,
@@ -909,6 +945,7 @@ inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
}
struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef ServiceBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NAME = 4,
VT_CALLS = 6,
@@ -924,11 +961,11 @@ struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int KeyCompareWithValue(const char *val) const {
return strcmp(name()->c_str(), val);
}
const flatbuffers::Vector<flatbuffers::Offset<RPCCall>> *calls() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<RPCCall>> *>(VT_CALLS);
const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS);
}
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
}
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
@@ -951,15 +988,16 @@ struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct ServiceBuilder {
typedef Service Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
fbb_.AddOffset(Service::VT_NAME, name);
}
void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<RPCCall>>> calls) {
void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls) {
fbb_.AddOffset(Service::VT_CALLS, calls);
}
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes);
}
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
@@ -981,8 +1019,8 @@ struct ServiceBuilder {
inline flatbuffers::Offset<Service> CreateService(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::String> name = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<RPCCall>>> calls = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
ServiceBuilder builder_(_fbb);
builder_.add_documentation(documentation);
@@ -995,12 +1033,12 @@ inline flatbuffers::Offset<Service> CreateService(
inline flatbuffers::Offset<Service> CreateServiceDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const char *name = nullptr,
const std::vector<flatbuffers::Offset<RPCCall>> *calls = nullptr,
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
std::vector<flatbuffers::Offset<reflection::RPCCall>> *calls = nullptr,
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
auto name__ = name ? _fbb.CreateString(name) : 0;
auto calls__ = calls ? _fbb.CreateVector<flatbuffers::Offset<RPCCall>>(*calls) : 0;
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
auto calls__ = calls ? _fbb.CreateVectorOfSortedTables<reflection::RPCCall>(calls) : 0;
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
return reflection::CreateService(
_fbb,
@@ -1011,6 +1049,7 @@ inline flatbuffers::Offset<Service> CreateServiceDirect(
}
struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef SchemaBuilder Builder;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_OBJECTS = 4,
VT_ENUMS = 6,
@@ -1019,11 +1058,11 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_ROOT_TABLE = 12,
VT_SERVICES = 14
};
const flatbuffers::Vector<flatbuffers::Offset<Object>> *objects() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Object>> *>(VT_OBJECTS);
const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS);
}
const flatbuffers::Vector<flatbuffers::Offset<Enum>> *enums() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Enum>> *>(VT_ENUMS);
const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *enums() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *>(VT_ENUMS);
}
const flatbuffers::String *file_ident() const {
return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT);
@@ -1031,11 +1070,11 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const flatbuffers::String *file_ext() const {
return GetPointer<const flatbuffers::String *>(VT_FILE_EXT);
}
const Object *root_table() const {
return GetPointer<const Object *>(VT_ROOT_TABLE);
const reflection::Object *root_table() const {
return GetPointer<const reflection::Object *>(VT_ROOT_TABLE);
}
const flatbuffers::Vector<flatbuffers::Offset<Service>> *services() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Service>> *>(VT_SERVICES);
const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
@@ -1059,12 +1098,13 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
};
struct SchemaBuilder {
typedef Schema Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Object>>> objects) {
void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects) {
fbb_.AddOffset(Schema::VT_OBJECTS, objects);
}
void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Enum>>> enums) {
void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums) {
fbb_.AddOffset(Schema::VT_ENUMS, enums);
}
void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) {
@@ -1073,10 +1113,10 @@ struct SchemaBuilder {
void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) {
fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext);
}
void add_root_table(flatbuffers::Offset<Object> root_table) {
void add_root_table(flatbuffers::Offset<reflection::Object> root_table) {
fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table);
}
void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Service>>> services) {
void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) {
fbb_.AddOffset(Schema::VT_SERVICES, services);
}
explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
@@ -1095,12 +1135,12 @@ struct SchemaBuilder {
inline flatbuffers::Offset<Schema> CreateSchema(
flatbuffers::FlatBufferBuilder &_fbb,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Object>>> objects = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Enum>>> enums = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums = 0,
flatbuffers::Offset<flatbuffers::String> file_ident = 0,
flatbuffers::Offset<flatbuffers::String> file_ext = 0,
flatbuffers::Offset<Object> root_table = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Service>>> services = 0) {
flatbuffers::Offset<reflection::Object> root_table = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0) {
SchemaBuilder builder_(_fbb);
builder_.add_services(services);
builder_.add_root_table(root_table);
@@ -1113,17 +1153,17 @@ inline flatbuffers::Offset<Schema> CreateSchema(
inline flatbuffers::Offset<Schema> CreateSchemaDirect(
flatbuffers::FlatBufferBuilder &_fbb,
const std::vector<flatbuffers::Offset<Object>> *objects = nullptr,
const std::vector<flatbuffers::Offset<Enum>> *enums = nullptr,
std::vector<flatbuffers::Offset<reflection::Object>> *objects = nullptr,
std::vector<flatbuffers::Offset<reflection::Enum>> *enums = nullptr,
const char *file_ident = nullptr,
const char *file_ext = nullptr,
flatbuffers::Offset<Object> root_table = 0,
const std::vector<flatbuffers::Offset<Service>> *services = nullptr) {
auto objects__ = objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0;
auto enums__ = enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0;
flatbuffers::Offset<reflection::Object> root_table = 0,
std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr) {
auto objects__ = objects ? _fbb.CreateVectorOfSortedTables<reflection::Object>(objects) : 0;
auto enums__ = enums ? _fbb.CreateVectorOfSortedTables<reflection::Enum>(enums) : 0;
auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0;
auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0;
auto services__ = services ? _fbb.CreateVector<flatbuffers::Offset<Service>>(*services) : 0;
auto services__ = services ? _fbb.CreateVectorOfSortedTables<reflection::Service>(services) : 0;
return reflection::CreateSchema(
_fbb,
objects__,

View File

@@ -96,13 +96,13 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
}
};
template <> class numeric_limits<float> :
template <> class numeric_limits<float> :
public std::numeric_limits<float> {
public:
static float lowest() { return -FLT_MAX; }
};
template <> class numeric_limits<double> :
template <> class numeric_limits<double> :
public std::numeric_limits<double> {
public:
static double lowest() { return -DBL_MAX; }
@@ -138,7 +138,12 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <typename T, typename U> using is_same = std::is_same<T,U>;
template <typename T> using is_floating_point = std::is_floating_point<T>;
template <typename T> using is_unsigned = std::is_unsigned<T>;
template <typename T> using is_enum = std::is_enum<T>;
template <typename T> using make_unsigned = std::make_unsigned<T>;
template<bool B, class T, class F>
using conditional = std::conditional<B, T, F>;
template<class T, T v>
using integral_constant = std::integral_constant<T, v>;
#else
// Map C++ TR1 templates defined by stlport.
template <typename T> using is_scalar = std::tr1::is_scalar<T>;
@@ -146,6 +151,7 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <typename T> using is_floating_point =
std::tr1::is_floating_point<T>;
template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
template <typename T> using is_enum = std::tr1::is_enum<T>;
// Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned.
template<typename T> struct make_unsigned {
static_assert(is_unsigned<T>::value, "Specialization not implemented!");
@@ -157,6 +163,10 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template<> struct make_unsigned<long> { using type = unsigned long; };
template<>
struct make_unsigned<long long> { using type = unsigned long long; };
template<bool B, class T, class F>
using conditional = std::tr1::conditional<B, T, F>;
template<class T, T v>
using integral_constant = std::tr1::integral_constant<T, v>;
#endif // !FLATBUFFERS_CPP98_STL
#else
// MSVC 2010 doesn't support C++11 aliases.
@@ -165,7 +175,12 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <typename T> struct is_floating_point :
public std::is_floating_point<T> {};
template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
template <typename T> struct is_enum : public std::is_enum<T> {};
template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
template<bool B, class T, class F>
struct conditional : public std::conditional<B, T, F> {};
template<class T, T v>
struct integral_constant : public std::integral_constant<T, v> {};
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
#ifndef FLATBUFFERS_CPP98_STL
@@ -268,6 +283,23 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
return reinterpret_cast<intptr_t>(x.get()) == y;
}
template <class T> bool operator!=(const unique_ptr<T>& x, decltype(nullptr)) {
return !!x;
}
template <class T> bool operator!=(decltype(nullptr), const unique_ptr<T>& x) {
return !!x;
}
template <class T> bool operator==(const unique_ptr<T>& x, decltype(nullptr)) {
return !x;
}
template <class T> bool operator==(decltype(nullptr), const unique_ptr<T>& x) {
return !x;
}
#endif // !FLATBUFFERS_CPP98_STL
} // namespace flatbuffers

View File

@@ -17,10 +17,10 @@
#ifndef FLATBUFFERS_UTIL_H_
#define FLATBUFFERS_UTIL_H_
#include "flatbuffers/base.h"
#include <errno.h>
#include "flatbuffers/base.h"
#ifndef FLATBUFFERS_PREFER_PRINTF
# include <sstream>
#else // FLATBUFFERS_PREFER_PRINTF
@@ -102,7 +102,7 @@ std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) {
size_t string_width = NumToStringWidth(t, precision);
std::string s(string_width, 0x00);
// Allow snprintf to use std::string trailing null to detect buffer overflow
snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, precision, t);
snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, string_width, t);
return s;
}
#endif // FLATBUFFERS_PREFER_PRINTF
@@ -327,7 +327,7 @@ template<typename T> inline bool StringToNumber(const char *s, T *val) {
int64_t i64;
// The errno check isn't needed, will return MAX/MIN on overflow.
if (StringToIntegerImpl(&i64, s, 0, false)) {
const int64_t max = flatbuffers::numeric_limits<T>::max();
const int64_t max = (flatbuffers::numeric_limits<T>::max)();
const int64_t min = flatbuffers::numeric_limits<T>::lowest();
if (i64 > max) {
*val = static_cast<T>(max);
@@ -365,7 +365,7 @@ inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) {
if (*s == '-') {
// For unsigned types return the max to distinguish from
// "no conversion can be performed".
*val = flatbuffers::numeric_limits<uint64_t>::max();
*val = (flatbuffers::numeric_limits<uint64_t>::max)();
return false;
}
}
@@ -636,6 +636,32 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
return true;
}
inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
size_t max_length,
const std::string &wrapped_line_prefix,
const std::string &wrapped_line_suffix) {
std::string text = wrapped_line_prefix;
size_t start_offset = 0;
const char *s = reinterpret_cast<const char *>(buffer);
for (size_t i = 0; s && i < buffer_size; i++) {
// Last iteration or do we have more?
bool have_more = i + 1 < buffer_size;
text += "0x";
text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
if (have_more) { text += ','; }
// If we have more to process and we reached max_length
if (have_more &&
text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
text += wrapped_line_suffix;
text += '\n';
start_offset = text.size();
text += wrapped_line_prefix;
}
}
text += wrapped_line_suffix;
return text;
}
// Remove paired quotes in a string: "text"|'text' -> text.
std::string RemoveStringQuotes(const std::string &s);
@@ -649,6 +675,9 @@ bool SetGlobalTestLocale(const char *locale_name,
bool ReadEnvironmentVariable(const char *var_name,
std::string *_value = nullptr);
// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs.
void SetupDefaultCRTReportMode();
} // namespace flatbuffers
#endif // FLATBUFFERS_UTIL_H_

View File

@@ -0,0 +1,241 @@
package com.google.flatbuffers;
import java.util.Arrays;
/**
* Implements {@code ReadBuf} using an array of bytes
* as a backing storage. Using array of bytes are
* usually faster than {@code ByteBuffer}.
*
* This class is not thread-safe, meaning that
* it must operate on a single thread. Operating from
* multiple thread leads into a undefined behavior
*/
public class ArrayReadWriteBuf implements ReadWriteBuf {
private byte[] buffer;
private int writePos;
public ArrayReadWriteBuf() {
this(10);
}
public ArrayReadWriteBuf(int initialCapacity) {
this(new byte[initialCapacity]);
}
public ArrayReadWriteBuf(byte[] buffer) {
this.buffer = buffer;
this.writePos = 0;
}
public ArrayReadWriteBuf(byte[] buffer, int startPos) {
this.buffer = buffer;
this.writePos = startPos;
}
@Override
public boolean getBoolean(int index) {
return buffer[index] != 0;
}
@Override
public byte get(int index) {
return buffer[index];
}
@Override
public short getShort(int index) {
return (short) ((buffer[index+ 1] << 8) | (buffer[index] & 0xff));
}
@Override
public int getInt(int index) {
return (((buffer[index + 3]) << 24) |
((buffer[index + 2] & 0xff) << 16) |
((buffer[index + 1] & 0xff) << 8) |
((buffer[index] & 0xff)));
}
@Override
public long getLong(int index) {
return ((((long) buffer[index++] & 0xff)) |
(((long) buffer[index++] & 0xff) << 8) |
(((long) buffer[index++] & 0xff) << 16) |
(((long) buffer[index++] & 0xff) << 24) |
(((long) buffer[index++] & 0xff) << 32) |
(((long) buffer[index++] & 0xff) << 40) |
(((long) buffer[index++] & 0xff) << 48) |
(((long) buffer[index]) << 56));
}
@Override
public float getFloat(int index) {
return Float.intBitsToFloat(getInt(index));
}
@Override
public double getDouble(int index) {
return Double.longBitsToDouble(getLong(index));
}
@Override
public String getString(int start, int size) {
return Utf8Safe.decodeUtf8Array(buffer, start, size);
}
@Override
public byte[] data() {
return buffer;
}
@Override
public void putBoolean(boolean value) {
setBoolean(writePos, value);
writePos++;
}
@Override
public void put(byte[] value, int start, int length) {
set(writePos, value, start, length);
writePos+=length;
}
@Override
public void put(byte value) {
set(writePos, value);
writePos++;
}
@Override
public void putShort(short value) {
setShort(writePos, value);
writePos +=2;
}
@Override
public void putInt(int value) {
setInt(writePos, value);
writePos +=4;
}
@Override
public void putLong(long value) {
setLong(writePos, value);
writePos +=8;
}
@Override
public void putFloat(float value) {
setFloat(writePos, value);
writePos +=4;
}
@Override
public void putDouble(double value) {
setDouble(writePos, value);
writePos +=8;
}
@Override
public void setBoolean(int index, boolean value) {
set(index, value ? (byte)1 : (byte)0);
}
@Override
public void set(int index, byte value) {
requestCapacity(index + 1);
buffer[index] = value;
}
@Override
public void set(int index, byte[] toCopy, int start, int length) {
requestCapacity(index + (length - start));
System.arraycopy(toCopy, start, buffer, index, length);
}
@Override
public void setShort(int index, short value) {
requestCapacity(index + 2);
buffer[index++] = (byte) ((value) & 0xff);
buffer[index ] = (byte) ((value >> 8) & 0xff);
}
@Override
public void setInt(int index, int value) {
requestCapacity(index + 4);
buffer[index++] = (byte) ((value) & 0xff);
buffer[index++] = (byte) ((value >> 8) & 0xff);
buffer[index++] = (byte) ((value >> 16) & 0xff);
buffer[index ] = (byte) ((value >> 24) & 0xff);
}
@Override
public void setLong(int index, long value) {
requestCapacity(index + 8);
int i = (int) value;
buffer[index++] = (byte) ((i) & 0xff);
buffer[index++] = (byte) ((i >> 8) & 0xff);
buffer[index++] = (byte) ((i >> 16) & 0xff);
buffer[index++] = (byte) ((i >> 24) & 0xff);
i = (int) (value >> 32);
buffer[index++] = (byte) ((i) & 0xff);
buffer[index++] = (byte) ((i >> 8) & 0xff);
buffer[index++] = (byte) ((i >> 16) & 0xff);
buffer[index ] = (byte) ((i >> 24) & 0xff);
}
@Override
public void setFloat(int index, float value) {
requestCapacity(index + 4);
int iValue = Float.floatToRawIntBits(value);
buffer[index++] = (byte) ((iValue) & 0xff);
buffer[index++] = (byte) ((iValue >> 8) & 0xff);
buffer[index++] = (byte) ((iValue >> 16) & 0xff);
buffer[index ] = (byte) ((iValue >> 24) & 0xff);
}
@Override
public void setDouble(int index, double value) {
requestCapacity(index + 8);
long lValue = Double.doubleToRawLongBits(value);
int i = (int) lValue;
buffer[index++] = (byte) ((i) & 0xff);
buffer[index++] = (byte) ((i >> 8) & 0xff);
buffer[index++] = (byte) ((i >> 16) & 0xff);
buffer[index++] = (byte) ((i >> 24) & 0xff);
i = (int) (lValue >> 32);
buffer[index++] = (byte) ((i) & 0xff);
buffer[index++] = (byte) ((i >> 8) & 0xff);
buffer[index++] = (byte) ((i >> 16) & 0xff);
buffer[index ] = (byte) ((i >> 24) & 0xff);
}
@Override
public int limit() {
return writePos;
}
@Override
public int writePosition() {
return writePos;
}
@Override
public boolean requestCapacity(int capacity) {
if (buffer.length > capacity) {
return true;
}
// implemented in the same growing fashion as ArrayList
int oldCapacity = buffer.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
buffer = Arrays.copyOf(buffer, newCapacity);
return true;
}
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import java.nio.ByteBuffer;
/// @cond FLATBUFFERS_INTERNAL
/**
* All vector access objects derive from this class, and add their own accessors.
*/
public class BaseVector {
/** Used to hold the vector data position. */
private int vector;
/** Used to hold the vector size. */
private int length;
/** Used to hold the vector element size in table. */
private int element_size;
/** The underlying ByteBuffer to hold the data of the vector. */
protected ByteBuffer bb;
/**
* Get the start data of a vector.
*
* @return Returns the start of the vector data.
*/
protected int __vector() {
return vector;
}
/**
* Gets the element position in vector's ByteBuffer.
*
* @param j An `int` index of element into a vector.
* @return Returns the position of the vector element in a ByteBuffer.
*/
protected int __element(int j) {
return vector + j * element_size;
}
/**
* Re-init the internal state with an external buffer {@code ByteBuffer}, an offset within and
* element size.
*
* This method exists primarily to allow recycling vector instances without risking memory leaks
* due to {@code ByteBuffer} references.
*/
protected void __reset(int _vector, int _element_size, ByteBuffer _bb) {
bb = _bb;
if (bb != null) {
vector = _vector;
length = bb.getInt(_vector - Constants.SIZEOF_INT);
element_size = _element_size;
} else {
vector = 0;
length = 0;
element_size = 0;
}
}
/**
* Resets the internal state with a null {@code ByteBuffer} and a zero position.
*
* This method exists primarily to allow recycling vector instances without risking memory leaks
* due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
* again to a {@code ByteBuffer}.
*/
public void reset() {
__reset(0, 0, null);
}
/**
* Get the length of a vector.
*
* @return Returns the length of the vector.
*/
public int length() {
return length;
}
}
/// @endcond

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of booleans.
*/
public final class BooleanVector extends BaseVector {
/**
* Assigns vector access object to vector data.
*
* @param _vector Start data of a vector.
* @param _bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public BooleanVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_BYTE, _bb); return this;
}
/**
* Reads the boolean at the given index.
*
* @param j The index from which the boolean will be read.
* @return the boolean value at the given index.
*/
public boolean get(int j) {
return 0 != bb.get(__element(j));
}
}

View File

@@ -0,0 +1,165 @@
package com.google.flatbuffers;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class ByteBufferReadWriteBuf implements ReadWriteBuf {
private final ByteBuffer buffer;
public ByteBufferReadWriteBuf(ByteBuffer bb) {
this.buffer = bb;
this.buffer.order(ByteOrder.LITTLE_ENDIAN);
}
@Override
public boolean getBoolean(int index) {
return get(index) != 0;
}
@Override
public byte get(int index) {
return buffer.get(index);
}
@Override
public short getShort(int index) {
return buffer.getShort(index);
}
@Override
public int getInt(int index) {
return buffer.getInt(index);
}
@Override
public long getLong(int index) {
return buffer.getLong(index);
}
@Override
public float getFloat(int index) {
return buffer.getFloat(index);
}
@Override
public double getDouble(int index) {
return buffer.getDouble(index);
}
@Override
public String getString(int start, int size) {
return Utf8Safe.decodeUtf8Buffer(buffer, start, size);
}
@Override
public byte[] data() {
return buffer.array();
}
@Override
public void putBoolean(boolean value) {
buffer.put(value ? (byte)1 : (byte)0);
}
@Override
public void put(byte[] value, int start, int length) {
buffer.put(value, start, length);
}
@Override
public void put(byte value) {
buffer.put(value);
}
@Override
public void putShort(short value) {
buffer.putShort(value);
}
@Override
public void putInt(int value) {
buffer.putInt(value);
}
@Override
public void putLong(long value) {
buffer.putLong(value);
}
@Override
public void putFloat(float value) {
buffer.putFloat(value);
}
@Override
public void putDouble(double value) {
buffer.putDouble(value);
}
@Override
public void setBoolean(int index, boolean value) {
set(index, value ? (byte)1 : (byte)0);
}
@Override
public void set(int index, byte value) {
requestCapacity(index + 1);
buffer.put(index, value);
}
@Override
public void set(int index, byte[] value, int start, int length) {
requestCapacity(index + (length - start));
int curPos = buffer.position();
buffer.position(index);
buffer.put(value, start, length);
buffer.position(curPos);
}
@Override
public void setShort(int index, short value) {
requestCapacity(index + 2);
buffer.putShort(index, value);
}
@Override
public void setInt(int index, int value) {
requestCapacity(index + 4);
buffer.putInt(index, value);
}
@Override
public void setLong(int index, long value) {
requestCapacity(index + 8);
buffer.putLong(index, value);
}
@Override
public void setFloat(int index, float value) {
requestCapacity(index + 4);
buffer.putFloat(index, value);
}
@Override
public void setDouble(int index, double value) {
requestCapacity(index + 8);
buffer.putDouble(index, value);
}
@Override
public int writePosition() {
return buffer.position();
}
@Override
public int limit() {
return buffer.limit();
}
@Override
public boolean requestCapacity(int capacity) {
return capacity <= buffer.limit();
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of signed or unsigned 8-bit values.
*/
public final class ByteVector extends BaseVector {
/**
* Assigns vector access object to vector data.
*
* @param vector Start data of a vector.
* @param bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public ByteVector __assign(int vector, ByteBuffer bb) {
__reset(vector, Constants.SIZEOF_BYTE, bb); return this;
}
/**
* Reads the byte at the given index.
*
* @param j The index from which the byte will be read.
* @return the 8-bit value at the given index.
*/
public byte get(int j) {
return bb.get(__element(j));
}
/**
* Reads the byte at the given index, zero-extends it to type int, and returns the result,
* which is therefore in the range 0 through 255.
*
* @param j The index from which the byte will be read.
* @return the unsigned 8-bit at the given index.
*/
public int getAsUnsigned(int j) {
return (int) get(j) & 0xFF;
}
}

View File

@@ -39,6 +39,14 @@ public class Constants {
static final int FILE_IDENTIFIER_LENGTH = 4;
/** The number of bytes in a size prefix. */
public static final int SIZE_PREFIX_LENGTH = 4;
/** A version identifier to force a compile error if someone
accidentally tries to build generated code with a runtime of
two mismatched version. Versions need to always match, as
the runtime and generated code are modified in sync.
Changes to the Java implementation need to be sure to change
the version here and in the code generator on every possible
incompatible change */
public static void FLATBUFFERS_1_12_0() {}
}
/// @endcond

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of double values.
*/
public final class DoubleVector extends BaseVector {
/**
* Assigns vector access object to vector data.
*
* @param _vector Start data of a vector.
* @param _bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public DoubleVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_DOUBLE, _bb); return this;
}
/**
* Reads the double value at the given index.
*
* @param j The index from which the double value will be read.
* @return the double value at the given index.
*/
public double get(int j) {
return bb.getDouble(__element(j));
}
}

View File

@@ -72,7 +72,6 @@ public class FlatBufferBuilder {
if (initial_size <= 0) {
initial_size = 1;
}
space = initial_size;
this.bb_factory = bb_factory;
if (existing_bb != null) {
bb = existing_bb;
@@ -82,6 +81,7 @@ public class FlatBufferBuilder {
bb = bb_factory.newByteBuffer(initial_size);
}
this.utf8 = utf8;
space = bb.capacity();
}
/**
@@ -199,6 +199,17 @@ public class FlatBufferBuilder {
}
}
/**
* Helper function to test if a field is present in the table
*
* @param table Flatbuffer table
* @param offset virtual table offset
* @return true if the filed is present
*/
public static boolean isFieldPresent(Table table, int offset) {
return table.__offset(offset) != 0;
}
/**
* Reset the FlatBufferBuilder by purging all data that it holds.
*/
@@ -231,6 +242,7 @@ public class FlatBufferBuilder {
int new_buf_size = old_buf_size == 0 ? 1 : old_buf_size << 1;
bb.position(0);
ByteBuffer nbb = bb_factory.newByteBuffer(new_buf_size);
new_buf_size = nbb.clear().capacity(); // Ensure the returned buffer is treated as empty
nbb.position(new_buf_size - old_buf_size);
nbb.put(bb);
return nbb;
@@ -560,6 +572,38 @@ public class FlatBufferBuilder {
return endVector();
}
/**
* Create a byte array in the buffer.
*
* @param arr a source array with data.
* @param offset the offset in the source array to start copying from.
* @param length the number of bytes to copy from the source array.
* @return The offset in the buffer where the encoded array starts.
*/
public int createByteVector(byte[] arr, int offset, int length) {
startVector(1, length, 1);
bb.position(space -= length);
bb.put(arr, offset, length);
return endVector();
}
/**
* Create a byte array in the buffer.
*
* The source {@link ByteBuffer} position is advanced by {@link ByteBuffer#remaining()} places
* after this call.
*
* @param byteBuffer A source {@link ByteBuffer} with data.
* @return The offset in the buffer where the encoded array starts.
*/
public int createByteVector(ByteBuffer byteBuffer) {
int length = byteBuffer.remaining();
startVector(1, length, 1);
bb.position(space -= length);
bb.put(byteBuffer);
return endVector();
}
/// @cond FLATBUFFERS_INTERNAL
/**
* Should not be accessing the final buffer before it is finished.
@@ -632,7 +676,7 @@ public class FlatBufferBuilder {
*
* @param numfields The number of fields found in this object.
*/
public void startObject(int numfields) {
public void startTable(int numfields) {
notNested();
if (vtable == null || vtable.length < numfields) vtable = new int[numfields];
vtable_in_use = numfields;
@@ -757,11 +801,11 @@ public class FlatBufferBuilder {
* Finish off writing the object that is under construction.
*
* @return The offset to the object inside {@link #dataBuffer()}.
* @see #startObject(int)
* @see #startTable(int)
*/
public int endObject() {
public int endTable() {
if (vtable == null || !nested)
throw new AssertionError("FlatBuffers: endObject called without startObject");
throw new AssertionError("FlatBuffers: endTable called without startTable");
addInt(0);
int vtableloc = offset();
// Write out the current vtable.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,770 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import static com.google.flatbuffers.FlexBuffers.*;
import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
/// @file
/// @addtogroup flatbuffers_java_api
/// @{
/**
* Helper class that builds FlexBuffers
* <p> This class presents all necessary APIs to create FlexBuffers. A `ByteBuffer` will be used to store the
* data. It can be created internally, or passed down in the constructor.</p>
*
* <p>There are some limitations when compared to original implementation in C++. Most notably:
* <ul>
* <li><p> No support for mutations (might change in the future).</p></li>
* <li><p> Buffer size limited to {@link Integer#MAX_VALUE}</p></li>
* <li><p> Since Java does not support unsigned type, all unsigned operations accepts an immediate higher representation
* of similar type.</p></li>
* </ul>
* </p>
*/
public class FlexBuffersBuilder {
/**
* No keys or strings will be shared
*/
public static final int BUILDER_FLAG_NONE = 0;
/**
* Keys will be shared between elements. Identical keys will only be serialized once, thus possibly saving space.
* But serialization performance might be slower and consumes more memory.
*/
public static final int BUILDER_FLAG_SHARE_KEYS = 1;
/**
* Strings will be shared between elements. Identical strings will only be serialized once, thus possibly saving space.
* But serialization performance might be slower and consumes more memory. This is ideal if you expect many repeated
* strings on the message.
*/
public static final int BUILDER_FLAG_SHARE_STRINGS = 2;
/**
* Strings and keys will be shared between elements.
*/
public static final int BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3;
/**
* Reserved for the future.
*/
public static final int BUILDER_FLAG_SHARE_KEY_VECTORS = 4;
/**
* Reserved for the future.
*/
public static final int BUILDER_FLAG_SHARE_ALL = 7;
/// @cond FLATBUFFERS_INTERNAL
private static final int WIDTH_8 = 0;
private static final int WIDTH_16 = 1;
private static final int WIDTH_32 = 2;
private static final int WIDTH_64 = 3;
private final ReadWriteBuf bb;
private final ArrayList<Value> stack = new ArrayList<>();
private final HashMap<String, Integer> keyPool = new HashMap<>();
private final HashMap<String, Integer> stringPool = new HashMap<>();
private final int flags;
private boolean finished = false;
// A lambda to sort map keys
private Comparator<Value> keyComparator = new Comparator<Value>() {
@Override
public int compare(Value o1, Value o2) {
int ia = o1.key;
int io = o2.key;
byte c1, c2;
do {
c1 = bb.get(ia);
c2 = bb.get(io);
if (c1 == 0)
return c1 - c2;
ia++;
io++;
}
while (c1 == c2);
return c1 - c2;
}
};
/// @endcond
/**
* Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set.
* @param bufSize size of buffer in bytes.
*/
public FlexBuffersBuilder(int bufSize) {
this(new ArrayReadWriteBuf(bufSize), BUILDER_FLAG_SHARE_KEYS);
}
/**
* Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set.
*/
public FlexBuffersBuilder() {
this(256);
}
/**
* Constructs a newly allocated {@code FlexBuffersBuilder}.
*
* @param bb `ByteBuffer` that will hold the message
* @param flags Share flags
*/
@Deprecated
public FlexBuffersBuilder(ByteBuffer bb, int flags) {
this(new ArrayReadWriteBuf(bb.array()), flags);
}
public FlexBuffersBuilder(ReadWriteBuf bb, int flags) {
this.bb = bb;
this.flags = flags;
}
/**
* Constructs a newly allocated {@code FlexBuffersBuilder}.
* By default same keys will be serialized only once
* @param bb `ByteBuffer` that will hold the message
*/
public FlexBuffersBuilder(ByteBuffer bb) {
this(bb, BUILDER_FLAG_SHARE_KEYS);
}
/**
* Return `ByteBuffer` containing FlexBuffer message. {@code #finish()} must be called before calling this
* function otherwise an assert will trigger.
*
* @return `ByteBuffer` with finished message
*/
public ReadWriteBuf getBuffer() {
assert (finished);
return bb;
}
/**
* Insert a single boolean into the buffer
* @param val true or false
*/
public void putBoolean(boolean val) {
putBoolean(null, val);
}
/**
* Insert a single boolean into the buffer
* @param key key used to store element in map
* @param val true or false
*/
public void putBoolean(String key, boolean val) {
stack.add(Value.bool(putKey(key), val));
}
private int putKey(String key) {
if (key == null) {
return -1;
}
int pos = bb.writePosition();
if ((flags & BUILDER_FLAG_SHARE_KEYS) != 0) {
Integer keyFromPool = keyPool.get(key);
if (keyFromPool == null) {
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
bb.put(keyBytes, 0, keyBytes.length);
bb.put((byte) 0);
keyPool.put(key, pos);
} else {
pos = keyFromPool;
}
} else {
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
bb.put(keyBytes, 0, keyBytes.length);
bb.put((byte) 0);
keyPool.put(key, pos);
}
return pos;
}
/**
* Adds a integer into the buff
* @param val integer
*/
public void putInt(int val) {
putInt(null, val);
}
/**
* Adds a integer into the buff
* @param key key used to store element in map
* @param val integer
*/
public void putInt(String key, int val) {
putInt(key, (long) val);
}
/**
* Adds a integer into the buff
* @param key key used to store element in map
* @param val 64-bit integer
*/
public void putInt(String key, long val) {
int iKey = putKey(key);
if (Byte.MIN_VALUE <= val && val <= Byte.MAX_VALUE) {
stack.add(Value.int8(iKey, (int) val));
} else if (Short.MIN_VALUE <= val && val <= Short.MAX_VALUE) {
stack.add(Value.int16(iKey, (int) val));
} else if (Integer.MIN_VALUE <= val && val <= Integer.MAX_VALUE) {
stack.add(Value.int32(iKey, (int) val));
} else {
stack.add(Value.int64(iKey, val));
}
}
/**
* Adds a 64-bit integer into the buff
* @param value integer
*/
public void putInt(long value) {
putInt(null, value);
}
/**
* Adds a unsigned integer into the buff.
* @param value integer representing unsigned value
*/
public void putUInt(int value) {
putUInt(null, (long) value);
}
/**
* Adds a unsigned integer (stored in a signed 64-bit integer) into the buff.
* @param value integer representing unsigned value
*/
public void putUInt(long value) {
putUInt(null, value);
}
/**
* Adds a 64-bit unsigned integer (stored as {@link BigInteger}) into the buff.
* Warning: This operation might be very slow.
* @param value integer representing unsigned value
*/
public void putUInt64(BigInteger value) {
putUInt64(null, value.longValue());
}
private void putUInt64(String key, long value) {
stack.add(Value.uInt64(putKey(key), value));
}
private void putUInt(String key, long value) {
int iKey = putKey(key);
Value vVal;
int width = widthUInBits(value);
if (width == WIDTH_8) {
vVal = Value.uInt8(iKey, (int)value);
} else if (width == WIDTH_16) {
vVal = Value.uInt16(iKey, (int)value);
} else if (width == WIDTH_32) {
vVal = Value.uInt32(iKey, (int)value);
} else {
vVal = Value.uInt64(iKey, value);
}
stack.add(vVal);
}
/**
* Adds a 32-bit float into the buff.
* @param value float representing value
*/
public void putFloat(float value) {
putFloat(null, value);
}
/**
* Adds a 32-bit float into the buff.
* @param key key used to store element in map
* @param value float representing value
*/
public void putFloat(String key, float val) {
stack.add(Value.float32(putKey(key), val));
}
/**
* Adds a 64-bit float into the buff.
* @param value float representing value
*/
public void putFloat(double value) {
putFloat(null, value);
}
/**
* Adds a 64-bit float into the buff.
* @param key key used to store element in map
* @param value float representing value
*/
public void putFloat(String key, double val) {
stack.add(Value.float64(putKey(key), val));
}
/**
* Adds a String into the buffer
* @param value string
* @return start position of string in the buffer
*/
public int putString(String value) {
return putString(null, value);
}
/**
* Adds a String into the buffer
* @param key key used to store element in map
* @param value string
* @return start position of string in the buffer
*/
public int putString(String key, String val) {
int iKey = putKey(key);
if ((flags & FlexBuffersBuilder.BUILDER_FLAG_SHARE_STRINGS) != 0) {
Integer i = stringPool.get(val);
if (i == null) {
Value value = writeString(iKey, val);
stringPool.put(val, (int) value.iValue);
stack.add(value);
return (int) value.iValue;
} else {
int bitWidth = widthUInBits(val.length());
stack.add(Value.blob(iKey, i, FBT_STRING, bitWidth));
return i;
}
} else {
Value value = writeString(iKey, val);
stack.add(value);
return (int) value.iValue;
}
}
private Value writeString(int key, String s) {
return writeBlob(key, s.getBytes(StandardCharsets.UTF_8), FBT_STRING, true);
}
// in bits to fit a unsigned int
static int widthUInBits(long len) {
if (len <= byteToUnsignedInt((byte)0xff)) return WIDTH_8;
if (len <= shortToUnsignedInt((short)0xffff)) return WIDTH_16;
if (len <= intToUnsignedLong(0xffff_ffff)) return WIDTH_32;
return WIDTH_64;
}
private Value writeBlob(int key, byte[] blob, int type, boolean trailing) {
int bitWidth = widthUInBits(blob.length);
int byteWidth = align(bitWidth);
writeInt(blob.length, byteWidth);
int sloc = bb.writePosition();
bb.put(blob, 0, blob.length);
if (trailing) {
bb.put((byte) 0);
}
return Value.blob(key, sloc, type, bitWidth);
}
// Align to prepare for writing a scalar with a certain size.
private int align(int alignment) {
int byteWidth = 1 << alignment;
int padBytes = Value.paddingBytes(bb.writePosition(), byteWidth);
while (padBytes-- != 0) {
bb.put((byte) 0);
}
return byteWidth;
}
private void writeInt(long value, int byteWidth) {
switch (byteWidth) {
case 1: bb.put((byte) value); break;
case 2: bb.putShort((short) value); break;
case 4: bb.putInt((int) value); break;
case 8: bb.putLong(value); break;
}
}
/**
* Adds a byte array into the message
* @param value byte array
* @return position in buffer as the start of byte array
*/
public int putBlob(byte[] value) {
return putBlob(null, value);
}
/**
* Adds a byte array into the message
* @param key key used to store element in map
* @param value byte array
* @return position in buffer as the start of byte array
*/
public int putBlob(String key, byte[] val) {
int iKey = putKey(key);
Value value = writeBlob(iKey, val, FBT_BLOB, false);
stack.add(value);
return (int) value.iValue;
}
/**
* Start a new vector in the buffer.
* @return a reference indicating position of the vector in buffer. This
* reference must be passed along when the vector is finished using endVector()
*/
public int startVector() {
return stack.size();
}
/**
* Finishes a vector, but writing the information in the buffer
* @param key key used to store element in map
* @param start reference for begining of the vector. Returned by {@link startVector()}
* @param typed boolean indicating wether vector is typed
* @param fixed boolean indicating wether vector is fixed
* @return Reference to the vector
*/
public int endVector(String key, int start, boolean typed, boolean fixed) {
int iKey = putKey(key);
Value vec = createVector(iKey, start, stack.size() - start, typed, fixed, null);
// Remove temp elements and return vector.
while (stack.size() > start) {
stack.remove(stack.size() - 1);
}
stack.add(vec);
return (int) vec.iValue;
}
/**
* Finish writing the message into the buffer. After that no other element must
* be inserted into the buffer. Also, you must call this function before start using the
* FlexBuffer message
* @return `ByteBuffer` containing the FlexBuffer message
*/
public ByteBuffer finish() {
// If you hit this assert, you likely have objects that were never included
// in a parent. You need to have exactly one root to finish a buffer.
// Check your Start/End calls are matched, and all objects are inside
// some other object.
assert (stack.size() == 1);
// Write root value.
int byteWidth = align(stack.get(0).elemWidth(bb.writePosition(), 0));
writeAny(stack.get(0), byteWidth);
// Write root type.
bb.put(stack.get(0).storedPackedType());
// Write root size. Normally determined by parent, but root has no parent :)
bb.put((byte) byteWidth);
this.finished = true;
return ByteBuffer.wrap(bb.data(), 0, bb.writePosition());
}
/*
* Create a vector based on the elements stored in the stack
*
* @param key reference to its key
* @param start element in the stack
* @param length size of the vector
* @param typed whether is TypedVector or not
* @param fixed whether is Fixed vector or not
* @param keys Value representing key vector
* @return Value representing the created vector
*/
private Value createVector(int key, int start, int length, boolean typed, boolean fixed, Value keys) {
assert (!fixed || typed); // typed=false, fixed=true combination is not supported.
// Figure out smallest bit width we can store this vector with.
int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
int prefixElems = 1;
if (keys != null) {
// If this vector is part of a map, we will pre-fix an offset to the keys
// to this vector.
bitWidth = Math.max(bitWidth, keys.elemWidth(bb.writePosition(), 0));
prefixElems += 2;
}
int vectorType = FBT_KEY;
// Check bit widths and types for all elements.
for (int i = start; i < stack.size(); i++) {
int elemWidth = stack.get(i).elemWidth(bb.writePosition(), i + prefixElems);
bitWidth = Math.max(bitWidth, elemWidth);
if (typed) {
if (i == start) {
vectorType = stack.get(i).type;
if (!FlexBuffers.isTypedVectorElementType(vectorType)) {
throw new FlexBufferException("TypedVector does not support this element type");
}
} else {
// If you get this assert, you are writing a typed vector with
// elements that are not all the same type.
assert (vectorType == stack.get(i).type);
}
}
}
// If you get this assert, your fixed types are not one of:
// Int / UInt / Float / Key.
assert (!fixed || FlexBuffers.isTypedVectorElementType(vectorType));
int byteWidth = align(bitWidth);
// Write vector. First the keys width/offset if available, and size.
if (keys != null) {
writeOffset(keys.iValue, byteWidth);
writeInt(1L << keys.minBitWidth, byteWidth);
}
if (!fixed) {
writeInt(length, byteWidth);
}
// Then the actual data.
int vloc = bb.writePosition();
for (int i = start; i < stack.size(); i++) {
writeAny(stack.get(i), byteWidth);
}
// Then the types.
if (!typed) {
for (int i = start; i < stack.size(); i++) {
bb.put(stack.get(i).storedPackedType(bitWidth));
}
}
return new Value(key, keys != null ? FBT_MAP
: (typed ? FlexBuffers.toTypedVector(vectorType, fixed ? length : 0)
: FBT_VECTOR), bitWidth, vloc);
}
private void writeOffset(long val, int byteWidth) {
int reloff = (int) (bb.writePosition() - val);
assert (byteWidth == 8 || reloff < 1L << (byteWidth * 8));
writeInt(reloff, byteWidth);
}
private void writeAny(final Value val, int byteWidth) {
switch (val.type) {
case FBT_NULL:
case FBT_BOOL:
case FBT_INT:
case FBT_UINT:
writeInt(val.iValue, byteWidth);
break;
case FBT_FLOAT:
writeDouble(val.dValue, byteWidth);
break;
default:
writeOffset(val.iValue, byteWidth);
break;
}
}
private void writeDouble(double val, int byteWidth) {
if (byteWidth == 4) {
bb.putFloat((float) val);
} else if (byteWidth == 8) {
bb.putDouble(val);
}
}
/**
* Start a new map in the buffer.
* @return a reference indicating position of the map in buffer. This
* reference must be passed along when the map is finished using endMap()
*/
public int startMap() {
return stack.size();
}
/**
* Finishes a map, but writing the information in the buffer
* @param key key used to store element in map
* @param start reference for begining of the map. Returned by {@link startMap()}
* @return Reference to the map
*/
public int endMap(String key, int start) {
int iKey = putKey(key);
Collections.sort(stack.subList(start, stack.size()), keyComparator);
Value keys = createKeyVector(start, stack.size() - start);
Value vec = createVector(iKey, start, stack.size() - start, false, false, keys);
// Remove temp elements and return map.
while (stack.size() > start) {
stack.remove(stack.size() - 1);
}
stack.add(vec);
return (int) vec.iValue;
}
private Value createKeyVector(int start, int length) {
// Figure out smallest bit width we can store this vector with.
int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
int prefixElems = 1;
// Check bit widths and types for all elements.
for (int i = start; i < stack.size(); i++) {
int elemWidth = Value.elemWidth(FBT_KEY, WIDTH_8, stack.get(i).key, bb.writePosition(), i + prefixElems);
bitWidth = Math.max(bitWidth, elemWidth);
}
int byteWidth = align(bitWidth);
// Write vector. First the keys width/offset if available, and size.
writeInt(length, byteWidth);
// Then the actual data.
int vloc = bb.writePosition();
for (int i = start; i < stack.size(); i++) {
int pos = stack.get(i).key;
assert(pos != -1);
writeOffset(stack.get(i).key, byteWidth);
}
// Then the types.
return new Value(-1, FlexBuffers.toTypedVector(FBT_KEY,0), bitWidth, vloc);
}
private static class Value {
final int type;
// for scalars, represents scalar size in bytes
// for vectors, represents the size
// for string, length
final int minBitWidth;
// float value
final double dValue;
// integer value
long iValue;
// position of the key associated with this value in buffer
int key;
Value(int key, int type, int bitWidth, long iValue) {
this.key = key;
this.type = type;
this.minBitWidth = bitWidth;
this.iValue = iValue;
this.dValue = Double.MIN_VALUE;
}
Value(int key, int type, int bitWidth, double dValue) {
this.key = key;
this.type = type;
this.minBitWidth = bitWidth;
this.dValue = dValue;
this.iValue = Long.MIN_VALUE;
}
static Value bool(int key, boolean b) {
return new Value(key, FBT_BOOL, WIDTH_8, b ? 1 : 0);
}
static Value blob(int key, int position, int type, int bitWidth) {
return new Value(key, type, bitWidth, position);
}
static Value int8(int key, int value) {
return new Value(key, FBT_INT, WIDTH_8, value);
}
static Value int16(int key, int value) {
return new Value(key, FBT_INT, WIDTH_16, value);
}
static Value int32(int key, int value) {
return new Value(key, FBT_INT, WIDTH_32, value);
}
static Value int64(int key, long value) {
return new Value(key, FBT_INT, WIDTH_64, value);
}
static Value uInt8(int key, int value) {
return new Value(key, FBT_UINT, WIDTH_8, value);
}
static Value uInt16(int key, int value) {
return new Value(key, FBT_UINT, WIDTH_16, value);
}
static Value uInt32(int key, int value) {
return new Value(key, FBT_UINT, WIDTH_32, value);
}
static Value uInt64(int key, long value) {
return new Value(key, FBT_UINT, WIDTH_64, value);
}
static Value float32(int key, float value) {
return new Value(key, FBT_FLOAT, WIDTH_32, value);
}
static Value float64(int key, double value) {
return new Value(key, FBT_FLOAT, WIDTH_64, value);
}
private byte storedPackedType() {
return storedPackedType(WIDTH_8);
}
private byte storedPackedType(int parentBitWidth) {
return packedType(storedWidth(parentBitWidth), type);
}
private static byte packedType(int bitWidth, int type) {
return (byte) (bitWidth | (type << 2));
}
private int storedWidth(int parentBitWidth) {
if (FlexBuffers.isTypeInline(type)) {
return Math.max(minBitWidth, parentBitWidth);
} else {
return minBitWidth;
}
}
private int elemWidth(int bufSize, int elemIndex) {
return elemWidth(type, minBitWidth, iValue, bufSize, elemIndex);
}
private static int elemWidth(int type, int minBitWidth, long iValue, int bufSize, int elemIndex) {
if (FlexBuffers.isTypeInline(type)) {
return minBitWidth;
} else {
// We have an absolute offset, but want to store a relative offset
// elem_index elements beyond the current buffer end. Since whether
// the relative offset fits in a certain byte_width depends on
// the size of the elements before it (and their alignment), we have
// to test for each size in turn.
// Original implementation checks for largest scalar
// which is long unsigned int
for (int byteWidth = 1; byteWidth <= 32; byteWidth *= 2) {
// Where are we going to write this offset?
int offsetLoc = bufSize + paddingBytes(bufSize, byteWidth) + (elemIndex * byteWidth);
// Compute relative offset.
long offset = offsetLoc - iValue;
// Does it fit?
int bitWidth = widthUInBits((int) offset);
if (((1L) << bitWidth) == byteWidth)
return bitWidth;
}
assert (false); // Must match one of the sizes above.
return WIDTH_64;
}
}
private static int paddingBytes(int bufSize, int scalarSize) {
return ((~bufSize) + 1) & (scalarSize - 1);
}
}
}
/// @}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of float values.
*/
public final class FloatVector extends BaseVector {
/**
* Assigns vector access object to vector data.
*
* @param _vector Start data of a vector.
* @param _bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public FloatVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_FLOAT, _bb); return this;
}
/**
* Reads the float value at the given index.
*
* @param j The index from which the float value will be read.
* @return the float value at the given index.
*/
public float get(int j) {
return bb.getFloat(__element(j));
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of signed or unsigned 32-bit values.
*/
public final class IntVector extends BaseVector {
/**
* Assigns vector access object to vector data.
*
* @param _vector Start data of a vector.
* @param _bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public IntVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_INT, _bb); return this;
}
/**
* Reads the integer at the given index.
*
* @param j The index from which the integer will be read.
* @return the 32-bit value at the given index.
*/
public int get(int j) {
return bb.getInt(__element(j));
}
/**
* Reads the integer at the given index, zero-extends it to type long, and returns the result,
* which is therefore in the range 0 through 4294967295.
*
* @param j The index from which the integer will be read.
* @return the unsigned 32-bit at the given index.
*/
public long getAsUnsigned(int j) {
return (long) get(j) & 0xFFFFFFFFL;
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of long values.
*/
public final class LongVector extends BaseVector {
/**
* Assigns vector access object to vector data.
*
* @param _vector Start data of a vector.
* @param _bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public LongVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_LONG, _bb); return this;
}
/**
* Reads the long value at the given index.
*
* @param j The index from which the long value will be read.
* @return the signed 64-bit value at the given index.
*/
public long get(int j) {
return bb.getLong(__element(j));
}
}

View File

@@ -0,0 +1,81 @@
package com.google.flatbuffers;
/**
* Represent a chunk of data, where FlexBuffers will read from.
*/
interface ReadBuf {
/**
* Read boolean from data. Booleans as stored as single byte
* @param index position of the element in ReadBuf
* @return boolean element
*/
boolean getBoolean(int index);
/**
* Read a byte from data.
* @param index position of the element in ReadBuf
* @return a byte
*/
byte get(int index);
/**
* Read a short from data.
* @param index position of the element in ReadBuf
* @return a short
*/
short getShort(int index);
/**
* Read a 32-bit int from data.
* @param index position of the element in ReadBuf
* @return an int
*/
int getInt(int index);
/**
* Read a 64-bit long from data.
* @param index position of the element in ReadBuf
* @return a long
*/
long getLong(int index);
/**
* Read a 32-bit float from data.
* @param index position of the element in ReadBuf
* @return a float
*/
float getFloat(int index);
/**
* Read a 64-bit float from data.
* @param index position of the element in ReadBuf
* @return a double
*/
double getDouble(int index);
/**
* Read an UTF-8 string from data.
* @param start initial element of the string
* @param size size of the string in bytes.
* @return a {@code String}
*/
String getString(int start, int size);
/**
* Expose ReadBuf as an array of bytes.
* This method is meant to be as efficient as possible, so for a array-backed ReadBuf, it should
* return its own internal data. In case access to internal data is not possible,
* a copy of the data into an array of bytes might occur.
* @return ReadBuf as an array of bytes
*/
byte[] data();
/**
* Defines the size of the message in the buffer. It also determines last position that buffer
* can be read. Last byte to be accessed is in position {@code limit() -1}.
* @return indicate last position
*/
int limit();
}

View File

@@ -0,0 +1,135 @@
package com.google.flatbuffers;
/**
* Interface to represent a read-write buffer. This interface will be used to access and write
* FlexBuffers message.
*/
interface ReadWriteBuf extends ReadBuf {
/**
* Put a boolean into the buffer at {@code writePosition()} . Booleans as stored as single
* byte. Write position will be incremented.
* @return boolean element
*/
void putBoolean(boolean value);
/**
* Put an array of bytes into the buffer at {@code writePosition()}. Write position will be
* incremented.
* @param value the data to be copied
* @param start initial position on value to be copied
* @param length amount of bytes to be copied
*/
void put (byte[] value, int start, int length);
/**
* Write a byte into the buffer at {@code writePosition()}. Write position will be
* incremented.
*/
void put(byte value);
/**
* Write a 16-bit into in the buffer at {@code writePosition()}. Write position will be
* incremented.
*/
void putShort(short value);
/**
* Write a 32-bit into in the buffer at {@code writePosition()}. Write position will be
* incremented.
*/
void putInt(int value);
/**
* Write a 64-bit into in the buffer at {@code writePosition()}. Write position will be
* incremented.
*/
void putLong(long value);
/**
* Write a 32-bit float into the buffer at {@code writePosition()}. Write position will be
* incremented.
*/
void putFloat(float value);
/**
* Write a 64-bit float into the buffer at {@code writePosition()}. Write position will be
* incremented.
*/
void putDouble(double value);
/**
* Write boolean into a given position on the buffer. Booleans as stored as single byte.
* @param index position of the element in buffer
*/
void setBoolean(int index, boolean value);
/**
* Read a byte from data.
* @param index position of the element in the buffer
* @return a byte
*/
void set(int index, byte value);
/**
* Write an array of bytes into the buffer.
* @param index initial position of the buffer to be written
* @param value the data to be copied
* @param start initial position on value to be copied
* @param length amount of bytes to be copied
*/
void set(int index, byte[] value, int start, int length);
/**
* Read a short from data.
* @param index position of the element in ReadBuf
* @return a short
*/
void setShort(int index, short value);
/**
* Read a 32-bit int from data.
* @param index position of the element in ReadBuf
* @return an int
*/
void setInt(int index, int value);
/**
* Read a 64-bit long from data.
* @param index position of the element in ReadBuf
* @return a long
*/
void setLong(int index, long value);
/**
* Read a 32-bit float from data.
* @param index position of the element in ReadBuf
* @return a float
*/
void setFloat(int index, float value);
/**
* Read a 64-bit float from data.
* @param index position of the element in ReadBuf
* @return a double
*/
void setDouble(int index, double value);
int writePosition();
/**
* Defines the size of the message in the buffer. It also determines last position that buffer
* can be read or write. Last byte to be accessed is in position {@code limit() -1}.
* @return indicate last position
*/
int limit();
/**
* Request capacity of the buffer. In case buffer is already larger
* than the requested, this method will just return true. Otherwise
* It might try to resize the buffer.
*
* @return true if buffer is able to offer
* the requested capacity
*/
boolean requestCapacity(int capacity);
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of signed or unsigned 16-bit values.
*/
public final class ShortVector extends BaseVector {
/**
* Assigns vector access object to vector data.
*
* @param _vector Start data of a vector.
* @param _bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public ShortVector __assign(int _vector, ByteBuffer _bb) {
__reset(_vector, Constants.SIZEOF_SHORT, _bb); return this;
}
/**
* Reads the short value at the given index.
*
* @param j The index from which the short value will be read.
* @return the 16-bit value at the given index.
*/
public short get(int j) {
return bb.getShort(__element(j));
}
/**
* Reads the short at the given index, zero-extends it to type int, and returns the result,
* which is therefore in the range 0 through 65535.
*
* @param j The index from which the short value will be read.
* @return the unsigned 16-bit at the given index.
*/
public int getAsUnsigned(int j) {
return (int) get(j) & 0xFFFF;
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of String.
*/
public final class StringVector extends BaseVector {
private Utf8 utf8 = Utf8.getDefault();
/**
* Assigns vector access object to vector data.
*
* @param _vector Start data of a vector.
* @param _element_size Size of a vector element.
* @param _bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public StringVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
__reset(_vector, _element_size, _bb); return this;
}
/**
* Reads the String at the given index.
*
* @param j The index from which the String value will be read.
* @return the String at the given index.
*/
public String get(int j) {
return Table.__string(__element(j), bb, utf8);
}
}

View File

@@ -29,6 +29,21 @@ public class Struct {
/** The underlying ByteBuffer to hold the data of the Struct. */
protected ByteBuffer bb;
/**
* Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
*
* This method exists primarily to allow recycling Table instances without risking memory leaks
* due to {@code ByteBuffer} references.
*/
protected void __reset(int _i, ByteBuffer _bb) {
bb = _bb;
if (bb != null) {
bb_pos = _i;
} else {
bb_pos = 0;
}
}
/**
* Resets internal state with a null {@code ByteBuffer} and a zero position.
*
@@ -39,8 +54,7 @@ public class Struct {
* @param struct the instance to reset to initial state
*/
public void __reset() {
bb = null;
bb_pos = 0;
__reset(0, null);
}
}

View File

@@ -19,7 +19,6 @@ package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/// @cond FLATBUFFERS_INTERNAL
@@ -27,20 +26,14 @@ import java.nio.charset.Charset;
* All tables in the generated code derive from this class, and add their own accessors.
*/
public class Table {
public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() {
@Override
protected Charset initialValue() {
return Charset.forName("UTF-8");
}
};
/** Used to hold the position of the `bb` buffer. */
protected int bb_pos;
/** The underlying ByteBuffer to hold the data of the Table. */
protected ByteBuffer bb;
/** Used to hold the vtable position. */
protected int vtable_start;
private int vtable_start;
/** Used to hold the vtable size. */
protected int vtable_size;
private int vtable_size;
Utf8 utf8 = Utf8.getDefault();
/**
@@ -75,6 +68,13 @@ public class Table {
return offset + bb.getInt(offset);
}
/**
* Retrieve a relative offset.
*
* @param offset An `int` index into a ByteBuffer containing the relative offset.
* @param bb from which the relative offset will be retrieved.
* @return Returns the relative offset stored at `offset`.
*/
protected static int __indirect(int offset, ByteBuffer bb) {
return offset + bb.getInt(offset);
}
@@ -91,6 +91,23 @@ public class Table {
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
*/
protected String __string(int offset) {
return __string(offset, bb, utf8);
}
/**
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
*
* This allocates a new string and converts to wide chars upon each access,
* which is not very efficient. Instead, each FlatBuffer string also comes with an
* accessor based on __vector_as_bytebuffer below, which is much more efficient,
* assuming your Java program can handle UTF-8 data directly.
*
* @param offset An `int` index into the Table's ByteBuffer.
* @param bb Table ByteBuffer used to read a string at given offset.
* @param utf8 decoder that creates a Java `String` from UTF-8 characters.
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
*/
protected static String __string(int offset, ByteBuffer bb, Utf8 utf8) {
offset += bb.getInt(offset);
int length = bb.getInt(offset);
return utf8.decodeUtf8(bb, offset + SIZEOF_INT, length);
@@ -169,11 +186,19 @@ public class Table {
* @return Returns the Table that points to the union at `offset`.
*/
protected Table __union(Table t, int offset) {
offset += bb_pos;
t.bb_pos = offset + bb.getInt(offset);
t.bb = bb;
t.vtable_start = t.bb_pos - bb.getInt(t.bb_pos);
t.vtable_size = bb.getShort(t.vtable_start);
return __union(t, offset, bb);
}
/**
* Initialize any Table-derived type to point to the union at the given `offset`.
*
* @param t A `Table`-derived type that should point to the union at `offset`.
* @param offset An `int` index into the Table's ByteBuffer.
* @param bb Table ByteBuffer used to initialize the object Table-derived type.
* @return Returns the Table that points to the union at `offset`.
*/
protected static Table __union(Table t, int offset, ByteBuffer bb) {
t.__reset(__indirect(offset, bb), bb);
return t;
}
@@ -263,6 +288,25 @@ public class Table {
return len_1 - len_2;
}
/**
* Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
*
* This method exists primarily to allow recycling Table instances without risking memory leaks
* due to {@code ByteBuffer} references.
*/
protected void __reset(int _i, ByteBuffer _bb) {
bb = _bb;
if (bb != null) {
bb_pos = _i;
vtable_start = bb_pos - bb.getInt(bb_pos);
vtable_size = bb.getShort(vtable_start);
} else {
bb_pos = 0;
vtable_start = 0;
vtable_size = 0;
}
}
/**
* Resets the internal state with a null {@code ByteBuffer} and a zero position.
*
@@ -271,10 +315,7 @@ public class Table {
* again to a {@code ByteBuffer}.
*/
public void __reset() {
bb = null;
bb_pos = 0;
vtable_start = 0;
vtable_size = 0;
__reset(0, null);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2019 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.flatbuffers;
import static com.google.flatbuffers.Constants.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
/**
* Helper type for accessing vector of unions.
*/
public final class UnionVector extends BaseVector {
/**
* Assigns vector access object to vector data.
*
* @param _vector Start data of a vector.
* @param _element_size Size of a vector element.
* @param _bb Table's ByteBuffer.
* @return Returns current vector access object assigned to vector data whose offset is stored at
* `vector`.
*/
public UnionVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
__reset(_vector, _element_size, _bb); return this;
}
/**
* Initialize any Table-derived type to point to the union at the given `index`.
*
* @param obj A `Table`-derived type that should point to the union at `index`.
* @param j An `int` index into the union vector.
* @return Returns the Table that points to the union at `index`.
*/
public Table get(Table obj, int j) {
return Table.__union(obj, __element(j), bb);
}
}

View File

@@ -110,9 +110,11 @@ public abstract class Utf8 {
throws IllegalArgumentException {
// Simultaneously checks for illegal trailing-byte in leading position (<= '11000000') and
// overlong 2-byte, '11000001'.
if (byte1 < (byte) 0xC2
|| isNotTrailingByte(byte2)) {
throw new IllegalArgumentException("Invalid UTF-8");
if (byte1 < (byte) 0xC2) {
throw new IllegalArgumentException("Invalid UTF-8: Illegal leading byte in 2 bytes utf");
}
if (isNotTrailingByte(byte2)) {
throw new IllegalArgumentException("Invalid UTF-8: Illegal trailing byte in 2 bytes utf");
}
resultArr[resultPos] = (char) (((byte1 & 0x1F) << 6) | trailingByteValue(byte2));
}

View File

@@ -67,6 +67,7 @@ public class Utf8Old extends Utf8 {
throw new IllegalArgumentException("bad character encoding", e);
}
}
cache.lastOutput.flip();
return cache.lastOutput.remaining();
}
@@ -90,7 +91,6 @@ public class Utf8Old extends Utf8 {
buffer.limit(offset + length);
try {
CharBuffer result = decoder.decode(buffer);
result.flip();
return result.toString();
} catch (CharacterCodingException e) {
throw new IllegalArgumentException("Bad encoding", e);

View File

@@ -123,7 +123,7 @@ final public class Utf8Safe extends Utf8 {
return utf8Length;
}
private static String decodeUtf8Array(byte[] bytes, int index, int size) {
public static String decodeUtf8Array(byte[] bytes, int index, int size) {
// Bitwise OR combines the sign bits so any negative value fails the check.
if ((index | size | bytes.length - index - size) < 0) {
throw new ArrayIndexOutOfBoundsException(
@@ -197,7 +197,7 @@ final public class Utf8Safe extends Utf8 {
return new String(resultArr, 0, resultPos);
}
private static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
public static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
int length) {
// Bitwise OR combines the sign bits so any negative value fails the check.
if ((offset | length | buffer.limit() - offset - length) < 0) {

View File

@@ -48,6 +48,12 @@ flatbuffers.SIZEOF_INT = 4;
*/
flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
/**
* @type {number}
* @const
*/
flatbuffers.SIZE_PREFIX_LENGTH = 4;
/**
* @enum {number}
*/
@@ -104,7 +110,7 @@ flatbuffers.Long = function(low, high) {
/**
* @param {number} low
* @param {number} high
* @returns {flatbuffers.Long}
* @returns {!flatbuffers.Long}
*/
flatbuffers.Long.create = function(low, high) {
// Special-case zero to avoid GC overhead for default values
@@ -127,7 +133,7 @@ flatbuffers.Long.prototype.equals = function(other) {
};
/**
* @type {flatbuffers.Long}
* @type {!flatbuffers.Long}
* @const
*/
flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
@@ -265,7 +271,7 @@ flatbuffers.Builder.prototype.dataBuffer = function() {
* Get the bytes representing the FlatBuffer. Only call this after you've
* called finish().
*
* @returns {Uint8Array}
* @returns {!Uint8Array}
*/
flatbuffers.Builder.prototype.asUint8Array = function() {
return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
@@ -550,7 +556,7 @@ flatbuffers.Builder.prototype.offset = function() {
* the end of the new buffer (since we build the buffer backwards).
*
* @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
* @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
* @returns {!flatbuffers.ByteBuffer} A new byte buffer with the old data copied
* to it. The data is located at the end of the buffer.
*
* uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
@@ -676,12 +682,14 @@ outer_loop:
*
* @param {flatbuffers.Offset} root_table
* @param {string=} opt_file_identifier
* @param {boolean=} opt_size_prefix
*/
flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier) {
flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier, opt_size_prefix) {
var size_prefix = opt_size_prefix ? flatbuffers.SIZE_PREFIX_LENGTH : 0;
if (opt_file_identifier) {
var file_identifier = opt_file_identifier;
this.prep(this.minalign, flatbuffers.SIZEOF_INT +
flatbuffers.FILE_IDENTIFIER_LENGTH);
flatbuffers.FILE_IDENTIFIER_LENGTH + size_prefix);
if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
throw new Error('FlatBuffers: file identifier must be length ' +
flatbuffers.FILE_IDENTIFIER_LENGTH);
@@ -690,11 +698,24 @@ flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier)
this.writeInt8(file_identifier.charCodeAt(i));
}
}
this.prep(this.minalign, flatbuffers.SIZEOF_INT);
this.prep(this.minalign, flatbuffers.SIZEOF_INT + size_prefix);
this.addOffset(root_table);
if (size_prefix) {
this.addInt32(this.bb.capacity() - this.space);
}
this.bb.setPosition(this.space);
};
/**
* Finalize a size prefixed buffer, pointing to the given `root_table`.
*
* @param {flatbuffers.Offset} root_table
* @param {string=} opt_file_identifier
*/
flatbuffers.Builder.prototype.finishSizePrefixed = function (root_table, opt_file_identifier) {
this.finish(root_table, opt_file_identifier, true);
};
/// @cond FLATBUFFERS_INTERNAL
/**
* This checks a required field has been set in a given table that has
@@ -804,7 +825,7 @@ flatbuffers.Builder.prototype.createString = function(s) {
*
* @param {number} low
* @param {number} high
* @returns {flatbuffers.Long}
* @returns {!flatbuffers.Long}
*/
flatbuffers.Builder.prototype.createLong = function(low, high) {
return flatbuffers.Long.create(low, high);
@@ -835,7 +856,7 @@ flatbuffers.ByteBuffer = function(bytes) {
* Create and allocate a new ByteBuffer with a given size.
*
* @param {number} byte_size
* @returns {flatbuffers.ByteBuffer}
* @returns {!flatbuffers.ByteBuffer}
*/
flatbuffers.ByteBuffer.allocate = function(byte_size) {
return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
@@ -931,7 +952,7 @@ flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
/**
* @param {number} offset
* @returns {flatbuffers.Long}
* @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
@@ -939,7 +960,7 @@ flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
/**
* @param {number} offset
* @returns {flatbuffers.Long}
* @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
@@ -1114,7 +1135,7 @@ flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
*
* @param {number} offset
* @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
* @returns {string|Uint8Array}
* @returns {string|!Uint8Array}
*/
flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
offset += this.readInt32(offset);
@@ -1225,7 +1246,7 @@ flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
*
* @param {number} low
* @param {number} high
* @returns {flatbuffers.Long}
* @returns {!flatbuffers.Long}
*/
flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
return flatbuffers.Long.create(low, high);

View File

@@ -12,32 +12,37 @@
// See the License for the specific language governing permissions and
// limitations under the License.
include "std.lobster"
import std
namespace flatbuffers
struct handle:
class handle:
buf_:string
pos_:int
enum + sz_8 = 1,
sz_16 = 2,
sz_32 = 4,
sz_64 = 8,
sz_voffset = 2,
sz_uoffset = 4,
sz_soffset = 4,
sz_metadata_fields = 2
// More strongly typed than a naked int, at no cost.
struct offset:
o:int
struct builder:
buf:string = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
enum sizeof:
sz_8 = 1
sz_16 = 2
sz_32 = 4
sz_64 = 8
sz_voffset = 2
sz_uoffset = 4
sz_soffset = 4
sz_metadata_fields = 2
class builder:
buf = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
current_vtable:[int] = []
head:int = 0
minalign:int = 1
object_end:int = 0
head = 0
minalign = 1
object_end = 0
vtables:[int] = []
nested:int = false
finished:int = false
nested = false
finished = false
// Optionally call this right after creating the builder for a larger initial buffer.
def Initial(initial_size:int):
@@ -49,7 +54,7 @@ struct builder:
def Offset():
// Offset relative to the end of the buffer.
return head
return offset { head }
// Returns a copy of the part of the buffer containing only the finished FlatBuffer
def SizedCopy():
@@ -75,11 +80,11 @@ struct builder:
// Prepend a zero scalar to the object. Later in this function we'll
// write an offset here that points to the object's vtable:
PrependInt32(0)
object_offset := head
let object_offset = head
// Write out new vtable speculatively.
vtable_size := (current_vtable.length + sz_metadata_fields) * sz_voffset
let vtable_size = (current_vtable.length + sz_metadata_fields) * sz_voffset
while current_vtable.length:
o := current_vtable.pop()
let o = current_vtable.pop()
PrependVOffsetT(if o: object_offset - o else: 0)
// The two metadata fields are written last.
// First, store the object bytesize:
@@ -91,17 +96,18 @@ struct builder:
// BenchmarkVtableDeduplication for a case in which this heuristic
// saves about 30% of the time used in writing objects with duplicate
// tables.
existing_vtable := do():
def find_existing_table():
reverse(vtables) vt2_offset:
// Find the other vtable:
vt2_start := buf.length - vt2_offset
vt2_len := buf.read_int16_le(vt2_start)
let vt2_start = buf.length - vt2_offset
let vt2_len = buf.read_int16_le(vt2_start)
// Compare the other vtable to the one under consideration.
// If they are equal, return the offset:
if vtable_size == vt2_len and
not compare_substring(buf, Start(), buf, vt2_start, vtable_size):
return vt2_offset from do
0
return vt2_offset
return 0
let existing_vtable = find_existing_table()
if existing_vtable:
// Found a duplicate vtable, remove the one we wrote.
head = object_offset
@@ -116,10 +122,11 @@ struct builder:
// Finally, store this vtable in memory for future
// deduplication:
vtables.push(head)
return object_offset
return offset { object_offset }
def Pad(n):
for(n): buf, head = buf.write_int8_le_back(head, 0)
for(n):
buf, head = buf.write_int8_le_back(head, 0)
def Prep(size, additional_bytes):
// Track the biggest thing we've ever aligned to.
@@ -127,27 +134,27 @@ struct builder:
minalign = size
// Find the amount of alignment needed such that `size` is properly
// aligned after `additionalBytes`:
align_size := ((~(head + additional_bytes)) + 1) & (size - 1)
let align_size = ((~(head + additional_bytes)) + 1) & (size - 1)
Pad(align_size)
def PrependUOffsetTRelative(off):
def PrependUOffsetTRelative(off:offset):
// Prepends an unsigned offset into vector data, relative to where it will be written.
Prep(sz_uoffset, 0)
assert off <= head
PlaceUOffsetT(head - off + sz_uoffset)
assert off.o <= head
PlaceUOffsetT(head - off.o + sz_uoffset)
def StartVector(elem_size, num_elems, alignment):
// Initializes bookkeeping for writing a new vector.
StartNesting()
Prep(sz_32, elem_size * num_elems)
Prep(alignment, elem_size * num_elems) // In case alignment > int.
return head
return Offset()
def EndVector(vector_num_elems):
EndNesting()
// we already made space for this, so write without PrependUint32
PlaceUOffsetT(vector_num_elems)
return head
return Offset()
def CreateString(s:string):
// writes a null-terminated byte string.
@@ -168,11 +175,11 @@ struct builder:
while current_vtable.length <= slotnum: current_vtable.push(0)
current_vtable[slotnum] = head
def __Finish(root_table:int, size_prefix:int):
def __Finish(root_table:offset, size_prefix:int):
// Finish finalizes a buffer, pointing to the given root_table
assert not finished
assert not nested
prep_size := sz_32
var prep_size = sz_32
if size_prefix:
prep_size += sz_32
Prep(minalign, prep_size)
@@ -182,10 +189,10 @@ struct builder:
finished = true
return Start()
def Finish(root_table:int):
def Finish(root_table:offset):
return __Finish(root_table, false)
def FinishSizePrefixed(root_table:int):
def FinishSizePrefixed(root_table:offset):
return __Finish(root_table, true)
def PrependBool(x):
@@ -263,16 +270,15 @@ struct builder:
def PrependFloat32Slot(o, x, d): PrependSlot(o, x, d): PrependFloat32(_)
def PrependFloat64Slot(o, x, d): PrependSlot(o, x, d): PrependFloat64(_)
def PrependUOffsetTRelativeSlot(o, x, d):
if x != d:
def PrependUOffsetTRelativeSlot(o:int, x:offset):
if x.o:
PrependUOffsetTRelative(x)
Slot(o)
def PrependStructSlot(v, x, d):
if x != d:
def PrependStructSlot(v:int, x:offset):
if x.o:
// Structs are always stored inline, so need to be created right
// where they are used. You'll get this error if you created it
//elsewhere.
assert x == head
// elsewhere.
assert x.o == head
Slot(v)

View File

@@ -29,12 +29,12 @@ local getAlignSize = compat.GetAlignSize
local function vtableEqual(a, objectStart, b)
UOffsetT:EnforceNumber(objectStart)
if (#a * VOffsetT.bytewidth) ~= #b then
if (#a * 2) ~= #b then
return false
end
for i, elem in ipairs(a) do
local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * VOffsetT.bytewidth)
local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * 2)
if x ~= 0 or elem ~= 0 then
local y = objectStart - elem
if x ~= y then
@@ -60,6 +60,23 @@ function m.New(initialSize)
return o
end
-- Clears the builder and resets the state. It does not actually clear the backing binary array, it just reuses it as
-- needed. This is a performant way to use the builder for multiple constructions without the overhead of multiple
-- builder allocations.
function mt:Clear()
self.finished = false
self.nested = false
self.minalign = 1
self.currentVTable = nil
self.objectEnd = nil
self.head = #self.bytes -- place the head at the end of the binary array
-- clear vtables instead of making a new table
local vtable = self.vtables
local vtableCount = #vtable
for i=1,vtableCount do vtable[i] = nil end
end
function mt:Output(full)
assert(self.finished, "Builder Not Finished")
if full then
@@ -104,7 +121,7 @@ function mt:WriteVtable()
local vt2lenstr = self.bytes:Slice(vt2Start, vt2Start+1)
local vt2Len = string.unpack(VOffsetT.packFmt, vt2lenstr, 1)
local metadata = VtableMetadataFields * VOffsetT.bytewidth
local metadata = VtableMetadataFields * 2
local vt2End = vt2Start + vt2Len
local vt2 = self.bytes:Slice(vt2Start+metadata,vt2End)
@@ -133,7 +150,7 @@ function mt:WriteVtable()
self:PrependVOffsetT(objectSize)
local vBytes = #self.currentVTable + VtableMetadataFields
vBytes = vBytes * VOffsetT.bytewidth
vBytes = vBytes * 2
self:PrependVOffsetT(vBytes)
local objectStart = #self.bytes - objectOffset
@@ -208,17 +225,17 @@ function mt:Prep(size, additionalBytes)
end
function mt:PrependSOffsetTRelative(off)
self:Prep(SOffsetT.bytewidth, 0)
self:Prep(4, 0)
assert(off <= self:Offset(), "Offset arithmetic error")
local off2 = self:Offset() - off + SOffsetT.bytewidth
local off2 = self:Offset() - off + 4
self:Place(off2, SOffsetT)
end
function mt:PrependUOffsetTRelative(off)
self:Prep(UOffsetT.bytewidth, 0)
self:Prep(4, 0)
local soffset = self:Offset()
if off <= soffset then
local off2 = soffset - off + UOffsetT.bytewidth
local off2 = soffset - off + 4
self:Place(off2, UOffsetT)
else
error("Offset arithmetic error")
@@ -228,8 +245,9 @@ end
function mt:StartVector(elemSize, numElements, alignment)
assert(not self.nested)
self.nested = true
self:Prep(Uint32.bytewidth, elemSize * numElements)
self:Prep(alignment, elemSize * numElements)
local elementSize = elemSize * numElements
self:Prep(4, elementSize) -- Uint32 length
self:Prep(alignment, elementSize)
return self:Offset()
end
@@ -246,7 +264,7 @@ function mt:CreateString(s)
assert(type(s) == "string")
self:Prep(UOffsetT.bytewidth, (#s + 1)*Uint8.bytewidth)
self:Prep(4, #s + 1)
self:Place(0, Uint8)
local l = #s
@@ -254,20 +272,21 @@ function mt:CreateString(s)
self.bytes:Set(s, self.head, self.head + l)
return self:EndVector(#s)
return self:EndVector(l)
end
function mt:CreateByteVector(x)
assert(not self.nested)
self.nested = true
self:Prep(UOffsetT.bytewidth, #x*Uint8.bytewidth)
local l = #x
self:Prep(4, l)
self.head = self.head - l
self.bytes:Set(x, self.head, self.head + l)
return self:EndVector(#x)
return self:EndVector(l)
end
function mt:Slot(slotnum)
@@ -278,12 +297,7 @@ end
local function finish(self, rootTable, sizePrefix)
UOffsetT:EnforceNumber(rootTable)
local prepSize = UOffsetT.bytewidth
if sizePrefix then
prepSize = prepSize + Int32.bytewidth
end
self:Prep(self.minalign, prepSize)
self:Prep(self.minalign, sizePrefix and 8 or 4)
self:PrependUOffsetTRelative(rootTable)
if sizePrefix then
local size = #self.bytes - self.head
@@ -308,8 +322,9 @@ function mt:Prepend(flags, off)
end
function mt:PrependSlot(flags, o, x, d)
flags:EnforceNumber(x)
flags:EnforceNumber(d)
flags:EnforceNumbers(x,d)
-- flags:EnforceNumber(x)
-- flags:EnforceNumber(d)
if x ~= d then
self:Prepend(flags, x)
self:Slot(o)

View File

@@ -34,6 +34,20 @@ function type_mt:EnforceNumber(n)
error("Number is not in the valid range")
end
function type_mt:EnforceNumbers(a,b)
-- duplicate code since the overhead of function calls
-- for such a popular method is time consuming
if not self.min_value and not self.max_value then
return
end
if self.min_value <= a and a <= self.max_value and self.min_value <= b and b <= self.max_value then
return
end
error("Number is not in the valid range")
end
function type_mt:EnforceNumberAndPack(n)
return bpack(self.packFmt, n)
end
@@ -53,7 +67,13 @@ local bool_mt =
max_value = true,
lua_type = type(true),
name = "bool",
packFmt = "<b"
packFmt = "<I1",
Pack = function(self, value) return value and "1" or "0" end,
Unpack = function(self, buf, pos) return buf[pos] == "1" end,
ValidNumber = function(self, n) return true end, -- anything is a valid boolean in Lua
EnforceNumber = function(self, n) end, -- anything is a valid boolean in Lua
EnforceNumbers = function(self, a, b) end, -- anything is a valid boolean in Lua
EnforceNumberAndPack = function(self, n) return self:Pack(value) end,
}
local uint8_mt =
@@ -170,7 +190,6 @@ setmetatable(float32_mt, {__index = type_mt})
setmetatable(float64_mt, {__index = type_mt})
m.Bool = bool_mt
m.Uint8 = uint8_mt
m.Uint16 = uint16_mt
m.Uint32 = uint32_mt
@@ -186,7 +205,7 @@ m.UOffsetT = uint32_mt
m.VOffsetT = uint16_mt
m.SOffsetT = int32_mt
function GenerateTypes(listOfTypes)
local GenerateTypes = function(listOfTypes)
for _,t in pairs(listOfTypes) do
t.Pack = function(self, value) return bpack(self.packFmt, value) end
t.Unpack = function(self, buf, pos) return bunpack(self.packFmt, buf, pos) end
@@ -195,4 +214,6 @@ end
GenerateTypes(m)
-- explicitly execute after GenerateTypes call, as we don't want to define a Pack/Unpack function for it.
m.Bool = bool_mt
return m

View File

@@ -6,69 +6,83 @@ local mt_name = "flatbuffers.view.mt"
local N = require("flatbuffers.numTypes")
local binaryarray = require("flatbuffers.binaryarray")
local function enforceOffset(off)
if off < 0 or off > 42949672951 then
error("Offset is not valid")
end
end
local unpack = string.unpack
local function unPackUoffset(bytes, off)
return unpack("<I4", bytes.str, off + 1)
end
local function unPackVoffset(bytes, off)
return unpack("<I2", bytes.str, off + 1)
end
function m.New(buf, pos)
N.UOffsetT:EnforceNumber(pos)
enforceOffset(pos)
-- need to convert from a string buffer into
-- a binary array
local o = {
bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
pos = pos
pos = pos,
}
setmetatable(o, {__index = mt, __metatable = mt_name})
return o
end
function mt:Offset(vtableOffset)
local vtable = self.pos - self:Get(N.SOffsetT, self.pos)
local vtableEnd = self:Get(N.VOffsetT, vtable)
if vtableOffset < vtableEnd then
return self:Get(N.VOffsetT, vtable + vtableOffset)
local vtable = self.vtable
if not vtable then
vtable = self.pos - self:Get(N.SOffsetT, self.pos)
self.vtable = vtable
self.vtableEnd = self:Get(N.VOffsetT, vtable)
end
if vtableOffset < self.vtableEnd then
return unPackVoffset(self.bytes, vtable + vtableOffset)
end
return 0
end
function mt:Indirect(off)
N.UOffsetT:EnforceNumber(off)
return off + N.UOffsetT:Unpack(self.bytes, off)
enforceOffset(off)
return off + unPackUoffset(self.bytes, off)
end
function mt:String(off)
N.UOffsetT:EnforceNumber(off)
off = off + N.UOffsetT:Unpack(self.bytes, off)
local start = off + N.UOffsetT.bytewidth
local length = N.UOffsetT:Unpack(self.bytes, off)
enforceOffset(off)
off = off + unPackUoffset(self.bytes, off)
local start = off + 4
local length = unPackUoffset(self.bytes, off)
return self.bytes:Slice(start, start+length)
end
function mt:VectorLen(off)
N.UOffsetT:EnforceNumber(off)
enforceOffset(off)
off = off + self.pos
off = off + N.UOffsetT:Unpack(self.bytes, off)
return N.UOffsetT:Unpack(self.bytes, off)
off = off + unPackUoffset(self.bytes, off)
return unPackUoffset(self.bytes, off)
end
function mt:Vector(off)
N.UOffsetT:EnforceNumber(off)
enforceOffset(off)
off = off + self.pos
local x = off + self:Get(N.UOffsetT, off)
x = x + N.UOffsetT.bytewidth
return x
return off + self:Get(N.UOffsetT, off) + 4
end
function mt:Union(t2, off)
assert(getmetatable(t2) == mt_name)
N.UOffsetT:EnforceNumber(off)
enforceOffset(off)
off = off + self.pos
t2.pos = off + self:Get(N.UOffsetT, off)
t2.bytes = self.bytes
end
function mt:Get(flags, off)
N.UOffsetT:EnforceNumber(off)
enforceOffset(off)
return flags:Unpack(self.bytes, off)
end
@@ -85,8 +99,7 @@ function mt:GetSlot(slot, d, validatorFlags)
end
function mt:GetVOffsetTSlot(slot, d)
N.VOffsetT:EnforceNumber(slot)
N.VOffsetT:EnforceNumber(d)
N.VOffsetT:EnforceNumbers(slot, d)
local off = self:Offset(slot)
if off == 0 then
return d

View File

@@ -16,6 +16,7 @@
using System;
using System.Collections.Generic;
using System.Text;
/// @file
@@ -47,6 +48,9 @@ namespace FlatBuffers
// For the current vector being built.
private int _vectorNumElems = 0;
// For CreateSharedString
private Dictionary<string, StringOffset> _sharedStringMap = null;
/// <summary>
/// Create a FlatBufferBuilder with a given initial size.
/// </summary>
@@ -191,7 +195,7 @@ namespace FlatBuffers
}
/// <summary>
/// Puts an array of type T into this builder at the
/// Puts an array of type T into this builder at the
/// current offset
/// </summary>
/// <typeparam name="T">The type of the input data </typeparam>
@@ -204,7 +208,7 @@ namespace FlatBuffers
#if ENABLE_SPAN_T
/// <summary>
/// Puts a span of type T into this builder at the
/// Puts a span of type T into this builder at the
/// current offset
/// </summary>
/// <typeparam name="T">The type of the input data </typeparam>
@@ -407,7 +411,7 @@ namespace FlatBuffers
"FlatBuffers: object serialization must not be nested.");
}
public void StartObject(int numfields)
public void StartTable(int numfields)
{
if (numfields < 0)
throw new ArgumentOutOfRangeException("Flatbuffers: invalid numfields");
@@ -536,9 +540,9 @@ namespace FlatBuffers
/// </summary>
/// <param name="o">The index into the vtable</param>
/// <param name="x">The value to put into the buffer. If the value is equal to the default
/// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
/// the value will be skipped.</param>
/// <param name="d">The default value to compare the value against</param>
public void AddOffset(int o, int x, int d) { if (ForceDefaults || x != d) { AddOffset(x); Slot(o); } }
public void AddOffset(int o, int x, int d) { if (x != d) { AddOffset(x); Slot(o); } }
/// @endcond
/// <summary>
@@ -579,6 +583,32 @@ namespace FlatBuffers
}
#endif
/// <summary>
/// Store a string in the buffer, which can contain any binary data.
/// If a string with this exact contents has already been serialized before,
/// instead simply returns the offset of the existing string.
/// </summary>
/// <param name="s">The string to encode.</param>
/// <returns>
/// The offset in the buffer where the encoded string starts.
/// </returns>
public StringOffset CreateSharedString(string s)
{
if (_sharedStringMap == null)
{
_sharedStringMap = new Dictionary<string, StringOffset>();
}
if (_sharedStringMap.ContainsKey(s))
{
return _sharedStringMap[s];
}
var stringOffset = CreateString(s);
_sharedStringMap.Add(s, stringOffset);
return stringOffset;
}
/// @cond FLATBUFFERS_INTERNAL
// Structs are stored inline, so nothing additional is being added.
// `d` is always 0.
@@ -591,11 +621,11 @@ namespace FlatBuffers
}
}
public int EndObject()
public int EndTable()
{
if (_vtableSize < 0)
throw new InvalidOperationException(
"Flatbuffers: calling endObject without a startObject");
"Flatbuffers: calling EndTable without a StartTable");
AddInt((int)0);
var vtableloc = Offset;

View File

@@ -25,5 +25,13 @@ namespace FlatBuffers
{
public const int FileIdentifierLength = 4;
public const int SizePrefixLength = 4;
/** A version identifier to force a compile error if someone
accidentally tries to build generated code with a runtime of
two mismatched version. Versions need to always match, as
the runtime and generated code are modified in sync.
Changes to the C# implementation need to be sure to change
the version here and in the code generator on every possible
incompatible change */
public static void FLATBUFFERS_1_12_0() {}
}
}

View File

@@ -21,7 +21,14 @@ namespace FlatBuffers
/// </summary>
public struct Struct
{
public int bb_pos;
public ByteBuffer bb;
public int bb_pos { get; private set; }
public ByteBuffer bb { get; private set; }
// Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
public Struct(int _i, ByteBuffer _bb) : this()
{
bb = _bb;
bb_pos = _i;
}
}
}

View File

@@ -16,6 +16,7 @@
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace FlatBuffers
{
@@ -24,11 +25,18 @@ namespace FlatBuffers
/// </summary>
public struct Table
{
public int bb_pos;
public ByteBuffer bb;
public int bb_pos { get; private set; }
public ByteBuffer bb { get; private set; }
public ByteBuffer ByteBuffer { get { return bb; } }
// Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
public Table(int _i, ByteBuffer _bb) : this()
{
bb = _bb;
bb_pos = _i;
}
// Look up a field in the vtable, return an offset into the object, or 0 if the field is not
// present.
public int __offset(int vtableOffset)
@@ -82,17 +90,23 @@ namespace FlatBuffers
// Get the data of a vector whoses offset is stored at "offset" in this object as an
// Spant&lt;byte&gt;. If the vector is not present in the ByteBuffer,
// then an empty span will be returned.
public Span<byte> __vector_as_span(int offset)
public Span<T> __vector_as_span<T>(int offset, int elementSize) where T : struct
{
if (!BitConverter.IsLittleEndian)
{
throw new NotSupportedException("Getting typed span on a Big Endian " +
"system is not support");
}
var o = this.__offset(offset);
if (0 == o)
{
return new Span<byte>();
return new Span<T>();
}
var pos = this.__vector(o);
var len = this.__vector_len(o);
return bb.ToSpan(pos, len);
return MemoryMarshal.Cast<byte, T>(bb.ToSpan(pos, len * elementSize));
}
#else
// Get the data of a vector whoses offset is stored at "offset" in this object as an
@@ -138,9 +152,8 @@ namespace FlatBuffers
// Initialize any Table-derived type to point to the union at the given offset.
public T __union<T>(int offset) where T : struct, IFlatbufferObject
{
offset += bb_pos;
T t = new T();
t.__init(offset + bb.GetInt(offset), bb);
t.__init(__indirect(offset), bb);
return t;
}

View File

@@ -1,6 +1,6 @@
{
"name": "flatbuffers",
"version": "1.11.0",
"version": "1.12.0",
"description": "Memory Efficient Serialization Library",
"files": [
"js/flatbuffers.js",

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