forked from BigfootDev/flatbuffers
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cebdad4d23 | ||
|
|
d798100be9 | ||
|
|
1fb6b9ee6f | ||
|
|
2d6e8f096b | ||
|
|
ec8038cc3d | ||
|
|
2df3d1c965 | ||
|
|
2272229983 | ||
|
|
b7bfecb4ee | ||
|
|
c7c4bbfce2 | ||
|
|
d7ba17dfe5 | ||
|
|
60b11435e6 | ||
|
|
ed2110d7b3 | ||
|
|
a9514de978 | ||
|
|
c57ab92e60 | ||
|
|
f878024d0b | ||
|
|
aac6be1153 | ||
|
|
dabe030890 | ||
|
|
29574282a2 | ||
|
|
2dd6ba57d1 | ||
|
|
6cc2307c71 | ||
|
|
74c8c7137a | ||
|
|
f9055ff9a7 | ||
|
|
9b3d8b318a | ||
|
|
87e29b25de | ||
|
|
f7bc9bd51b | ||
|
|
3dee617c86 | ||
|
|
2fb25e2bb3 | ||
|
|
b395359b6e | ||
|
|
fd61d70205 | ||
|
|
4f4495a693 | ||
|
|
68bbe983e9 | ||
|
|
bbef92c17d | ||
|
|
25c884158f | ||
|
|
3f936c5655 | ||
|
|
42a265b419 | ||
|
|
4bc4979acc | ||
|
|
b095367d17 | ||
|
|
eac2905568 | ||
|
|
12fd0c6838 | ||
|
|
19101826a8 | ||
|
|
7b94eab2b1 | ||
|
|
1a21b54560 | ||
|
|
b55f18649a | ||
|
|
e2373668d9 | ||
|
|
8c1a723ba5 | ||
|
|
ab7949dc16 | ||
|
|
2c4dce5ba7 | ||
|
|
cc84240098 |
16
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
16
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
Thank you for submitting a PR!
|
||||
|
||||
Please 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
|
||||
`cd tests && sh generate_code.sh` (or equivalent .bat) and include the generated
|
||||
code changes in the PR. This allows us to better see the effect of the PR.
|
||||
|
||||
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.
|
||||
|
||||
Include other details as appropriate.
|
||||
|
||||
Thanks!
|
||||
@@ -30,6 +30,8 @@ set(FlatBuffers_Library_SRCS
|
||||
include/flatbuffers/util.h
|
||||
include/flatbuffers/reflection.h
|
||||
include/flatbuffers/reflection_generated.h
|
||||
include/flatbuffers/flexbuffers.h
|
||||
src/code_generators.cpp
|
||||
src/idl_parser.cpp
|
||||
src/idl_gen_text.cpp
|
||||
src/reflection.cpp
|
||||
@@ -47,6 +49,7 @@ set(FlatBuffers_Compiler_SRCS
|
||||
src/idl_gen_fbs.cpp
|
||||
src/idl_gen_grpc.cpp
|
||||
src/flatc.cpp
|
||||
src/flatc_main.cpp
|
||||
grpc/src/compiler/schema_interface.h
|
||||
grpc/src/compiler/cpp_generator.h
|
||||
grpc/src/compiler/cpp_generator.cc
|
||||
@@ -62,7 +65,6 @@ set(FlatHash_SRCS
|
||||
set(FlatBuffers_Tests_SRCS
|
||||
${FlatBuffers_Library_SRCS}
|
||||
src/idl_gen_fbs.cpp
|
||||
src/idl_gen_general.cpp
|
||||
tests/test.cpp
|
||||
# file generate by running compiler on tests/monster_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
||||
@@ -76,13 +78,7 @@ set(FlatBuffers_Sample_Binary_SRCS
|
||||
)
|
||||
|
||||
set(FlatBuffers_Sample_Text_SRCS
|
||||
include/flatbuffers/flatbuffers.h
|
||||
include/flatbuffers/hash.h
|
||||
include/flatbuffers/idl.h
|
||||
include/flatbuffers/util.h
|
||||
src/idl_parser.cpp
|
||||
src/idl_gen_text.cpp
|
||||
src/util.cpp
|
||||
${FlatBuffers_Library_SRCS}
|
||||
samples/sample_text.cpp
|
||||
# file generated by running compiler on samples/monster.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||
|
||||
@@ -25,7 +25,7 @@ use Github pull requests for this purpose.
|
||||
|
||||
Some tips for good pull requests:
|
||||
* Use our code
|
||||
[style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.html).
|
||||
[style guide](https://google.github.io/styleguide/cppguide.html).
|
||||
When in doubt, try to stay true to the existing code of the project.
|
||||
* Write a descriptive commit message. What problem are you solving and what
|
||||
are the consequences? Where and what did you test? Some good tips:
|
||||
|
||||
@@ -24,7 +24,9 @@ LOCAL_PATH := $(call realpath-portable,$(LOCAL_PATH))
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := flatbuffers
|
||||
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
|
||||
LOCAL_EXPORT_CPPFLAGS := -std=c++11 -fexceptions -Wall -Wno-literal-suffix
|
||||
LOCAL_EXPORT_CPPFLAGS := -std=c++11 -fexceptions -Wall \
|
||||
-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
# static library that additionally includes text parsing/generation/reflection
|
||||
@@ -34,7 +36,8 @@ LOCAL_MODULE := flatbuffers_extra
|
||||
LOCAL_SRC_FILES := src/idl_parser.cpp \
|
||||
src/idl_gen_text.cpp \
|
||||
src/reflection.cpp \
|
||||
src/util.cpp
|
||||
src/util.cpp \
|
||||
src/code_generators.cpp
|
||||
LOCAL_STATIC_LIBRARIES := flatbuffers
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
|
||||
@@ -93,6 +93,12 @@ Additional options:
|
||||
output (by default the case for C++ and JS), all code will end up in
|
||||
this one file.
|
||||
|
||||
- `--no-js-exports` : Removes Node.js style export lines (useful for JS)
|
||||
|
||||
- `--goog-js-export` : Uses goog.exportsSymbol and goog.exportsProperty
|
||||
instead of Node.js style exporting. Needed for compatibility with the
|
||||
Google closure compiler (useful for JS).
|
||||
|
||||
- `--raw-binary` : Allow binaries without a file_indentifier to be read.
|
||||
This may crash flatc given a mismatched schema.
|
||||
|
||||
@@ -108,9 +114,14 @@ Additional options:
|
||||
to the reflection/reflection.fbs schema. Loading this binary file is the
|
||||
basis for reflection functionality.
|
||||
|
||||
- `--bfbs-comments`: Add doc comments to the binary schema files.
|
||||
|
||||
- `--conform FILE` : Specify a schema the following schemas should be
|
||||
an evolution of. Gives errors if not. Useful to check if schema
|
||||
modifications don't break schema evolution rules.
|
||||
|
||||
- `--include-prefix PATH` : Prefix this path to any generated include
|
||||
statements.
|
||||
|
||||
NOTE: short-form options for generators are deprecated, use the long form
|
||||
whenever possible.
|
||||
|
||||
@@ -85,7 +85,7 @@ convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
|
||||
|
||||
*Note: That we never stored a `mana` value, so it will return the default.*
|
||||
|
||||
## Object based API.
|
||||
## Object based API. {#flatbuffers_cpp_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
|
||||
@@ -99,13 +99,79 @@ construction, access and mutation.
|
||||
To use:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
auto monsterobj = UnpackMonster(buffer);
|
||||
// Autogenerated class from table Monster.
|
||||
MonsterT monsterobj;
|
||||
|
||||
// Deserialize from buffer into object.
|
||||
UnPackTo(&monsterobj, flatbuffer);
|
||||
|
||||
// Update object directly like a C++ class instance.
|
||||
cout << monsterobj->name; // This is now a std::string!
|
||||
monsterobj->name = "Bob"; // Change the name.
|
||||
|
||||
// Serialize into new flatbuffer.
|
||||
FlatBufferBuilder fbb;
|
||||
CreateMonster(fbb, monsterobj.get()); // Serialize into new buffer.
|
||||
Pack(fbb, &monsterobj);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following attributes are specific to the object-based API code generation:
|
||||
|
||||
- `native_inline` (on a field): Because FlatBuffer tables and structs are
|
||||
optionally present in a given buffer, they are best represented as pointers
|
||||
(specifically std::unique_ptrs) in the native class since they can be null.
|
||||
This attribute changes the member declaration to use the type directly
|
||||
rather than wrapped in a unique_ptr.
|
||||
|
||||
- `native_default`: "value" (on a field): For members that are declared
|
||||
"native_inline", the value specified with this attribute will be included
|
||||
verbatim in the class constructor initializer list for this member.
|
||||
|
||||
- `native_type`' "type" (on a struct): In some cases, a more optimal C++ data
|
||||
type exists for a given struct. For example, the following schema:
|
||||
|
||||
struct Vec2 {
|
||||
x: float;
|
||||
y: float;
|
||||
}
|
||||
|
||||
generates the following Object-Based API class:
|
||||
|
||||
struct Vec2T : flatbuffers::NativeTable {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
However, it can be useful to instead use a user-defined C++ type since it
|
||||
can provide more functionality, eg.
|
||||
|
||||
struct vector2 {
|
||||
float x = 0, y = 0;
|
||||
vector2 operator+(vector2 rhs) const { ... }
|
||||
vector2 operator-(vector2 rhs) const { ... }
|
||||
float length() const { ... }
|
||||
// etc.
|
||||
};
|
||||
|
||||
The `native_type` attribute will replace the usage of the generated class
|
||||
with the given type. So, continuing with the example, the generated
|
||||
code would use |vector2| in place of |Vec2T| for all generated code.
|
||||
|
||||
However, becuase the native_type is unknown to flatbuffers, the user must
|
||||
provide the following functions to aide in the serialization process:
|
||||
|
||||
namespace flatbuffers {
|
||||
FlatbufferStruct Pack(const native_type& obj);
|
||||
native_type UnPack(const FlatbufferStruct& obj);
|
||||
}
|
||||
|
||||
Finally, the following top-level attribute
|
||||
|
||||
- native_include: "path" (at file level): Because the `native_type` attribute
|
||||
can be used to introduce types that are unknown to flatbuffers, it may be
|
||||
necessary to include "external" header files in the generated code. This
|
||||
attribute can be used to directly add an #include directive to the top of
|
||||
the generated code that includes the specified path directly.
|
||||
|
||||
# External references.
|
||||
|
||||
An additional feature of the object API is the ability to allow you to load
|
||||
|
||||
@@ -78,6 +78,9 @@ inefficiency, but also forces you to write *more* code to access data
|
||||
In this context, it is only a better choice for systems that have very
|
||||
little to no information ahead of time about what data needs to be stored.
|
||||
|
||||
If you do need to store data that doesn't fit a schema, FlatBuffers also
|
||||
offers a schema-less (self-describing) version!
|
||||
|
||||
Read more about the "why" of FlatBuffers in the
|
||||
[white paper](@ref flatbuffers_white_paper).
|
||||
|
||||
@@ -138,6 +141,8 @@ sections provide a more in-depth usage guide.
|
||||
using FlatBuffers.
|
||||
- A [white paper](@ref flatbuffers_white_paper) explaining the "why" of
|
||||
FlatBuffers.
|
||||
- How to use the [schema-less](@ref flexbuffers) version of
|
||||
FlatBuffers.
|
||||
- A description of the [internals](@ref flatbuffers_internals) of FlatBuffers.
|
||||
- A formal [grammar](@ref flatbuffers_grammar) of the schema language.
|
||||
|
||||
|
||||
156
docs/source/FlexBuffers.md
Normal file
156
docs/source/FlexBuffers.md
Normal file
@@ -0,0 +1,156 @@
|
||||
FlexBuffers {#flexbuffers}
|
||||
==========
|
||||
|
||||
FlatBuffers was designed around schemas, because when you want maximum
|
||||
performance and data consistency, strong typing is helpful.
|
||||
|
||||
There are however times when you want to store data that doesn't fit a
|
||||
schema, because you can't know ahead of time what all needs to be stored.
|
||||
|
||||
For this, FlatBuffers has a dedicated format, called FlexBuffers.
|
||||
This is a binary format that can be used in conjunction
|
||||
with FlatBuffers (by storing a part of a buffer in FlexBuffers
|
||||
format), or also as its own independent serialization format.
|
||||
|
||||
While it loses the strong typing, you retain the most unique advantage
|
||||
FlatBuffers has over other serialization formats (schema-based or not):
|
||||
FlexBuffers can also be accessed without parsing / copying / object allocation.
|
||||
This is a huge win in efficiency / memory friendly-ness, and allows unique
|
||||
use cases such as mmap-ing large amounts of free-form data.
|
||||
|
||||
FlexBuffers' design and implementation allows for a very compact encoding,
|
||||
combining automatic pooling of strings with automatic sizing of containers to
|
||||
their smallest possible representation (8/16/32/64 bits). Many values and
|
||||
offsets can be encoded in just 8 bits. While a schema-less representation is
|
||||
usually more bulky because of the need to be self-descriptive, FlexBuffers
|
||||
generates smaller binaries for many cases than regular FlatBuffers.
|
||||
|
||||
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.
|
||||
|
||||
Include the header `flexbuffers.h`, which in turn depends on `flatbuffers.h`
|
||||
and `util.h`.
|
||||
|
||||
To create a buffer:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
flexbuffers::Builder fbb;
|
||||
fbb.Int(13);
|
||||
fbb.Finish();
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You create any value, followed by `Finish`. Unlike FlatBuffers which requires
|
||||
the root value to be a table, here any value can be the root, including a lonely
|
||||
int value.
|
||||
|
||||
You can now access the `std::vector<uint8_t>` that contains the encoded value
|
||||
as `fbb.GetBuffer()`. Write it, send it, or store it in a parent FlatBuffer. In
|
||||
this case, the buffer is just 3 bytes in size.
|
||||
|
||||
To read this value back, you could just say:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
auto root = flexbuffers::GetRoot(my_buffer);
|
||||
int64_t i = root.AsInt64();
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
FlexBuffers stores ints only as big as needed, so it doesn't differentiate
|
||||
between different sizes of ints. You can ask for the 64 bit version,
|
||||
regardless of what you put in. In fact, since you demand to read the root
|
||||
as an int, if you supply a buffer that actually contains a float, or a
|
||||
string with numbers in it, it will convert it for you on the fly as well,
|
||||
or return 0 if it can't. If instead you actually want to know what is inside
|
||||
the buffer before you access it, you can call `root.GetType()` or `root.IsInt()`
|
||||
etc.
|
||||
|
||||
Here's a slightly more complex value you could write instead of `fbb.Int` above:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
fbb.Map([&]() {
|
||||
fbb.Vector("vec", [&]() {
|
||||
fbb.Int(-100);
|
||||
fbb.String("Fred");
|
||||
fbb.IndirectFloat(4.0f);
|
||||
});
|
||||
fbb.UInt("foo", 100);
|
||||
});
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This stores the equivalent of the JSON value
|
||||
`{ vec: [ -100, "Fred", 4.0 ], foo: 100 }`. The root is a dictionary that has
|
||||
just two key-value pairs, with keys `vec` and `foo`. Unlike FlatBuffers, it
|
||||
actually has to store these keys in the buffer (which it does only once if
|
||||
you store multiple such objects, by pooling key values), but also unlike
|
||||
FlatBuffers it has no restriction on the keys (fields) that you use.
|
||||
|
||||
The map constructor uses a C++11 Lambda to group its children, but you can
|
||||
also use more conventional start/end calls if you prefer.
|
||||
|
||||
The first value in the map is a vector. You'll notice that unlike FlatBuffers,
|
||||
you can use mixed types. There is also a `TypedVector` variant that only
|
||||
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.
|
||||
|
||||
Accessing it:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
auto map = flexbuffers::GetRoot(my_buffer).AsMap();
|
||||
map.size(); // 2
|
||||
auto vec = map["vec"].AsVector();
|
||||
vec.size(); // 3
|
||||
vec[0].AsInt64(); // -100;
|
||||
vec[1].AsString().c_str(); // "Fred";
|
||||
vec[1].AsInt64(); // 0 (Number parsing failed).
|
||||
vec[2].AsDouble(); // 4.0
|
||||
vec[2].AsString().IsTheEmptyString(); // true (Wrong Type).
|
||||
vec[2].AsString().c_str(); // "" (This still works though).
|
||||
vec[2].ToString().c_str(); // "4" (Or have it converted).
|
||||
map["foo"].AsUInt8(); // 100
|
||||
map["unknown"].IsNull(); // true
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
# Binary encoding
|
||||
|
||||
A description of how FlexBuffers are encoded is in the
|
||||
[internals](@ref flatbuffers_internals) document.
|
||||
|
||||
|
||||
# Efficiency tips
|
||||
|
||||
* Vectors generally are a lot more efficient than maps, so prefer them over maps
|
||||
when possible for small objects. Instead of a map with keys `x`, `y` and `z`,
|
||||
use a vector. Better yet, use a typed vector. Or even better, use a fixed
|
||||
size typed vector.
|
||||
* Maps are backwards compatible with vectors, and can be iterated as such.
|
||||
You can iterate either just the values (`map.Values()`), or in parallel with
|
||||
the keys vector (`map.Keys()`). If you intend
|
||||
to access most or all elements, this is faster than looking up each element
|
||||
by key, since that involves a binary search of the key vector.
|
||||
* When possible, don't mix values that require a big bit width (such as double)
|
||||
in a large vector of smaller values, since all elements will take on this
|
||||
width. Use `IndirectDouble` when this is a possibility. Note that
|
||||
integers automatically use the smallest width possible, i.e. if you ask
|
||||
to serialize an int64_t whose value is actually small, you will use less
|
||||
bits. Doubles are represented as floats whenever possible losslessly, but
|
||||
this is only possible for few values.
|
||||
Since nested vectors/maps are stored over offsets, they typically don't
|
||||
affect the vector width.
|
||||
* To store large arrays of byte data, use a blob. If you'd use a typed
|
||||
vector, the bit width of the size field may make it use more space than
|
||||
expected, and may not be compatible with `memcpy`.
|
||||
Similarly, large arrays of (u)int16_t may be better off stored as a
|
||||
binary blob if their size could exceed 64k elements.
|
||||
Construction and use are otherwise similar to strings.
|
||||
@@ -292,4 +292,148 @@ flexibility in which of the children of root object to write first (though in
|
||||
this case there's only one string), and what order to write the fields in.
|
||||
Different orders may also cause different alignments to happen.
|
||||
|
||||
# FlexBuffers
|
||||
|
||||
The [schema-less](@ref flexbuffers) version of FlatBuffers have their
|
||||
own encoding, detailed here.
|
||||
|
||||
It shares many properties mentioned above, in that all data is accessed
|
||||
over offsets, all scalars are aligned to their own size, and
|
||||
all data is always stored in little endian format.
|
||||
|
||||
One difference is that FlexBuffers are built front to back, so children are
|
||||
stored before parents, and the root of the data starts at the last byte.
|
||||
|
||||
Another difference is that scalar data is stored with a variable number of bits
|
||||
(8/16/32/64). The current width is always determined by the *parent*, i.e. if
|
||||
the scalar sits in a vector, the vector determines the bit width for all
|
||||
elements at once. Selecting the minimum bit width for a particular vector is
|
||||
something the encoder does automatically and thus is typically of no concern
|
||||
to the user, though being aware of this feature (and not sticking a double in
|
||||
the same vector as a bunch of byte sized elements) is helpful for efficiency.
|
||||
|
||||
Unlike FlatBuffers there is only one kind of offset, and that is an unsigned
|
||||
integer indicating the number of bytes in a negative direction from the address
|
||||
of itself (where the offset is stored).
|
||||
|
||||
### Vectors
|
||||
|
||||
The representation of the vector is at the core of how FlexBuffers works (since
|
||||
maps are really just a combination of 2 vectors), so it is worth starting there.
|
||||
|
||||
As mentioned, a vector is governed by a single bit width (supplied by its
|
||||
parent). This includes the size field. For example, a vector that stores the
|
||||
integer values `1, 2, 3` is encoded as follows:
|
||||
|
||||
uint8_t 3, 1, 2, 3, 4, 4, 4
|
||||
|
||||
The first `3` is the size field, and is placed before the vector (an offset
|
||||
from the parent to this vector points to the first element, not the size
|
||||
field, so the size field is effectively at index -1).
|
||||
Since this is an untyped vector `SL_VECTOR`, it is followed by 3 type
|
||||
bytes (one per element of the vector), which are always following the vector,
|
||||
and are always a uint8_t even if the vector is made up of bigger scalars.
|
||||
|
||||
### Types
|
||||
|
||||
A type byte is made up of 2 components (see flexbuffers.h for exact values):
|
||||
|
||||
* 2 lower bits representing the bit-width of the child (8, 16, 32, 64).
|
||||
This is only used if the child is accessed over an offset, such as a child
|
||||
vector. It is ignored for inline types.
|
||||
* 6 bits representing the actual type (see flexbuffers.h).
|
||||
|
||||
Thus, in this example `4` means 8 bit child (value 0, unused, since the value is
|
||||
in-line), type `SL_INT` (value 1).
|
||||
|
||||
### Typed Vectors
|
||||
|
||||
These are like the Vectors above, but omit the type bytes. The type is instead
|
||||
determined by the vector type supplied by the parent. Typed vectors are only
|
||||
available for a subset of types for which these savings can be significant,
|
||||
namely inline signed/unsigned integers (`TYPE_VECTOR_INT` / `TYPE_VECTOR_UINT`),
|
||||
floats (`TYPE_VECTOR_FLOAT`), and keys (`TYPE_VECTOR_KEY`, see below).
|
||||
|
||||
Additionally, for scalars, there are fixed length vectors of sizes 2 / 3 / 4
|
||||
that don't store the size (`TYPE_VECTOR_INT2` etc.), for an additional savings
|
||||
in space when storing common vector or color data.
|
||||
|
||||
### Scalars
|
||||
|
||||
FlexBuffers supports integers (`TYPE_INT` and `TYPE_UINT`) and floats
|
||||
(`TYPE_FLOAT`), available in the bit-widths mentioned above. They can be stored
|
||||
both inline and over an offset (`TYPE_INDIRECT_*`).
|
||||
|
||||
The offset version is useful to encode costly 64bit (or even 32bit) quantities
|
||||
into vectors / maps of smaller sizes, and to share / repeat a value multiple
|
||||
times.
|
||||
|
||||
### Blobs, Strings and Keys.
|
||||
|
||||
A blob (`TYPE_BLOB`) is encoded similar to a vector, with one difference: the
|
||||
elements are always `uint8_t`. The parent bit width only determines the width of
|
||||
the size field, allowing blobs to be large without the elements being large.
|
||||
|
||||
Strings (`TYPE_STRING`) are similar to blobs, except they have an additional 0
|
||||
termination byte for convenience, and they MUST be UTF-8 encoded (since an
|
||||
accessor in a language that does not support pointers to UTF-8 data may have to
|
||||
convert them to a native string type).
|
||||
|
||||
A "Key" (`TYPE_KEY`) is similar to a string, but doesn't store the size
|
||||
field. They're so named because they are used with maps, which don't care
|
||||
for the size, and can thus be even more compact. Unlike strings, keys cannot
|
||||
contain bytes of value 0 as part of their data (size can only be determined by
|
||||
`strlen`), so while you can use them outside the context of maps if you so
|
||||
desire, you're usually better off with strings.
|
||||
|
||||
### Maps
|
||||
|
||||
A map (`TYPE_MAP`) is like an (untyped) vector, but with 2 prefixes before the
|
||||
size field:
|
||||
|
||||
| index | field |
|
||||
| ----: | :----------------------------------------------------------- |
|
||||
| -3 | An offset to the keys vector (may be shared between tables). |
|
||||
| -2 | Byte width of the keys vector. |
|
||||
| -1 | Size (from here on it is compatible with `TYPE_VECTOR`) |
|
||||
| 0 | Elements. |
|
||||
| Size | Types. |
|
||||
|
||||
Since a map is otherwise the same as a vector, it can be iterated like
|
||||
a vector (which is probably faster than lookup by key).
|
||||
|
||||
The keys vector is a typed vector of keys. Both the keys and corresponding
|
||||
values *have* to be stored in sorted order (as determined by `strcmp`), such
|
||||
that lookups can be made using binary search.
|
||||
|
||||
The reason the key vector is a seperate structure from the value vector is
|
||||
such that it can be shared between multiple value vectors, and also to
|
||||
allow it to be treated as its own indivual vector in code.
|
||||
|
||||
An example map { foo: 13, bar: 14 } would be encoded as:
|
||||
|
||||
0 : uint8_t 'f', 'o', 'o', 0
|
||||
4 : uint8_t 'b', 'a', 'r', 0
|
||||
8 : uint8_t 2 // key vector of size 2
|
||||
// key vector offset points here
|
||||
9 : uint8_t 9, 6 // offsets to foo_key and bar_key
|
||||
11: uint8_t 3, 1 // offset to key vector, and its byte width
|
||||
13: uint8_t 2 // value vector of size
|
||||
// value vector offset points here
|
||||
14: uint8_t 13, 14 // values
|
||||
16: uint8_t 4, 4 // types
|
||||
|
||||
### The root
|
||||
|
||||
As mentioned, the root starts at the end of the buffer.
|
||||
The last uint8_t is the width in bytes of the root (normally the parent
|
||||
determines the width, but the root has no parent). The uint8_t before this is
|
||||
the type of the root, and the bytes before that are the root value (of the
|
||||
number of bytes specified by the last byte).
|
||||
|
||||
So for example, the integer value `13` as root would be:
|
||||
|
||||
uint8_t 13, 4, 1 // Value, type, root byte width.
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
@@ -158,6 +158,10 @@ If you have a need to distinguish between different FlatBuffers in a more
|
||||
open-ended way, for example for use as files, see the file identification
|
||||
feature below.
|
||||
|
||||
There is an experimental support only in C++ for a vector of unions
|
||||
(and types). In the example IDL file above, use [Any] to add a
|
||||
vector of Any to Monster table.
|
||||
|
||||
### Namespaces
|
||||
|
||||
These will generate the corresponding namespace in C++ for all helper
|
||||
@@ -309,6 +313,10 @@ Current understood attributes:
|
||||
to be stored in any particular order, they are often optimized for
|
||||
space by sorting them to size. This attribute stops that from happening.
|
||||
There should generally not be any reason to use this flag.
|
||||
- 'native_*'. Several attributes have been added to support the [C++ object
|
||||
Based API](@ref flatbuffers_cpp_object_based_api). All such attributes
|
||||
are prefixed with the term "native_".
|
||||
|
||||
|
||||
## JSON Parsing
|
||||
|
||||
|
||||
@@ -759,6 +759,7 @@ INPUT = "FlatBuffers.md" \
|
||||
"Support.md" \
|
||||
"Benchmarks.md" \
|
||||
"WhitePaper.md" \
|
||||
"FlexBuffers.md" \
|
||||
"Internals.md" \
|
||||
"Grammar.md" \
|
||||
"../../CONTRIBUTING.md" \
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
title="Use in PHP"/>
|
||||
<tab type="user" url="@ref flatbuffers_guide_use_python"
|
||||
title="Use in Python"/>
|
||||
<tab type="user" url="@ref flexbuffers"
|
||||
title="Schema-less version"/>
|
||||
</tab>
|
||||
<tab type="user" url="@ref flatbuffers_support"
|
||||
title="Platform / Language / Feature support"/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package flatbuffers
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -10,7 +10,7 @@ type Table struct {
|
||||
|
||||
// Offset provides access into the Table's vtable.
|
||||
//
|
||||
// Deprecated fields are ignored by checking against the vtable's length.
|
||||
// Fields which are deprecated are ignored by checking against the vtable's length.
|
||||
func (t *Table) Offset(vtableOffset VOffsetT) VOffsetT {
|
||||
vtable := UOffsetT(SOffsetT(t.Pos) - t.GetSOffsetT(t.Pos))
|
||||
if vtableOffset < t.GetVOffsetT(vtable) {
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace grpc_go_generator {
|
||||
grpc::string unexportName(grpc::string s) {
|
||||
if (s.empty())
|
||||
return s;
|
||||
s[0] = std::tolower(s[0]);
|
||||
s[0] = static_cast<char>(std::tolower(s[0]));
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ grpc::string unexportName(grpc::string s) {
|
||||
grpc::string exportName(grpc::string s) {
|
||||
if (s.empty())
|
||||
return s;
|
||||
s[0] = std::toupper(s[0]);
|
||||
s[0] = static_cast<char>(std::toupper(s[0]));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,25 +17,63 @@
|
||||
#ifndef FLATBUFFERS_CODE_GENERATORS_H_
|
||||
#define FLATBUFFERS_CODE_GENERATORS_H_
|
||||
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include "flatbuffers/idl.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// Utility class to assist in generating code through use of text templates.
|
||||
//
|
||||
// Example code:
|
||||
// CodeWriter code;
|
||||
// code.SetValue("NAME", "Foo");
|
||||
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
|
||||
// code.SetValue("NAME", "Bar");
|
||||
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
|
||||
// std::cout << code.ToString() << std::endl;
|
||||
//
|
||||
// Output:
|
||||
// void Foo() { printf("%s", "Foo"); }
|
||||
// void Bar() { printf("%s", "Bar"); }
|
||||
class CodeWriter {
|
||||
public:
|
||||
CodeWriter() {}
|
||||
|
||||
// Clears the current "written" code.
|
||||
void Clear() {
|
||||
stream_.str("");
|
||||
stream_.clear();
|
||||
}
|
||||
|
||||
// Associates a key with a value. All subsequent calls to operator+=, where
|
||||
// the specified key is contained in {{ and }} delimiters will be replaced by
|
||||
// the given value.
|
||||
void SetValue(const std::string& key, const std::string& value) {
|
||||
value_map_[key] = value;
|
||||
}
|
||||
|
||||
// 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
|
||||
// will be suppressed if the text ends with the \\ character.
|
||||
void operator+=(std::string text);
|
||||
|
||||
// Returns the current contents of the CodeWriter as a std::string.
|
||||
std::string ToString() const { return stream_.str(); }
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> value_map_;
|
||||
std::stringstream stream_;
|
||||
};
|
||||
|
||||
class BaseGenerator {
|
||||
public:
|
||||
virtual bool generate() = 0;
|
||||
|
||||
static const std::string NamespaceDir(const Parser &parser,
|
||||
const std::string &path,
|
||||
const Namespace &ns) {
|
||||
EnsureDirExists(path.c_str());
|
||||
if (parser.opts.one_file) return path;
|
||||
std::string namespace_dir = path; // Either empty or ends in separator.
|
||||
auto &namespaces = ns.components;
|
||||
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
||||
namespace_dir += *it + kPathSeparator;
|
||||
EnsureDirExists(namespace_dir.c_str());
|
||||
}
|
||||
return namespace_dir;
|
||||
}
|
||||
static std::string NamespaceDir(const Parser &parser,
|
||||
const std::string &path,
|
||||
const Namespace &ns);
|
||||
|
||||
protected:
|
||||
BaseGenerator(const Parser &parser, const std::string &path,
|
||||
@@ -46,71 +84,35 @@ class BaseGenerator {
|
||||
path_(path),
|
||||
file_name_(file_name),
|
||||
qualifying_start_(qualifying_start),
|
||||
qualifying_separator_(qualifying_separator){};
|
||||
virtual ~BaseGenerator(){};
|
||||
qualifying_separator_(qualifying_separator) {}
|
||||
virtual ~BaseGenerator() {}
|
||||
|
||||
// No copy/assign.
|
||||
BaseGenerator &operator=(const BaseGenerator &);
|
||||
BaseGenerator(const BaseGenerator &);
|
||||
|
||||
const std::string NamespaceDir(const Namespace &ns) {
|
||||
return BaseGenerator::NamespaceDir(parser_, path_, ns);
|
||||
}
|
||||
std::string NamespaceDir(const Namespace &ns) const;
|
||||
|
||||
const char *FlatBuffersGeneratedWarning() {
|
||||
return "automatically generated by the FlatBuffers compiler,"
|
||||
" do not modify\n\n";
|
||||
}
|
||||
static const char *FlatBuffersGeneratedWarning();
|
||||
|
||||
bool IsEverythingGenerated() {
|
||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||
++it) {
|
||||
if (!(*it)->generated) return false;
|
||||
}
|
||||
for (auto it = parser_.structs_.vec.begin();
|
||||
it != parser_.structs_.vec.end(); ++it) {
|
||||
if (!(*it)->generated) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool IsEverythingGenerated() const;
|
||||
|
||||
std::string FullNamespace(const char *separator, const Namespace &ns) {
|
||||
std::string namespace_name;
|
||||
auto &namespaces = ns.components;
|
||||
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
||||
if (namespace_name.length()) namespace_name += separator;
|
||||
namespace_name += *it;
|
||||
}
|
||||
return namespace_name;
|
||||
}
|
||||
static std::string FullNamespace(const char *separator, const Namespace &ns);
|
||||
|
||||
const std::string LastNamespacePart(const Namespace &ns) {
|
||||
auto &namespaces = ns.components;
|
||||
if (namespaces.size())
|
||||
return *(namespaces.end() - 1);
|
||||
else
|
||||
return std::string("");
|
||||
}
|
||||
static std::string LastNamespacePart(const Namespace &ns);
|
||||
|
||||
// tracks the current namespace for early exit in WrapInNameSpace
|
||||
// c++, java and csharp returns a different namespace from
|
||||
// the following default (no early exit, always fully qualify),
|
||||
// which works for js and php
|
||||
virtual const Namespace *CurrentNameSpace() { return nullptr; }
|
||||
virtual const Namespace *CurrentNameSpace() const { return nullptr; }
|
||||
|
||||
// Ensure that a type is prefixed with its namespace whenever it is used
|
||||
// outside of its namespace.
|
||||
std::string WrapInNameSpace(const Namespace *ns, const std::string &name) {
|
||||
if (CurrentNameSpace() == ns) return name;
|
||||
std::string qualified_name = qualifying_start_;
|
||||
for (auto it = ns->components.begin(); it != ns->components.end(); ++it)
|
||||
qualified_name += *it + qualifying_separator_;
|
||||
return qualified_name + name;
|
||||
}
|
||||
std::string WrapInNameSpace(const Namespace *ns,
|
||||
const std::string &name) const;
|
||||
|
||||
std::string WrapInNameSpace(const Definition &def) {
|
||||
return WrapInNameSpace(def.defined_namespace, def.name);
|
||||
}
|
||||
std::string WrapInNameSpace(const Definition &def) const;
|
||||
|
||||
const Parser &parser_;
|
||||
const std::string &path_;
|
||||
@@ -119,6 +121,17 @@ class BaseGenerator {
|
||||
const std::string qualifying_separator_;
|
||||
};
|
||||
|
||||
struct CommentConfig {
|
||||
const char *first_line;
|
||||
const char *content_line_prefix;
|
||||
const char *last_line;
|
||||
};
|
||||
|
||||
extern void GenComment(const std::vector<std::string> &dc,
|
||||
std::string *code_ptr,
|
||||
const CommentConfig *config,
|
||||
const char *prefix = "");
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_CODE_GENERATORS_H_
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||
|
||||
#define FLATBUFFERS_VERSION_MAJOR 1
|
||||
#define FLATBUFFERS_VERSION_MINOR 5
|
||||
#define FLATBUFFERS_VERSION_MINOR 6
|
||||
#define FLATBUFFERS_VERSION_REVISION 0
|
||||
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
||||
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
||||
@@ -496,12 +496,11 @@ class vector_downward {
|
||||
public:
|
||||
explicit vector_downward(size_t initial_size,
|
||||
const simple_allocator &allocator)
|
||||
: reserved_(initial_size),
|
||||
: reserved_((initial_size + sizeof(largest_scalar_t) - 1) &
|
||||
~(sizeof(largest_scalar_t) - 1)),
|
||||
buf_(allocator.allocate(reserved_)),
|
||||
cur_(buf_ + reserved_),
|
||||
allocator_(allocator) {
|
||||
assert((initial_size & (sizeof(largest_scalar_t) - 1)) == 0);
|
||||
}
|
||||
allocator_(allocator) {}
|
||||
|
||||
~vector_downward() {
|
||||
if (buf_)
|
||||
@@ -539,17 +538,7 @@ class vector_downward {
|
||||
|
||||
uint8_t *make_space(size_t len) {
|
||||
if (len > static_cast<size_t>(cur_ - buf_)) {
|
||||
auto old_size = size();
|
||||
auto largest_align = AlignOf<largest_scalar_t>();
|
||||
reserved_ += (std::max)(len, growth_policy(reserved_));
|
||||
// Round up to avoid undefined behavior from unaligned loads and stores.
|
||||
reserved_ = (reserved_ + (largest_align - 1)) & ~(largest_align - 1);
|
||||
auto new_buf = allocator_.allocate(reserved_);
|
||||
auto new_cur = new_buf + reserved_ - old_size;
|
||||
memcpy(new_cur, cur_, old_size);
|
||||
cur_ = new_cur;
|
||||
allocator_.deallocate(buf_);
|
||||
buf_ = new_buf;
|
||||
reallocate(len);
|
||||
}
|
||||
cur_ -= len;
|
||||
// Beyond this, signed offsets may not have enough range:
|
||||
@@ -570,18 +559,30 @@ class vector_downward {
|
||||
|
||||
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
|
||||
|
||||
// push() & fill() are most frequently called with small byte counts (<= 4),
|
||||
// which is why we're using loops rather than calling memcpy/memset.
|
||||
void push(const uint8_t *bytes, size_t num) {
|
||||
auto dest = make_space(num);
|
||||
for (size_t i = 0; i < num; i++) dest[i] = bytes[i];
|
||||
memcpy(dest, bytes, num);
|
||||
}
|
||||
|
||||
// Specialized version of push() that avoids memcpy call for small data.
|
||||
template<typename T> void push_small(T little_endian_t) {
|
||||
auto dest = make_space(sizeof(T));
|
||||
*reinterpret_cast<T *>(dest) = little_endian_t;
|
||||
}
|
||||
|
||||
// fill() is most frequently called with small byte counts (<= 4),
|
||||
// which is why we're using loops rather than calling memset.
|
||||
void fill(size_t zero_pad_bytes) {
|
||||
auto dest = make_space(zero_pad_bytes);
|
||||
for (size_t i = 0; i < zero_pad_bytes; i++) dest[i] = 0;
|
||||
}
|
||||
|
||||
// Version for when we know the size is larger.
|
||||
void fill_big(size_t zero_pad_bytes) {
|
||||
auto dest = make_space(zero_pad_bytes);
|
||||
memset(dest, 0, zero_pad_bytes);
|
||||
}
|
||||
|
||||
void pop(size_t bytes_to_remove) { cur_ += bytes_to_remove; }
|
||||
|
||||
private:
|
||||
@@ -593,6 +594,20 @@ class vector_downward {
|
||||
uint8_t *buf_;
|
||||
uint8_t *cur_; // Points at location between empty (below) and used (above).
|
||||
const simple_allocator &allocator_;
|
||||
|
||||
void reallocate(size_t len) {
|
||||
auto old_size = size();
|
||||
auto largest_align = AlignOf<largest_scalar_t>();
|
||||
reserved_ += (std::max)(len, growth_policy(reserved_));
|
||||
// Round up to avoid undefined behavior from unaligned loads and stores.
|
||||
reserved_ = (reserved_ + (largest_align - 1)) & ~(largest_align - 1);
|
||||
auto new_buf = allocator_.allocate(reserved_);
|
||||
auto new_cur = new_buf + reserved_ - old_size;
|
||||
memcpy(new_cur, cur_, old_size);
|
||||
cur_ = new_cur;
|
||||
allocator_.deallocate(buf_);
|
||||
buf_ = new_buf;
|
||||
}
|
||||
};
|
||||
|
||||
// Converts a Field ID to a virtual table offset.
|
||||
@@ -643,7 +658,7 @@ FLATBUFFERS_FINAL_CLASS
|
||||
const simple_allocator *allocator = nullptr)
|
||||
: buf_(initial_size, allocator ? *allocator : default_allocator),
|
||||
nested(false), finished(false), minalign_(1), force_defaults_(false),
|
||||
string_pool(nullptr) {
|
||||
dedup_vtables_(true), string_pool(nullptr) {
|
||||
offsetbuf_.reserve(16); // Avoid first few reallocs.
|
||||
vtables_.reserve(16);
|
||||
EndianCheck();
|
||||
@@ -720,6 +735,10 @@ FLATBUFFERS_FINAL_CLASS
|
||||
/// @param[in] bool fd When set to `true`, always serializes default values.
|
||||
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.
|
||||
void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
|
||||
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
void Pad(size_t num_bytes) { buf_.fill(num_bytes); }
|
||||
|
||||
@@ -754,7 +773,7 @@ FLATBUFFERS_FINAL_CLASS
|
||||
AssertScalarT<T>();
|
||||
T litle_endian_element = EndianScalar(element);
|
||||
Align(sizeof(T));
|
||||
PushBytes(reinterpret_cast<uint8_t *>(&litle_endian_element), sizeof(T));
|
||||
buf_.push_small(litle_endian_element);
|
||||
return GetSize();
|
||||
}
|
||||
|
||||
@@ -786,7 +805,7 @@ FLATBUFFERS_FINAL_CLASS
|
||||
template<typename T> void AddStruct(voffset_t field, const T *structptr) {
|
||||
if (!structptr) return; // Default, don't store.
|
||||
Align(AlignOf<T>());
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(structptr), sizeof(T));
|
||||
buf_.push_small(*structptr);
|
||||
TrackField(field, GetSize());
|
||||
}
|
||||
|
||||
@@ -837,7 +856,7 @@ FLATBUFFERS_FINAL_CLASS
|
||||
// Write a vtable, which consists entirely of voffset_t elements.
|
||||
// It starts with the number of offsets, followed by a type id, followed
|
||||
// by the offsets themselves. In reverse:
|
||||
buf_.fill(numfields * sizeof(voffset_t));
|
||||
buf_.fill_big(numfields * sizeof(voffset_t));
|
||||
auto table_object_size = vtableoffsetloc - start;
|
||||
assert(table_object_size < 0x10000); // Vtable use 16bit offsets.
|
||||
PushElement<voffset_t>(static_cast<voffset_t>(table_object_size));
|
||||
@@ -857,13 +876,15 @@ FLATBUFFERS_FINAL_CLASS
|
||||
auto vt_use = GetSize();
|
||||
// See if we already have generated a vtable with this exact same
|
||||
// layout before. If so, make it point to the old one, remove this one.
|
||||
for (auto it = vtables_.begin(); it != vtables_.end(); ++it) {
|
||||
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*it));
|
||||
auto vt2_size = *vt2;
|
||||
if (vt1_size != vt2_size || memcmp(vt2, vt1, vt1_size)) continue;
|
||||
vt_use = *it;
|
||||
buf_.pop(GetSize() - vtableoffsetloc);
|
||||
break;
|
||||
if (dedup_vtables_) {
|
||||
for (auto it = vtables_.begin(); it != vtables_.end(); ++it) {
|
||||
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*it));
|
||||
auto vt2_size = *vt2;
|
||||
if (vt1_size != vt2_size || memcmp(vt2, vt1, vt1_size)) continue;
|
||||
vt_use = *it;
|
||||
buf_.pop(GetSize() - vtableoffsetloc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If this is a new vtable, remember it.
|
||||
if (vt_use == GetSize()) {
|
||||
@@ -1106,6 +1127,27 @@ FLATBUFFERS_FINAL_CLASS
|
||||
return Offset<Vector<const T *>>(EndVector(len));
|
||||
}
|
||||
|
||||
#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
|
||||
/// 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.
|
||||
/// This is mostly useful when flatbuffers are generated with mutation
|
||||
/// accessors.
|
||||
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
|
||||
size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
|
||||
StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>());
|
||||
T *structs = reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
|
||||
for (size_t i = 0; i < vector_size; i++) {
|
||||
filler(i, structs);
|
||||
structs++;
|
||||
}
|
||||
return Offset<Vector<const T *>>(EndVector(vector_size));
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @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
|
||||
@@ -1229,7 +1271,7 @@ FLATBUFFERS_FINAL_CLASS
|
||||
minalign_);
|
||||
if (file_identifier) {
|
||||
assert(strlen(file_identifier) == kFileIdentifierLength);
|
||||
buf_.push(reinterpret_cast<const uint8_t *>(file_identifier),
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
|
||||
kFileIdentifierLength);
|
||||
}
|
||||
PushElement(ReferTo(root)); // Location of root.
|
||||
@@ -1263,6 +1305,8 @@ FLATBUFFERS_FINAL_CLASS
|
||||
|
||||
bool force_defaults_; // Serialize values equal to their defaults anyway.
|
||||
|
||||
bool dedup_vtables_;
|
||||
|
||||
struct StringOffsetCompare {
|
||||
StringOffsetCompare(const vector_downward &buf) : buf_(&buf) {}
|
||||
bool operator() (const Offset<String> &a, const Offset<String> &b) const {
|
||||
|
||||
96
include/flatbuffers/flatc.h
Normal file
96
include/flatbuffers/flatc.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#ifndef FLATC_H_
|
||||
#define FLATC_H_
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
class FlatCompiler {
|
||||
public:
|
||||
// Output generator for the various programming languages and formats we
|
||||
// support.
|
||||
struct Generator {
|
||||
typedef bool (*GenerateFn)(const flatbuffers::Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
typedef std::string (*MakeRuleFn)(const flatbuffers::Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
GenerateFn generate;
|
||||
const char *generator_opt_short;
|
||||
const char *generator_opt_long;
|
||||
const char *lang_name;
|
||||
GenerateFn generateGRPC;
|
||||
flatbuffers::IDLOptions::Language lang;
|
||||
const char *generator_help;
|
||||
MakeRuleFn make_rule;
|
||||
};
|
||||
|
||||
typedef void (*WarnFn)(const FlatCompiler *flatc,
|
||||
const std::string &warn,
|
||||
bool show_exe_name);
|
||||
|
||||
typedef void (*ErrorFn)(const FlatCompiler *flatc,
|
||||
const std::string &err,
|
||||
bool usage, bool show_exe_name);
|
||||
|
||||
// Parameters required to initialize the FlatCompiler.
|
||||
struct InitParams {
|
||||
InitParams()
|
||||
: generators(nullptr),
|
||||
num_generators(0),
|
||||
warn_fn(nullptr),
|
||||
error_fn(nullptr) {}
|
||||
|
||||
const Generator* generators;
|
||||
size_t num_generators;
|
||||
WarnFn warn_fn;
|
||||
ErrorFn error_fn;
|
||||
};
|
||||
|
||||
explicit FlatCompiler(const InitParams& params) : params_(params) {}
|
||||
|
||||
int Compile(int argc, const char** argv);
|
||||
|
||||
std::string GetUsageString(const char* program_name) const;
|
||||
|
||||
private:
|
||||
void ParseFile(flatbuffers::Parser &parser,
|
||||
const std::string &filename,
|
||||
const std::string &contents,
|
||||
std::vector<const char *> &include_directories) const;
|
||||
|
||||
void Warn(const std::string &warn, bool show_exe_name = true) const;
|
||||
|
||||
void Error(const std::string &err, bool usage = true,
|
||||
bool show_exe_name = true) const;
|
||||
|
||||
InitParams params_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATC_H_
|
||||
1341
include/flatbuffers/flexbuffers.h
Normal file
1341
include/flatbuffers/flexbuffers.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -43,9 +43,7 @@ class SerializationTraits<T, typename std::enable_if<std::is_base_of<
|
||||
|
||||
// There is no de-serialization step in FlatBuffers, so we just receive
|
||||
// the data from GRPC.
|
||||
static grpc::Status Deserialize(grpc_byte_buffer *buffer,
|
||||
T *msg,
|
||||
int max_message_size) {
|
||||
static grpc::Status Deserialize(grpc_byte_buffer *buffer, T *msg) {
|
||||
// TODO(wvo): make this more efficient / zero copy when possible.
|
||||
auto len = grpc_byte_buffer_length(buffer);
|
||||
msg->buf = reinterpret_cast<uint8_t *>(malloc(len));
|
||||
|
||||
@@ -337,6 +337,7 @@ struct ServiceDef : public Definition {
|
||||
struct IDLOptions {
|
||||
bool strict_json;
|
||||
bool skip_js_exports;
|
||||
bool use_goog_js_export_format;
|
||||
bool output_default_scalars_in_json;
|
||||
int indent_step;
|
||||
bool output_enum_identifiers;
|
||||
@@ -354,15 +355,33 @@ struct IDLOptions {
|
||||
std::string cpp_object_api_pointer_type;
|
||||
bool union_value_namespacing;
|
||||
bool allow_non_utf8;
|
||||
std::string include_prefix;
|
||||
bool binary_schema_comments;
|
||||
|
||||
// Possible options for the more general generator below.
|
||||
enum Language { kJava, kCSharp, kGo, kMAX };
|
||||
enum Language {
|
||||
kJava = 1 << 0,
|
||||
kCSharp = 1 << 1,
|
||||
kGo = 1 << 2,
|
||||
kCpp = 1 << 3,
|
||||
kJs = 1 << 4,
|
||||
kPython = 1 << 5,
|
||||
kPhp = 1 << 6,
|
||||
kJson = 1 << 7,
|
||||
kBinary = 1 << 8,
|
||||
kMAX
|
||||
};
|
||||
|
||||
Language lang;
|
||||
|
||||
// The corresponding language bit will be set if a language is included
|
||||
// for code generation.
|
||||
unsigned long lang_to_generate;
|
||||
|
||||
IDLOptions()
|
||||
: strict_json(false),
|
||||
skip_js_exports(false),
|
||||
use_goog_js_export_format(false),
|
||||
output_default_scalars_in_json(false),
|
||||
indent_step(2),
|
||||
output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false),
|
||||
@@ -378,7 +397,9 @@ struct IDLOptions {
|
||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||
union_value_namespacing(true),
|
||||
allow_non_utf8(false),
|
||||
lang(IDLOptions::kJava) {}
|
||||
binary_schema_comments(false),
|
||||
lang(IDLOptions::kJava),
|
||||
lang_to_generate(0) {}
|
||||
};
|
||||
|
||||
// This encapsulates where the parser is in the current source file.
|
||||
@@ -459,6 +480,8 @@ class Parser : public ParserState {
|
||||
known_attributes_["cpp_type"] = true;
|
||||
known_attributes_["cpp_ptr_type"] = true;
|
||||
known_attributes_["native_inline"] = true;
|
||||
known_attributes_["native_type"] = true;
|
||||
known_attributes_["native_default"] = true;
|
||||
}
|
||||
|
||||
~Parser() {
|
||||
@@ -502,7 +525,7 @@ class Parser : public ParserState {
|
||||
|
||||
private:
|
||||
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, int64_t *val);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val);
|
||||
FLATBUFFERS_CHECKED_ERROR Next();
|
||||
FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
|
||||
bool Is(int t);
|
||||
@@ -560,6 +583,7 @@ private:
|
||||
BaseType baseType);
|
||||
|
||||
public:
|
||||
SymbolTable<Type> types_;
|
||||
SymbolTable<StructDef> structs_;
|
||||
SymbolTable<EnumDef> enums_;
|
||||
SymbolTable<ServiceDef> services_;
|
||||
@@ -573,6 +597,7 @@ private:
|
||||
|
||||
std::map<std::string, bool> included_files_;
|
||||
std::map<std::string, std::set<std::string>> files_included_per_file_;
|
||||
std::vector<std::string> native_included_files_;
|
||||
|
||||
std::map<std::string, bool> known_attributes_;
|
||||
|
||||
@@ -592,13 +617,6 @@ private:
|
||||
|
||||
extern std::string MakeCamel(const std::string &in, bool first = true);
|
||||
|
||||
struct CommentConfig;
|
||||
|
||||
extern void GenComment(const std::vector<std::string> &dc,
|
||||
std::string *code_ptr,
|
||||
const CommentConfig *config,
|
||||
const char *prefix = "");
|
||||
|
||||
// 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,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
|
||||
#ifndef FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
|
||||
#define FLATBUFFERS_GENERATED_REFLECTION_REFLECTION_H_
|
||||
|
||||
@@ -42,11 +43,33 @@ enum BaseType {
|
||||
};
|
||||
|
||||
inline const char **EnumNamesBaseType() {
|
||||
static const char *names[] = { "None", "UType", "Bool", "Byte", "UByte", "Short", "UShort", "Int", "UInt", "Long", "ULong", "Float", "Double", "String", "Vector", "Obj", "Union", nullptr };
|
||||
static const char *names[] = {
|
||||
"None",
|
||||
"UType",
|
||||
"Bool",
|
||||
"Byte",
|
||||
"UByte",
|
||||
"Short",
|
||||
"UShort",
|
||||
"Int",
|
||||
"UInt",
|
||||
"Long",
|
||||
"ULong",
|
||||
"Float",
|
||||
"Double",
|
||||
"String",
|
||||
"Vector",
|
||||
"Obj",
|
||||
"Union",
|
||||
nullptr
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameBaseType(BaseType e) { return EnumNamesBaseType()[static_cast<int>(e)]; }
|
||||
inline const char *EnumNameBaseType(BaseType e) {
|
||||
const size_t index = static_cast<int>(e);
|
||||
return EnumNamesBaseType()[index];
|
||||
}
|
||||
|
||||
struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
@@ -54,9 +77,15 @@ struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_ELEMENT = 6,
|
||||
VT_INDEX = 8
|
||||
};
|
||||
BaseType base_type() const { return static_cast<BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0)); }
|
||||
BaseType element() const { return static_cast<BaseType>(GetField<int8_t>(VT_ELEMENT, 0)); }
|
||||
int32_t index() const { return GetField<int32_t>(VT_INDEX, -1); }
|
||||
BaseType base_type() const {
|
||||
return static_cast<BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
|
||||
}
|
||||
BaseType element() const {
|
||||
return static_cast<BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
|
||||
}
|
||||
int32_t index() const {
|
||||
return GetField<int32_t>(VT_INDEX, -1);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<int8_t>(verifier, VT_BASE_TYPE) &&
|
||||
@@ -69,18 +98,29 @@ struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct TypeBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_base_type(BaseType base_type) { fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0); }
|
||||
void add_element(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); }
|
||||
TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_base_type(BaseType base_type) {
|
||||
fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0);
|
||||
}
|
||||
void add_element(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);
|
||||
}
|
||||
TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
TypeBuilder &operator=(const TypeBuilder &);
|
||||
flatbuffers::Offset<Type> Finish() {
|
||||
auto o = flatbuffers::Offset<Type>(fbb_.EndTable(start_, 3));
|
||||
const auto end = fbb_.EndTable(start_, 3);
|
||||
auto o = flatbuffers::Offset<Type>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Type> CreateType(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Type> CreateType(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
BaseType base_type = None,
|
||||
BaseType element = None,
|
||||
int32_t index = -1) {
|
||||
@@ -96,10 +136,18 @@ struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_KEY = 4,
|
||||
VT_VALUE = 6
|
||||
};
|
||||
const flatbuffers::String *key() const { return GetPointer<const flatbuffers::String *>(VT_KEY); }
|
||||
bool KeyCompareLessThan(const KeyValue *o) const { return *key() < *o->key(); }
|
||||
int KeyCompareWithValue(const char *val) const { return strcmp(key()->c_str(), val); }
|
||||
const flatbuffers::String *value() const { return GetPointer<const flatbuffers::String *>(VT_VALUE); }
|
||||
const flatbuffers::String *key() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_KEY);
|
||||
}
|
||||
bool KeyCompareLessThan(const KeyValue *o) const {
|
||||
return *key() < *o->key();
|
||||
}
|
||||
int KeyCompareWithValue(const char *val) const {
|
||||
return strcmp(key()->c_str(), val);
|
||||
}
|
||||
const flatbuffers::String *value() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_VALUE);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyFieldRequired<flatbuffers::uoffset_t>(verifier, VT_KEY) &&
|
||||
@@ -113,18 +161,27 @@ struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct KeyValueBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_key(flatbuffers::Offset<flatbuffers::String> key) { fbb_.AddOffset(KeyValue::VT_KEY, key); }
|
||||
void add_value(flatbuffers::Offset<flatbuffers::String> value) { fbb_.AddOffset(KeyValue::VT_VALUE, value); }
|
||||
KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_key(flatbuffers::Offset<flatbuffers::String> key) {
|
||||
fbb_.AddOffset(KeyValue::VT_KEY, key);
|
||||
}
|
||||
void add_value(flatbuffers::Offset<flatbuffers::String> value) {
|
||||
fbb_.AddOffset(KeyValue::VT_VALUE, value);
|
||||
}
|
||||
KeyValueBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
KeyValueBuilder &operator=(const KeyValueBuilder &);
|
||||
flatbuffers::Offset<KeyValue> Finish() {
|
||||
auto o = flatbuffers::Offset<KeyValue>(fbb_.EndTable(start_, 2));
|
||||
fbb_.Required(o, KeyValue::VT_KEY); // key
|
||||
const auto end = fbb_.EndTable(start_, 2);
|
||||
auto o = flatbuffers::Offset<KeyValue>(end);
|
||||
fbb_.Required(o, KeyValue::VT_KEY);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<KeyValue> CreateKeyValue(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<KeyValue> CreateKeyValue(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::String> key = 0,
|
||||
flatbuffers::Offset<flatbuffers::String> value = 0) {
|
||||
KeyValueBuilder builder_(_fbb);
|
||||
@@ -133,10 +190,14 @@ inline flatbuffers::Offset<KeyValue> CreateKeyValue(flatbuffers::FlatBufferBuild
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const char *key = nullptr,
|
||||
const char *value = nullptr) {
|
||||
return CreateKeyValue(_fbb, key ? _fbb.CreateString(key) : 0, value ? _fbb.CreateString(value) : 0);
|
||||
return reflection::CreateKeyValue(
|
||||
_fbb,
|
||||
key ? _fbb.CreateString(key) : 0,
|
||||
value ? _fbb.CreateString(value) : 0);
|
||||
}
|
||||
|
||||
struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
@@ -145,11 +206,28 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_VALUE = 6,
|
||||
VT_OBJECT = 8
|
||||
};
|
||||
const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(VT_NAME); }
|
||||
int64_t value() const { return GetField<int64_t>(VT_VALUE, 0); }
|
||||
bool KeyCompareLessThan(const EnumVal *o) const { return value() < o->value(); }
|
||||
int KeyCompareWithValue(int64_t val) const { return value() < val ? -1 : value() > val; }
|
||||
const Object *object() const { return GetPointer<const Object *>(VT_OBJECT); }
|
||||
const flatbuffers::String *name() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_NAME);
|
||||
}
|
||||
int64_t value() const {
|
||||
return GetField<int64_t>(VT_VALUE, 0);
|
||||
}
|
||||
bool KeyCompareLessThan(const EnumVal *o) const {
|
||||
return value() < o->value();
|
||||
}
|
||||
int KeyCompareWithValue(int64_t val) const {
|
||||
const auto key = value();
|
||||
if (key < val) {
|
||||
return -1;
|
||||
} else if (key > val) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
const Object *object() const {
|
||||
return GetPointer<const Object *>(VT_OBJECT);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyFieldRequired<flatbuffers::uoffset_t>(verifier, VT_NAME) &&
|
||||
@@ -164,19 +242,30 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct EnumValBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) { fbb_.AddOffset(EnumVal::VT_NAME, name); }
|
||||
void add_value(int64_t value) { fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0); }
|
||||
void add_object(flatbuffers::Offset<Object> object) { fbb_.AddOffset(EnumVal::VT_OBJECT, object); }
|
||||
EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||
fbb_.AddOffset(EnumVal::VT_NAME, name);
|
||||
}
|
||||
void add_value(int64_t value) {
|
||||
fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0);
|
||||
}
|
||||
void add_object(flatbuffers::Offset<Object> object) {
|
||||
fbb_.AddOffset(EnumVal::VT_OBJECT, object);
|
||||
}
|
||||
EnumValBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
EnumValBuilder &operator=(const EnumValBuilder &);
|
||||
flatbuffers::Offset<EnumVal> Finish() {
|
||||
auto o = flatbuffers::Offset<EnumVal>(fbb_.EndTable(start_, 3));
|
||||
fbb_.Required(o, EnumVal::VT_NAME); // name
|
||||
const auto end = fbb_.EndTable(start_, 3);
|
||||
auto o = flatbuffers::Offset<EnumVal>(end);
|
||||
fbb_.Required(o, EnumVal::VT_NAME);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<EnumVal> CreateEnumVal(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<EnumVal> CreateEnumVal(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
int64_t value = 0,
|
||||
flatbuffers::Offset<Object> object = 0) {
|
||||
@@ -187,11 +276,16 @@ inline flatbuffers::Offset<EnumVal> CreateEnumVal(flatbuffers::FlatBufferBuilder
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const char *name = nullptr,
|
||||
int64_t value = 0,
|
||||
flatbuffers::Offset<Object> object = 0) {
|
||||
return CreateEnumVal(_fbb, name ? _fbb.CreateString(name) : 0, value, object);
|
||||
return reflection::CreateEnumVal(
|
||||
_fbb,
|
||||
name ? _fbb.CreateString(name) : 0,
|
||||
value,
|
||||
object);
|
||||
}
|
||||
|
||||
struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
@@ -200,15 +294,33 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_VALUES = 6,
|
||||
VT_IS_UNION = 8,
|
||||
VT_UNDERLYING_TYPE = 10,
|
||||
VT_ATTRIBUTES = 12
|
||||
VT_ATTRIBUTES = 12,
|
||||
VT_DOCUMENTATION = 14
|
||||
};
|
||||
const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(VT_NAME); }
|
||||
bool KeyCompareLessThan(const Enum *o) const { return *name() < *o->name(); }
|
||||
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); }
|
||||
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 flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES); }
|
||||
const flatbuffers::String *name() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_NAME);
|
||||
}
|
||||
bool KeyCompareLessThan(const Enum *o) const {
|
||||
return *name() < *o->name();
|
||||
}
|
||||
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);
|
||||
}
|
||||
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 flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
|
||||
}
|
||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyFieldRequired<flatbuffers::uoffset_t>(verifier, VT_NAME) &&
|
||||
@@ -222,6 +334,9 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_ATTRIBUTES) &&
|
||||
verifier.Verify(attributes()) &&
|
||||
verifier.VerifyVectorOfTables(attributes()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_DOCUMENTATION) &&
|
||||
verifier.Verify(documentation()) &&
|
||||
verifier.VerifyVectorOfStrings(documentation()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
@@ -229,29 +344,49 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct EnumBuilder {
|
||||
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) { 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) { fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type); }
|
||||
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) { fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes); }
|
||||
EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
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) {
|
||||
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) {
|
||||
fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type);
|
||||
}
|
||||
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
|
||||
fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes);
|
||||
}
|
||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||
fbb_.AddOffset(Enum::VT_DOCUMENTATION, documentation);
|
||||
}
|
||||
EnumBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
EnumBuilder &operator=(const EnumBuilder &);
|
||||
flatbuffers::Offset<Enum> Finish() {
|
||||
auto o = flatbuffers::Offset<Enum>(fbb_.EndTable(start_, 5));
|
||||
fbb_.Required(o, Enum::VT_NAME); // name
|
||||
fbb_.Required(o, Enum::VT_VALUES); // values
|
||||
fbb_.Required(o, Enum::VT_UNDERLYING_TYPE); // underlying_type
|
||||
const auto end = fbb_.EndTable(start_, 6);
|
||||
auto o = flatbuffers::Offset<Enum>(end);
|
||||
fbb_.Required(o, Enum::VT_NAME);
|
||||
fbb_.Required(o, Enum::VT_VALUES);
|
||||
fbb_.Required(o, Enum::VT_UNDERLYING_TYPE);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Enum> CreateEnum(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Enum> CreateEnum(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<EnumVal>>> values = 0,
|
||||
bool is_union = false,
|
||||
flatbuffers::Offset<Type> underlying_type = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0) {
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||
EnumBuilder builder_(_fbb);
|
||||
builder_.add_documentation(documentation);
|
||||
builder_.add_attributes(attributes);
|
||||
builder_.add_underlying_type(underlying_type);
|
||||
builder_.add_values(values);
|
||||
@@ -260,13 +395,22 @@ inline flatbuffers::Offset<Enum> CreateEnum(flatbuffers::FlatBufferBuilder &_fbb
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Enum> CreateEnumDirect(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Enum> CreateEnumDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const char *name = nullptr,
|
||||
const std::vector<flatbuffers::Offset<EnumVal>> *values = nullptr,
|
||||
bool is_union = false,
|
||||
flatbuffers::Offset<Type> underlying_type = 0,
|
||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr) {
|
||||
return CreateEnum(_fbb, name ? _fbb.CreateString(name) : 0, values ? _fbb.CreateVector<flatbuffers::Offset<EnumVal>>(*values) : 0, is_union, underlying_type, attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0);
|
||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
|
||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||
return reflection::CreateEnum(
|
||||
_fbb,
|
||||
name ? _fbb.CreateString(name) : 0,
|
||||
values ? _fbb.CreateVector<flatbuffers::Offset<EnumVal>>(*values) : 0,
|
||||
is_union,
|
||||
underlying_type,
|
||||
attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0,
|
||||
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0);
|
||||
}
|
||||
|
||||
struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
@@ -280,20 +424,48 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_DEPRECATED = 16,
|
||||
VT_REQUIRED = 18,
|
||||
VT_KEY = 20,
|
||||
VT_ATTRIBUTES = 22
|
||||
VT_ATTRIBUTES = 22,
|
||||
VT_DOCUMENTATION = 24
|
||||
};
|
||||
const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(VT_NAME); }
|
||||
bool KeyCompareLessThan(const Field *o) const { return *name() < *o->name(); }
|
||||
int KeyCompareWithValue(const char *val) const { return strcmp(name()->c_str(), val); }
|
||||
const Type *type() const { return GetPointer<const Type *>(VT_TYPE); }
|
||||
uint16_t id() const { return GetField<uint16_t>(VT_ID, 0); }
|
||||
uint16_t offset() const { return GetField<uint16_t>(VT_OFFSET, 0); }
|
||||
int64_t default_integer() const { return GetField<int64_t>(VT_DEFAULT_INTEGER, 0); }
|
||||
double default_real() const { return GetField<double>(VT_DEFAULT_REAL, 0.0); }
|
||||
bool deprecated() const { return GetField<uint8_t>(VT_DEPRECATED, 0) != 0; }
|
||||
bool required() const { return GetField<uint8_t>(VT_REQUIRED, 0) != 0; }
|
||||
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::String *name() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_NAME);
|
||||
}
|
||||
bool KeyCompareLessThan(const Field *o) const {
|
||||
return *name() < *o->name();
|
||||
}
|
||||
int KeyCompareWithValue(const char *val) const {
|
||||
return strcmp(name()->c_str(), val);
|
||||
}
|
||||
const Type *type() const {
|
||||
return GetPointer<const Type *>(VT_TYPE);
|
||||
}
|
||||
uint16_t id() const {
|
||||
return GetField<uint16_t>(VT_ID, 0);
|
||||
}
|
||||
uint16_t offset() const {
|
||||
return GetField<uint16_t>(VT_OFFSET, 0);
|
||||
}
|
||||
int64_t default_integer() const {
|
||||
return GetField<int64_t>(VT_DEFAULT_INTEGER, 0);
|
||||
}
|
||||
double default_real() const {
|
||||
return GetField<double>(VT_DEFAULT_REAL, 0.0);
|
||||
}
|
||||
bool deprecated() const {
|
||||
return GetField<uint8_t>(VT_DEPRECATED, 0) != 0;
|
||||
}
|
||||
bool required() const {
|
||||
return GetField<uint8_t>(VT_REQUIRED, 0) != 0;
|
||||
}
|
||||
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<flatbuffers::String>> *documentation() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyFieldRequired<flatbuffers::uoffset_t>(verifier, VT_NAME) &&
|
||||
@@ -310,6 +482,9 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_ATTRIBUTES) &&
|
||||
verifier.Verify(attributes()) &&
|
||||
verifier.VerifyVectorOfTables(attributes()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_DOCUMENTATION) &&
|
||||
verifier.Verify(documentation()) &&
|
||||
verifier.VerifyVectorOfStrings(documentation()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
@@ -317,27 +492,55 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct FieldBuilder {
|
||||
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) { fbb_.AddOffset(Field::VT_TYPE, type); }
|
||||
void add_id(uint16_t id) { fbb_.AddElement<uint16_t>(Field::VT_ID, id, 0); }
|
||||
void add_offset(uint16_t offset) { fbb_.AddElement<uint16_t>(Field::VT_OFFSET, offset, 0); }
|
||||
void add_default_integer(int64_t default_integer) { fbb_.AddElement<int64_t>(Field::VT_DEFAULT_INTEGER, default_integer, 0); }
|
||||
void add_default_real(double default_real) { fbb_.AddElement<double>(Field::VT_DEFAULT_REAL, default_real, 0.0); }
|
||||
void add_deprecated(bool deprecated) { fbb_.AddElement<uint8_t>(Field::VT_DEPRECATED, static_cast<uint8_t>(deprecated), 0); }
|
||||
void add_required(bool required) { fbb_.AddElement<uint8_t>(Field::VT_REQUIRED, static_cast<uint8_t>(required), 0); }
|
||||
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) { fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes); }
|
||||
FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||
fbb_.AddOffset(Field::VT_NAME, name);
|
||||
}
|
||||
void add_type(flatbuffers::Offset<Type> type) {
|
||||
fbb_.AddOffset(Field::VT_TYPE, type);
|
||||
}
|
||||
void add_id(uint16_t id) {
|
||||
fbb_.AddElement<uint16_t>(Field::VT_ID, id, 0);
|
||||
}
|
||||
void add_offset(uint16_t offset) {
|
||||
fbb_.AddElement<uint16_t>(Field::VT_OFFSET, offset, 0);
|
||||
}
|
||||
void add_default_integer(int64_t default_integer) {
|
||||
fbb_.AddElement<int64_t>(Field::VT_DEFAULT_INTEGER, default_integer, 0);
|
||||
}
|
||||
void add_default_real(double default_real) {
|
||||
fbb_.AddElement<double>(Field::VT_DEFAULT_REAL, default_real, 0.0);
|
||||
}
|
||||
void add_deprecated(bool deprecated) {
|
||||
fbb_.AddElement<uint8_t>(Field::VT_DEPRECATED, static_cast<uint8_t>(deprecated), 0);
|
||||
}
|
||||
void add_required(bool required) {
|
||||
fbb_.AddElement<uint8_t>(Field::VT_REQUIRED, static_cast<uint8_t>(required), 0);
|
||||
}
|
||||
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) {
|
||||
fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes);
|
||||
}
|
||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||
fbb_.AddOffset(Field::VT_DOCUMENTATION, documentation);
|
||||
}
|
||||
FieldBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
FieldBuilder &operator=(const FieldBuilder &);
|
||||
flatbuffers::Offset<Field> Finish() {
|
||||
auto o = flatbuffers::Offset<Field>(fbb_.EndTable(start_, 10));
|
||||
fbb_.Required(o, Field::VT_NAME); // name
|
||||
fbb_.Required(o, Field::VT_TYPE); // type
|
||||
const auto end = fbb_.EndTable(start_, 11);
|
||||
auto o = flatbuffers::Offset<Field>(end);
|
||||
fbb_.Required(o, Field::VT_NAME);
|
||||
fbb_.Required(o, Field::VT_TYPE);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Field> CreateField(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Field> CreateField(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
flatbuffers::Offset<Type> type = 0,
|
||||
uint16_t id = 0,
|
||||
@@ -347,10 +550,12 @@ inline flatbuffers::Offset<Field> CreateField(flatbuffers::FlatBufferBuilder &_f
|
||||
bool deprecated = false,
|
||||
bool required = false,
|
||||
bool key = false,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0) {
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||
FieldBuilder builder_(_fbb);
|
||||
builder_.add_default_real(default_real);
|
||||
builder_.add_default_integer(default_integer);
|
||||
builder_.add_documentation(documentation);
|
||||
builder_.add_attributes(attributes);
|
||||
builder_.add_type(type);
|
||||
builder_.add_name(name);
|
||||
@@ -362,7 +567,8 @@ inline flatbuffers::Offset<Field> CreateField(flatbuffers::FlatBufferBuilder &_f
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Field> CreateFieldDirect(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Field> CreateFieldDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const char *name = nullptr,
|
||||
flatbuffers::Offset<Type> type = 0,
|
||||
uint16_t id = 0,
|
||||
@@ -372,8 +578,21 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(flatbuffers::FlatBufferBuild
|
||||
bool deprecated = false,
|
||||
bool required = false,
|
||||
bool key = false,
|
||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr) {
|
||||
return CreateField(_fbb, name ? _fbb.CreateString(name) : 0, type, id, offset, default_integer, default_real, deprecated, required, key, attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0);
|
||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
|
||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||
return reflection::CreateField(
|
||||
_fbb,
|
||||
name ? _fbb.CreateString(name) : 0,
|
||||
type,
|
||||
id,
|
||||
offset,
|
||||
default_integer,
|
||||
default_real,
|
||||
deprecated,
|
||||
required,
|
||||
key,
|
||||
attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0,
|
||||
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0);
|
||||
}
|
||||
|
||||
struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
@@ -383,16 +602,36 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_IS_STRUCT = 8,
|
||||
VT_MINALIGN = 10,
|
||||
VT_BYTESIZE = 12,
|
||||
VT_ATTRIBUTES = 14
|
||||
VT_ATTRIBUTES = 14,
|
||||
VT_DOCUMENTATION = 16
|
||||
};
|
||||
const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(VT_NAME); }
|
||||
bool KeyCompareLessThan(const Object *o) const { return *name() < *o->name(); }
|
||||
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); }
|
||||
bool is_struct() const { return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0; }
|
||||
int32_t minalign() const { return GetField<int32_t>(VT_MINALIGN, 0); }
|
||||
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::String *name() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_NAME);
|
||||
}
|
||||
bool KeyCompareLessThan(const Object *o) const {
|
||||
return *name() < *o->name();
|
||||
}
|
||||
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);
|
||||
}
|
||||
bool is_struct() const {
|
||||
return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0;
|
||||
}
|
||||
int32_t minalign() const {
|
||||
return GetField<int32_t>(VT_MINALIGN, 0);
|
||||
}
|
||||
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<flatbuffers::String>> *documentation() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyFieldRequired<flatbuffers::uoffset_t>(verifier, VT_NAME) &&
|
||||
@@ -406,6 +645,9 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_ATTRIBUTES) &&
|
||||
verifier.Verify(attributes()) &&
|
||||
verifier.VerifyVectorOfTables(attributes()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_DOCUMENTATION) &&
|
||||
verifier.Verify(documentation()) &&
|
||||
verifier.VerifyVectorOfStrings(documentation()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
@@ -413,30 +655,52 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct ObjectBuilder {
|
||||
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) { fbb_.AddOffset(Object::VT_FIELDS, fields); }
|
||||
void add_is_struct(bool is_struct) { fbb_.AddElement<uint8_t>(Object::VT_IS_STRUCT, static_cast<uint8_t>(is_struct), 0); }
|
||||
void add_minalign(int32_t minalign) { fbb_.AddElement<int32_t>(Object::VT_MINALIGN, minalign, 0); }
|
||||
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) { fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes); }
|
||||
ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
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) {
|
||||
fbb_.AddOffset(Object::VT_FIELDS, fields);
|
||||
}
|
||||
void add_is_struct(bool is_struct) {
|
||||
fbb_.AddElement<uint8_t>(Object::VT_IS_STRUCT, static_cast<uint8_t>(is_struct), 0);
|
||||
}
|
||||
void add_minalign(int32_t minalign) {
|
||||
fbb_.AddElement<int32_t>(Object::VT_MINALIGN, minalign, 0);
|
||||
}
|
||||
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) {
|
||||
fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes);
|
||||
}
|
||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||
fbb_.AddOffset(Object::VT_DOCUMENTATION, documentation);
|
||||
}
|
||||
ObjectBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
ObjectBuilder &operator=(const ObjectBuilder &);
|
||||
flatbuffers::Offset<Object> Finish() {
|
||||
auto o = flatbuffers::Offset<Object>(fbb_.EndTable(start_, 6));
|
||||
fbb_.Required(o, Object::VT_NAME); // name
|
||||
fbb_.Required(o, Object::VT_FIELDS); // fields
|
||||
const auto end = fbb_.EndTable(start_, 7);
|
||||
auto o = flatbuffers::Offset<Object>(end);
|
||||
fbb_.Required(o, Object::VT_NAME);
|
||||
fbb_.Required(o, Object::VT_FIELDS);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Object> CreateObject(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Object> CreateObject(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<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<KeyValue>>> attributes = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||
ObjectBuilder builder_(_fbb);
|
||||
builder_.add_documentation(documentation);
|
||||
builder_.add_attributes(attributes);
|
||||
builder_.add_bytesize(bytesize);
|
||||
builder_.add_minalign(minalign);
|
||||
@@ -446,14 +710,24 @@ inline flatbuffers::Offset<Object> CreateObject(flatbuffers::FlatBufferBuilder &
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Object> CreateObjectDirect(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Object> CreateObjectDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const char *name = nullptr,
|
||||
const std::vector<flatbuffers::Offset<Field>> *fields = nullptr,
|
||||
bool is_struct = false,
|
||||
int32_t minalign = 0,
|
||||
int32_t bytesize = 0,
|
||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr) {
|
||||
return CreateObject(_fbb, name ? _fbb.CreateString(name) : 0, fields ? _fbb.CreateVector<flatbuffers::Offset<Field>>(*fields) : 0, is_struct, minalign, bytesize, attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0);
|
||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
|
||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||
return reflection::CreateObject(
|
||||
_fbb,
|
||||
name ? _fbb.CreateString(name) : 0,
|
||||
fields ? _fbb.CreateVector<flatbuffers::Offset<Field>>(*fields) : 0,
|
||||
is_struct,
|
||||
minalign,
|
||||
bytesize,
|
||||
attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0,
|
||||
documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0);
|
||||
}
|
||||
|
||||
struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
@@ -464,11 +738,21 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_FILE_EXT = 10,
|
||||
VT_ROOT_TABLE = 12
|
||||
};
|
||||
const flatbuffers::Vector<flatbuffers::Offset<Object>> *objects() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Object>> *>(VT_OBJECTS); }
|
||||
const flatbuffers::Vector<flatbuffers::Offset<Enum>> *enums() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Enum>> *>(VT_ENUMS); }
|
||||
const flatbuffers::String *file_ident() const { return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT); }
|
||||
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 flatbuffers::Vector<flatbuffers::Offset<Object>> *objects() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Object>> *>(VT_OBJECTS);
|
||||
}
|
||||
const flatbuffers::Vector<flatbuffers::Offset<Enum>> *enums() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Enum>> *>(VT_ENUMS);
|
||||
}
|
||||
const flatbuffers::String *file_ident() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT);
|
||||
}
|
||||
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);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyFieldRequired<flatbuffers::uoffset_t>(verifier, VT_OBJECTS) &&
|
||||
@@ -490,22 +774,37 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct SchemaBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Object>>> objects) { fbb_.AddOffset(Schema::VT_OBJECTS, objects); }
|
||||
void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Enum>>> enums) { fbb_.AddOffset(Schema::VT_ENUMS, enums); }
|
||||
void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) { fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident); }
|
||||
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) { fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table); }
|
||||
SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Object>>> objects) {
|
||||
fbb_.AddOffset(Schema::VT_OBJECTS, objects);
|
||||
}
|
||||
void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Enum>>> enums) {
|
||||
fbb_.AddOffset(Schema::VT_ENUMS, enums);
|
||||
}
|
||||
void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) {
|
||||
fbb_.AddOffset(Schema::VT_FILE_IDENT, file_ident);
|
||||
}
|
||||
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) {
|
||||
fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table);
|
||||
}
|
||||
SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
SchemaBuilder &operator=(const SchemaBuilder &);
|
||||
flatbuffers::Offset<Schema> Finish() {
|
||||
auto o = flatbuffers::Offset<Schema>(fbb_.EndTable(start_, 5));
|
||||
fbb_.Required(o, Schema::VT_OBJECTS); // objects
|
||||
fbb_.Required(o, Schema::VT_ENUMS); // enums
|
||||
const auto end = fbb_.EndTable(start_, 5);
|
||||
auto o = flatbuffers::Offset<Schema>(end);
|
||||
fbb_.Required(o, Schema::VT_OBJECTS);
|
||||
fbb_.Required(o, Schema::VT_ENUMS);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Schema> CreateSchema(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
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::String> file_ident = 0,
|
||||
@@ -520,13 +819,20 @@ inline flatbuffers::Offset<Schema> CreateSchema(flatbuffers::FlatBufferBuilder &
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Schema> CreateSchemaDirect(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Schema> CreateSchemaDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const std::vector<flatbuffers::Offset<Object>> *objects = nullptr,
|
||||
const std::vector<flatbuffers::Offset<Enum>> *enums = nullptr,
|
||||
const char *file_ident = nullptr,
|
||||
const char *file_ext = nullptr,
|
||||
flatbuffers::Offset<Object> root_table = 0) {
|
||||
return CreateSchema(_fbb, objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0, enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0, file_ident ? _fbb.CreateString(file_ident) : 0, file_ext ? _fbb.CreateString(file_ext) : 0, root_table);
|
||||
return reflection::CreateSchema(
|
||||
_fbb,
|
||||
objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0,
|
||||
enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0,
|
||||
file_ident ? _fbb.CreateString(file_ident) : 0,
|
||||
file_ext ? _fbb.CreateString(file_ext) : 0,
|
||||
root_table);
|
||||
}
|
||||
|
||||
inline const reflection::Schema *GetSchema(const void *buf) {
|
||||
@@ -538,16 +844,22 @@ inline const char *SchemaIdentifier() {
|
||||
}
|
||||
|
||||
inline bool SchemaBufferHasIdentifier(const void *buf) {
|
||||
return flatbuffers::BufferHasIdentifier(buf, SchemaIdentifier());
|
||||
return flatbuffers::BufferHasIdentifier(
|
||||
buf, SchemaIdentifier());
|
||||
}
|
||||
|
||||
inline bool VerifySchemaBuffer(flatbuffers::Verifier &verifier) {
|
||||
inline bool VerifySchemaBuffer(
|
||||
flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier());
|
||||
}
|
||||
|
||||
inline const char *SchemaExtension() { return "bfbs"; }
|
||||
inline const char *SchemaExtension() {
|
||||
return "bfbs";
|
||||
}
|
||||
|
||||
inline void FinishSchemaBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<reflection::Schema> root) {
|
||||
inline void FinishSchemaBuffer(
|
||||
flatbuffers::FlatBufferBuilder &fbb,
|
||||
flatbuffers::Offset<reflection::Schema> root) {
|
||||
fbb.Finish(root, SchemaIdentifier());
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,8 @@ inline std::string IntToStringHex(int i, int xdigits) {
|
||||
}
|
||||
|
||||
// Portable implementation of strtoll().
|
||||
inline int64_t StringToInt(const char *str, char **endptr = nullptr, int base = 10) {
|
||||
inline int64_t StringToInt(const char *str, char **endptr = nullptr,
|
||||
int base = 10) {
|
||||
#ifdef _MSC_VER
|
||||
return _strtoi64(str, endptr, base);
|
||||
#else
|
||||
@@ -104,7 +105,8 @@ inline int64_t StringToInt(const char *str, char **endptr = nullptr, int base =
|
||||
}
|
||||
|
||||
// Portable implementation of strtoull().
|
||||
inline int64_t StringToUInt(const char *str, char **endptr = nullptr, int base = 10) {
|
||||
inline uint64_t StringToUInt(const char *str, char **endptr = nullptr,
|
||||
int base = 10) {
|
||||
#ifdef _MSC_VER
|
||||
return _strtoui64(str, endptr, base);
|
||||
#else
|
||||
|
||||
@@ -2,6 +2,15 @@
|
||||
/// @addtogroup flatbuffers_javascript_api
|
||||
/// @{
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
|
||||
/**
|
||||
* @fileoverview
|
||||
*
|
||||
* Need to suppress 'global this' error so the Node.js export line doesn't cause
|
||||
* closure compile to error out.
|
||||
* @suppress {globalThis}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @namespace
|
||||
@@ -530,6 +539,10 @@ flatbuffers.Builder.prototype.offset = function() {
|
||||
* @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
|
||||
* @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
|
||||
* it a uint8Array we need to suppress the type check:
|
||||
* @suppress {checkTypes}
|
||||
*/
|
||||
flatbuffers.Builder.growByteBuffer = function(bb) {
|
||||
var old_buf_size = bb.capacity();
|
||||
|
||||
27
package.json
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "flatbuffers",
|
||||
"version": "1.6.0",
|
||||
"description": "Memory Efficient Serialization Library",
|
||||
"files": ["js/flatbuffers.js"],
|
||||
"main": "js/flatbuffers.js",
|
||||
"directories": {
|
||||
"doc": "docs",
|
||||
"test": "tests"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tests/JavaScriptTest.sh"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/google/flatbuffers.git"
|
||||
},
|
||||
"keywords": [
|
||||
"flatbuffers"
|
||||
],
|
||||
"author": "The FlatBuffers project",
|
||||
"license": "SEE LICENSE IN LICENSE.txt",
|
||||
"bugs": {
|
||||
"url": "https://github.com/google/flatbuffers/issues"
|
||||
},
|
||||
"homepage": "https://google.github.io/flatbuffers/"
|
||||
}
|
||||
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.google.flatbuffers</groupId>
|
||||
<artifactId>flatbuffers-java</artifactId>
|
||||
<version>1.5.0-SNAPSHOT</version>
|
||||
<version>1.6.0-SNAPSHOT</version>
|
||||
<packaging>bundle</packaging>
|
||||
<name>FlatBuffers Java API</name>
|
||||
<description>
|
||||
|
||||
@@ -51,6 +51,7 @@ table Enum {
|
||||
is_union:bool = false;
|
||||
underlying_type:Type (required);
|
||||
attributes:[KeyValue];
|
||||
documentation:[string];
|
||||
}
|
||||
|
||||
table Field {
|
||||
@@ -64,6 +65,7 @@ table Field {
|
||||
required:bool = false;
|
||||
key:bool = false;
|
||||
attributes:[KeyValue];
|
||||
documentation:[string];
|
||||
}
|
||||
|
||||
table Object { // Used for both tables and structs.
|
||||
@@ -73,6 +75,7 @@ table Object { // Used for both tables and structs.
|
||||
minalign:int;
|
||||
bytesize:int; // For structs.
|
||||
attributes:[KeyValue];
|
||||
documentation:[string];
|
||||
}
|
||||
|
||||
table Schema {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
|
||||
#ifndef FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
|
||||
#define FLATBUFFERS_GENERATED_MONSTER_MYGAME_SAMPLE_H_
|
||||
|
||||
@@ -25,11 +26,19 @@ enum Color {
|
||||
};
|
||||
|
||||
inline const char **EnumNamesColor() {
|
||||
static const char *names[] = { "Red", "Green", "Blue", nullptr };
|
||||
static const char *names[] = {
|
||||
"Red",
|
||||
"Green",
|
||||
"Blue",
|
||||
nullptr
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameColor(Color e) { return EnumNamesColor()[static_cast<int>(e)]; }
|
||||
inline const char *EnumNameColor(Color e) {
|
||||
const size_t index = static_cast<int>(e);
|
||||
return EnumNamesColor()[index];
|
||||
}
|
||||
|
||||
enum Equipment {
|
||||
Equipment_NONE = 0,
|
||||
@@ -39,11 +48,18 @@ enum Equipment {
|
||||
};
|
||||
|
||||
inline const char **EnumNamesEquipment() {
|
||||
static const char *names[] = { "NONE", "Weapon", nullptr };
|
||||
static const char *names[] = {
|
||||
"NONE",
|
||||
"Weapon",
|
||||
nullptr
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameEquipment(Equipment e) { return EnumNamesEquipment()[static_cast<int>(e)]; }
|
||||
inline const char *EnumNameEquipment(Equipment e) {
|
||||
const size_t index = static_cast<int>(e);
|
||||
return EnumNamesEquipment()[index];
|
||||
}
|
||||
|
||||
template<typename T> struct EquipmentTraits {
|
||||
static const Equipment enum_value = Equipment_NONE;
|
||||
@@ -55,12 +71,15 @@ template<> struct EquipmentTraits<Weapon> {
|
||||
|
||||
struct EquipmentUnion {
|
||||
Equipment type;
|
||||
|
||||
flatbuffers::NativeTable *table;
|
||||
|
||||
EquipmentUnion() : type(Equipment_NONE), table(nullptr) {}
|
||||
EquipmentUnion(EquipmentUnion&& u):
|
||||
type(std::move(u.type)), table(std::move(u.table)) {}
|
||||
EquipmentUnion(const EquipmentUnion &);
|
||||
EquipmentUnion &operator=(const EquipmentUnion &);
|
||||
~EquipmentUnion() { Reset(); }
|
||||
|
||||
void Reset();
|
||||
|
||||
template <typename T>
|
||||
@@ -72,13 +91,17 @@ struct EquipmentUnion {
|
||||
}
|
||||
}
|
||||
|
||||
static flatbuffers::NativeTable *UnPack(const void *union_obj, Equipment type, const flatbuffers::resolver_function_t *resolver);
|
||||
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *rehasher = nullptr) const;
|
||||
static flatbuffers::NativeTable *UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver);
|
||||
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
|
||||
|
||||
WeaponT *AsWeapon() { return type == Equipment_Weapon ? reinterpret_cast<WeaponT *>(table) : nullptr; }
|
||||
WeaponT *AsWeapon() {
|
||||
return type == Equipment_Weapon ?
|
||||
reinterpret_cast<WeaponT *>(table) : nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *union_obj, Equipment type);
|
||||
bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Equipment type);
|
||||
bool VerifyEquipmentVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
|
||||
|
||||
MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
|
||||
private:
|
||||
@@ -87,17 +110,35 @@ MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
|
||||
float z_;
|
||||
|
||||
public:
|
||||
Vec3() { memset(this, 0, sizeof(Vec3)); }
|
||||
Vec3(const Vec3 &_o) { memcpy(this, &_o, sizeof(Vec3)); }
|
||||
Vec3() {
|
||||
memset(this, 0, sizeof(Vec3));
|
||||
}
|
||||
Vec3(const Vec3 &_o) {
|
||||
memcpy(this, &_o, sizeof(Vec3));
|
||||
}
|
||||
Vec3(float _x, float _y, float _z)
|
||||
: x_(flatbuffers::EndianScalar(_x)), y_(flatbuffers::EndianScalar(_y)), z_(flatbuffers::EndianScalar(_z)) { }
|
||||
|
||||
float x() const { return flatbuffers::EndianScalar(x_); }
|
||||
void mutate_x(float _x) { flatbuffers::WriteScalar(&x_, _x); }
|
||||
float y() const { return flatbuffers::EndianScalar(y_); }
|
||||
void mutate_y(float _y) { flatbuffers::WriteScalar(&y_, _y); }
|
||||
float z() const { return flatbuffers::EndianScalar(z_); }
|
||||
void mutate_z(float _z) { flatbuffers::WriteScalar(&z_, _z); }
|
||||
: x_(flatbuffers::EndianScalar(_x)),
|
||||
y_(flatbuffers::EndianScalar(_y)),
|
||||
z_(flatbuffers::EndianScalar(_z)) {
|
||||
}
|
||||
float x() const {
|
||||
return flatbuffers::EndianScalar(x_);
|
||||
}
|
||||
void mutate_x(float _x) {
|
||||
flatbuffers::WriteScalar(&x_, _x);
|
||||
}
|
||||
float y() const {
|
||||
return flatbuffers::EndianScalar(y_);
|
||||
}
|
||||
void mutate_y(float _y) {
|
||||
flatbuffers::WriteScalar(&y_, _y);
|
||||
}
|
||||
float z() const {
|
||||
return flatbuffers::EndianScalar(z_);
|
||||
}
|
||||
void mutate_z(float _z) {
|
||||
flatbuffers::WriteScalar(&z_, _z);
|
||||
}
|
||||
};
|
||||
STRUCT_END(Vec3, 12);
|
||||
|
||||
@@ -112,9 +153,10 @@ struct MonsterT : public flatbuffers::NativeTable {
|
||||
std::vector<std::unique_ptr<WeaponT>> weapons;
|
||||
EquipmentUnion equipped;
|
||||
MonsterT()
|
||||
: mana(150),
|
||||
hp(100),
|
||||
color(Color_Blue) {}
|
||||
: mana(150),
|
||||
hp(100),
|
||||
color(Color_Blue) {
|
||||
}
|
||||
};
|
||||
|
||||
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
@@ -130,24 +172,60 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_EQUIPPED_TYPE = 20,
|
||||
VT_EQUIPPED = 22
|
||||
};
|
||||
const Vec3 *pos() const { return GetStruct<const Vec3 *>(VT_POS); }
|
||||
Vec3 *mutable_pos() { return GetStruct<Vec3 *>(VT_POS); }
|
||||
int16_t mana() const { return GetField<int16_t>(VT_MANA, 150); }
|
||||
bool mutate_mana(int16_t _mana) { return SetField(VT_MANA, _mana); }
|
||||
int16_t hp() const { return GetField<int16_t>(VT_HP, 100); }
|
||||
bool mutate_hp(int16_t _hp) { return SetField(VT_HP, _hp); }
|
||||
const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(VT_NAME); }
|
||||
flatbuffers::String *mutable_name() { return GetPointer<flatbuffers::String *>(VT_NAME); }
|
||||
const flatbuffers::Vector<uint8_t> *inventory() const { return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_INVENTORY); }
|
||||
flatbuffers::Vector<uint8_t> *mutable_inventory() { return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY); }
|
||||
Color color() const { return static_cast<Color>(GetField<int8_t>(VT_COLOR, 2)); }
|
||||
bool mutate_color(Color _color) { return SetField(VT_COLOR, static_cast<int8_t>(_color)); }
|
||||
const flatbuffers::Vector<flatbuffers::Offset<Weapon>> *weapons() const { return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Weapon>> *>(VT_WEAPONS); }
|
||||
flatbuffers::Vector<flatbuffers::Offset<Weapon>> *mutable_weapons() { return GetPointer<flatbuffers::Vector<flatbuffers::Offset<Weapon>> *>(VT_WEAPONS); }
|
||||
Equipment equipped_type() const { return static_cast<Equipment>(GetField<uint8_t>(VT_EQUIPPED_TYPE, 0)); }
|
||||
bool mutate_equipped_type(Equipment _equipped_type) { return SetField(VT_EQUIPPED_TYPE, static_cast<uint8_t>(_equipped_type)); }
|
||||
const void *equipped() const { return GetPointer<const void *>(VT_EQUIPPED); }
|
||||
void *mutable_equipped() { return GetPointer<void *>(VT_EQUIPPED); }
|
||||
const Vec3 *pos() const {
|
||||
return GetStruct<const Vec3 *>(VT_POS);
|
||||
}
|
||||
Vec3 *mutable_pos() {
|
||||
return GetStruct<Vec3 *>(VT_POS);
|
||||
}
|
||||
int16_t mana() const {
|
||||
return GetField<int16_t>(VT_MANA, 150);
|
||||
}
|
||||
bool mutate_mana(int16_t _mana) {
|
||||
return SetField(VT_MANA, _mana);
|
||||
}
|
||||
int16_t hp() const {
|
||||
return GetField<int16_t>(VT_HP, 100);
|
||||
}
|
||||
bool mutate_hp(int16_t _hp) {
|
||||
return SetField(VT_HP, _hp);
|
||||
}
|
||||
const flatbuffers::String *name() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_NAME);
|
||||
}
|
||||
flatbuffers::String *mutable_name() {
|
||||
return GetPointer<flatbuffers::String *>(VT_NAME);
|
||||
}
|
||||
const flatbuffers::Vector<uint8_t> *inventory() const {
|
||||
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
|
||||
}
|
||||
flatbuffers::Vector<uint8_t> *mutable_inventory() {
|
||||
return GetPointer<flatbuffers::Vector<uint8_t> *>(VT_INVENTORY);
|
||||
}
|
||||
Color color() const {
|
||||
return static_cast<Color>(GetField<int8_t>(VT_COLOR, 2));
|
||||
}
|
||||
bool mutate_color(Color _color) {
|
||||
return SetField(VT_COLOR, static_cast<int8_t>(_color));
|
||||
}
|
||||
const flatbuffers::Vector<flatbuffers::Offset<Weapon>> *weapons() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Weapon>> *>(VT_WEAPONS);
|
||||
}
|
||||
flatbuffers::Vector<flatbuffers::Offset<Weapon>> *mutable_weapons() {
|
||||
return GetPointer<flatbuffers::Vector<flatbuffers::Offset<Weapon>> *>(VT_WEAPONS);
|
||||
}
|
||||
Equipment equipped_type() const {
|
||||
return static_cast<Equipment>(GetField<uint8_t>(VT_EQUIPPED_TYPE, 0));
|
||||
}
|
||||
bool mutate_equipped_type(Equipment _equipped_type) {
|
||||
return SetField(VT_EQUIPPED_TYPE, static_cast<uint8_t>(_equipped_type));
|
||||
}
|
||||
const void *equipped() const {
|
||||
return GetPointer<const void *>(VT_EQUIPPED);
|
||||
}
|
||||
void *mutable_equipped() {
|
||||
return GetPointer<void *>(VT_EQUIPPED);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<Vec3>(verifier, VT_POS) &&
|
||||
@@ -166,31 +244,55 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VerifyEquipment(verifier, equipped(), equipped_type()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
|
||||
MonsterT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
|
||||
void UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
|
||||
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct MonsterBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_pos(const Vec3 *pos) { fbb_.AddStruct(Monster::VT_POS, pos); }
|
||||
void add_mana(int16_t mana) { fbb_.AddElement<int16_t>(Monster::VT_MANA, mana, 150); }
|
||||
void add_hp(int16_t hp) { fbb_.AddElement<int16_t>(Monster::VT_HP, hp, 100); }
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) { fbb_.AddOffset(Monster::VT_NAME, name); }
|
||||
void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) { fbb_.AddOffset(Monster::VT_INVENTORY, inventory); }
|
||||
void add_color(Color color) { fbb_.AddElement<int8_t>(Monster::VT_COLOR, static_cast<int8_t>(color), 2); }
|
||||
void add_weapons(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Weapon>>> weapons) { fbb_.AddOffset(Monster::VT_WEAPONS, weapons); }
|
||||
void add_equipped_type(Equipment equipped_type) { fbb_.AddElement<uint8_t>(Monster::VT_EQUIPPED_TYPE, static_cast<uint8_t>(equipped_type), 0); }
|
||||
void add_equipped(flatbuffers::Offset<void> equipped) { fbb_.AddOffset(Monster::VT_EQUIPPED, equipped); }
|
||||
MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_pos(const Vec3 *pos) {
|
||||
fbb_.AddStruct(Monster::VT_POS, pos);
|
||||
}
|
||||
void add_mana(int16_t mana) {
|
||||
fbb_.AddElement<int16_t>(Monster::VT_MANA, mana, 150);
|
||||
}
|
||||
void add_hp(int16_t hp) {
|
||||
fbb_.AddElement<int16_t>(Monster::VT_HP, hp, 100);
|
||||
}
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||
fbb_.AddOffset(Monster::VT_NAME, name);
|
||||
}
|
||||
void add_inventory(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> inventory) {
|
||||
fbb_.AddOffset(Monster::VT_INVENTORY, inventory);
|
||||
}
|
||||
void add_color(Color color) {
|
||||
fbb_.AddElement<int8_t>(Monster::VT_COLOR, static_cast<int8_t>(color), 2);
|
||||
}
|
||||
void add_weapons(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Weapon>>> weapons) {
|
||||
fbb_.AddOffset(Monster::VT_WEAPONS, weapons);
|
||||
}
|
||||
void add_equipped_type(Equipment equipped_type) {
|
||||
fbb_.AddElement<uint8_t>(Monster::VT_EQUIPPED_TYPE, static_cast<uint8_t>(equipped_type), 0);
|
||||
}
|
||||
void add_equipped(flatbuffers::Offset<void> equipped) {
|
||||
fbb_.AddOffset(Monster::VT_EQUIPPED, equipped);
|
||||
}
|
||||
MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
MonsterBuilder &operator=(const MonsterBuilder &);
|
||||
flatbuffers::Offset<Monster> Finish() {
|
||||
auto o = flatbuffers::Offset<Monster>(fbb_.EndTable(start_, 10));
|
||||
const auto end = fbb_.EndTable(start_, 10);
|
||||
auto o = flatbuffers::Offset<Monster>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
@@ -213,7 +315,8 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonsterDirect(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Monster> CreateMonsterDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const Vec3 *pos = 0,
|
||||
int16_t mana = 150,
|
||||
int16_t hp = 100,
|
||||
@@ -223,17 +326,28 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(flatbuffers::FlatBufferB
|
||||
const std::vector<flatbuffers::Offset<Weapon>> *weapons = nullptr,
|
||||
Equipment equipped_type = Equipment_NONE,
|
||||
flatbuffers::Offset<void> equipped = 0) {
|
||||
return CreateMonster(_fbb, pos, mana, hp, name ? _fbb.CreateString(name) : 0, inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0, color, weapons ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(*weapons) : 0, equipped_type, equipped);
|
||||
return MyGame::Sample::CreateMonster(
|
||||
_fbb,
|
||||
pos,
|
||||
mana,
|
||||
hp,
|
||||
name ? _fbb.CreateString(name) : 0,
|
||||
inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0,
|
||||
color,
|
||||
weapons ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(*weapons) : 0,
|
||||
equipped_type,
|
||||
equipped);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
|
||||
flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
|
||||
struct WeaponT : public flatbuffers::NativeTable {
|
||||
typedef Weapon TableType;
|
||||
std::string name;
|
||||
int16_t damage;
|
||||
WeaponT()
|
||||
: damage(0) {}
|
||||
: damage(0) {
|
||||
}
|
||||
};
|
||||
|
||||
struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
@@ -242,10 +356,18 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_NAME = 4,
|
||||
VT_DAMAGE = 6
|
||||
};
|
||||
const flatbuffers::String *name() const { return GetPointer<const flatbuffers::String *>(VT_NAME); }
|
||||
flatbuffers::String *mutable_name() { return GetPointer<flatbuffers::String *>(VT_NAME); }
|
||||
int16_t damage() const { return GetField<int16_t>(VT_DAMAGE, 0); }
|
||||
bool mutate_damage(int16_t _damage) { return SetField(VT_DAMAGE, _damage); }
|
||||
const flatbuffers::String *name() const {
|
||||
return GetPointer<const flatbuffers::String *>(VT_NAME);
|
||||
}
|
||||
flatbuffers::String *mutable_name() {
|
||||
return GetPointer<flatbuffers::String *>(VT_NAME);
|
||||
}
|
||||
int16_t damage() const {
|
||||
return GetField<int16_t>(VT_DAMAGE, 0);
|
||||
}
|
||||
bool mutate_damage(int16_t _damage) {
|
||||
return SetField(VT_DAMAGE, _damage);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_NAME) &&
|
||||
@@ -253,24 +375,34 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VerifyField<int16_t>(verifier, VT_DAMAGE) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
WeaponT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
|
||||
WeaponT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
|
||||
void UnPackTo(WeaponT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
|
||||
static flatbuffers::Offset<Weapon> Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct WeaponBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) { fbb_.AddOffset(Weapon::VT_NAME, name); }
|
||||
void add_damage(int16_t damage) { fbb_.AddElement<int16_t>(Weapon::VT_DAMAGE, damage, 0); }
|
||||
WeaponBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||
fbb_.AddOffset(Weapon::VT_NAME, name);
|
||||
}
|
||||
void add_damage(int16_t damage) {
|
||||
fbb_.AddElement<int16_t>(Weapon::VT_DAMAGE, damage, 0);
|
||||
}
|
||||
WeaponBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
WeaponBuilder &operator=(const WeaponBuilder &);
|
||||
flatbuffers::Offset<Weapon> Finish() {
|
||||
auto o = flatbuffers::Offset<Weapon>(fbb_.EndTable(start_, 2));
|
||||
const auto end = fbb_.EndTable(start_, 2);
|
||||
auto o = flatbuffers::Offset<Weapon>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||
int16_t damage = 0) {
|
||||
WeaponBuilder builder_(_fbb);
|
||||
@@ -279,93 +411,146 @@ inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeaponDirect(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<Weapon> CreateWeaponDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const char *name = nullptr,
|
||||
int16_t damage = 0) {
|
||||
return CreateWeapon(_fbb, name ? _fbb.CreateString(name) : 0, damage);
|
||||
return MyGame::Sample::CreateWeapon(
|
||||
_fbb,
|
||||
name ? _fbb.CreateString(name) : 0,
|
||||
damage);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
|
||||
flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
|
||||
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const {
|
||||
(void)resolver;
|
||||
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
|
||||
auto _o = new MonsterT();
|
||||
UnPackTo(_o, _resolver);
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
|
||||
(void)_o;
|
||||
(void)_resolver;
|
||||
{ auto _e = pos(); if (_e) _o->pos = std::unique_ptr<Vec3>(new Vec3(*_e)); };
|
||||
{ auto _e = mana(); _o->mana = _e; };
|
||||
{ auto _e = hp(); _o->hp = _e; };
|
||||
{ auto _e = name(); if (_e) _o->name = _e->str(); };
|
||||
{ auto _e = inventory(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory.push_back(_e->Get(_i)); } } };
|
||||
{ auto _e = inventory(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory.push_back(_e->Get(_i)); } };
|
||||
{ auto _e = color(); _o->color = _e; };
|
||||
{ auto _e = weapons(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons.push_back(std::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(resolver))); } } };
|
||||
{ auto _e = weapons(); if (_e) for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons.push_back(std::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(_resolver))); } };
|
||||
{ auto _e = equipped_type(); _o->equipped.type = _e; };
|
||||
{ auto _e = equipped(); if (_e) _o->equipped.table = EquipmentUnion::UnPack(_e, equipped_type(), resolver); };
|
||||
return _o;
|
||||
{ auto _e = equipped(); if (_e) _o->equipped.table = EquipmentUnion::UnPack(_e, equipped_type(),_resolver); };
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateMonster(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) {
|
||||
(void)rehasher;
|
||||
return CreateMonster(_fbb,
|
||||
_o->pos ? _o->pos.get() : 0,
|
||||
_o->mana,
|
||||
_o->hp,
|
||||
_o->name.size() ? _fbb.CreateString(_o->name) : 0,
|
||||
_o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0,
|
||||
_o->color,
|
||||
_o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(_o->weapons.size(), [&](size_t i) { return CreateWeapon(_fbb, _o->weapons[i].get(), rehasher); }) : 0,
|
||||
_o->equipped.type,
|
||||
_o->equipped.Pack(_fbb));
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
(void)_rehasher;
|
||||
(void)_o;
|
||||
auto _pos = _o->pos ? _o->pos.get() : 0;
|
||||
auto _mana = _o->mana;
|
||||
auto _hp = _o->hp;
|
||||
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
|
||||
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
|
||||
auto _color = _o->color;
|
||||
auto _weapons = _o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(_o->weapons.size(), [&](size_t i) { return CreateWeapon(_fbb, _o->weapons[i].get(), _rehasher); }) : 0;
|
||||
auto _equipped_type = _o->equipped.type;
|
||||
auto _equipped = _o->equipped.Pack(_fbb);
|
||||
return MyGame::Sample::CreateMonster(
|
||||
_fbb,
|
||||
_pos,
|
||||
_mana,
|
||||
_hp,
|
||||
_name,
|
||||
_inventory,
|
||||
_color,
|
||||
_weapons,
|
||||
_equipped_type,
|
||||
_equipped);
|
||||
}
|
||||
|
||||
inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *resolver) const {
|
||||
(void)resolver;
|
||||
inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
|
||||
auto _o = new WeaponT();
|
||||
UnPackTo(_o, _resolver);
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline void Weapon::UnPackTo(WeaponT *_o, const flatbuffers::resolver_function_t *_resolver) const {
|
||||
(void)_o;
|
||||
(void)_resolver;
|
||||
{ auto _e = name(); if (_e) _o->name = _e->str(); };
|
||||
{ auto _e = damage(); _o->damage = _e; };
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Weapon> Weapon::Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateWeapon(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *rehasher) {
|
||||
(void)rehasher;
|
||||
return CreateWeapon(_fbb,
|
||||
_o->name.size() ? _fbb.CreateString(_o->name) : 0,
|
||||
_o->damage);
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
(void)_rehasher;
|
||||
(void)_o;
|
||||
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
|
||||
auto _damage = _o->damage;
|
||||
return MyGame::Sample::CreateWeapon(
|
||||
_fbb,
|
||||
_name,
|
||||
_damage);
|
||||
}
|
||||
|
||||
inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *union_obj, Equipment type) {
|
||||
inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Equipment type) {
|
||||
switch (type) {
|
||||
case Equipment_NONE: return true;
|
||||
case Equipment_Weapon: return verifier.VerifyTable(reinterpret_cast<const Weapon *>(union_obj));
|
||||
case Equipment_NONE: {
|
||||
return true;
|
||||
}
|
||||
case Equipment_Weapon: {
|
||||
auto ptr = reinterpret_cast<const Weapon *>(obj);
|
||||
return verifier.VerifyTable(ptr);
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline flatbuffers::NativeTable *EquipmentUnion::UnPack(const void *union_obj, Equipment type, const flatbuffers::resolver_function_t *resolver) {
|
||||
inline bool VerifyEquipmentVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
|
||||
if (values->size() != types->size()) return false;
|
||||
for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
|
||||
if (!VerifyEquipment(
|
||||
verifier, values->Get(i), types->GetEnum<Equipment>(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline flatbuffers::NativeTable *EquipmentUnion::UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver) {
|
||||
switch (type) {
|
||||
case Equipment_NONE: return nullptr;
|
||||
case Equipment_Weapon: return reinterpret_cast<const Weapon *>(union_obj)->UnPack(resolver);
|
||||
case Equipment_Weapon: {
|
||||
auto ptr = reinterpret_cast<const Weapon *>(obj);
|
||||
return ptr->UnPack(resolver);
|
||||
}
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<void> EquipmentUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *rehasher) const {
|
||||
inline flatbuffers::Offset<void> EquipmentUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher) const {
|
||||
switch (type) {
|
||||
case Equipment_NONE: return 0;
|
||||
case Equipment_Weapon: return CreateWeapon(_fbb, reinterpret_cast<const WeaponT *>(table), rehasher).Union();
|
||||
case Equipment_Weapon: {
|
||||
auto ptr = reinterpret_cast<const WeaponT *>(table);
|
||||
return CreateWeapon(_fbb, ptr, _rehasher).Union();
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void EquipmentUnion::Reset() {
|
||||
switch (type) {
|
||||
case Equipment_Weapon: delete reinterpret_cast<WeaponT *>(table); break;
|
||||
case Equipment_Weapon: {
|
||||
auto ptr = reinterpret_cast<WeaponT *>(table);
|
||||
delete ptr;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
table = nullptr;
|
||||
@@ -380,16 +565,21 @@ inline Monster *GetMutableMonster(void *buf) {
|
||||
return flatbuffers::GetMutableRoot<Monster>(buf);
|
||||
}
|
||||
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) {
|
||||
inline bool VerifyMonsterBuffer(
|
||||
flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifyBuffer<MyGame::Sample::Monster>(nullptr);
|
||||
}
|
||||
|
||||
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Sample::Monster> root) {
|
||||
inline void FinishMonsterBuffer(
|
||||
flatbuffers::FlatBufferBuilder &fbb,
|
||||
flatbuffers::Offset<MyGame::Sample::Monster> root) {
|
||||
fbb.Finish(root);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<MonsterT> UnPackMonster(const void *buf, const flatbuffers::resolver_function_t *resolver = nullptr) {
|
||||
return std::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(resolver));
|
||||
inline std::unique_ptr<MonsterT> UnPackMonster(
|
||||
const void *buf,
|
||||
const flatbuffers::resolver_function_t *res = nullptr) {
|
||||
return std::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(res));
|
||||
}
|
||||
|
||||
} // namespace Sample
|
||||
|
||||
@@ -19,147 +19,147 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
"fmt"
|
||||
"strconv"
|
||||
sample "MyGame/Sample"
|
||||
sample "MyGame/Sample"
|
||||
"fmt"
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Example how to use Flatbuffers to create and read binary buffers.
|
||||
func main() {
|
||||
builder := flatbuffers.NewBuilder(0)
|
||||
builder := flatbuffers.NewBuilder(0)
|
||||
|
||||
// Create some weapons for our Monster ("Sword" and "Axe").
|
||||
weaponOne := builder.CreateString("Sword")
|
||||
weaponTwo := builder.CreateString("Axe")
|
||||
// Create some weapons for our Monster ("Sword" and "Axe").
|
||||
weaponOne := builder.CreateString("Sword")
|
||||
weaponTwo := builder.CreateString("Axe")
|
||||
|
||||
sample.WeaponStart(builder)
|
||||
sample.WeaponAddName(builder, weaponOne)
|
||||
sample.WeaponAddDamage(builder, 3)
|
||||
sword := sample.WeaponEnd(builder)
|
||||
sample.WeaponStart(builder)
|
||||
sample.WeaponAddName(builder, weaponOne)
|
||||
sample.WeaponAddDamage(builder, 3)
|
||||
sword := sample.WeaponEnd(builder)
|
||||
|
||||
sample.WeaponStart(builder)
|
||||
sample.WeaponAddName(builder, weaponTwo)
|
||||
sample.WeaponAddDamage(builder, 5)
|
||||
axe := sample.WeaponEnd(builder)
|
||||
sample.WeaponStart(builder)
|
||||
sample.WeaponAddName(builder, weaponTwo)
|
||||
sample.WeaponAddDamage(builder, 5)
|
||||
axe := sample.WeaponEnd(builder)
|
||||
|
||||
// Serialize the FlatBuffer data.
|
||||
name := builder.CreateString("Orc")
|
||||
// Serialize the FlatBuffer data.
|
||||
name := builder.CreateString("Orc")
|
||||
|
||||
sample.MonsterStartInventoryVector(builder, 10)
|
||||
// Note: Since we prepend the bytes, this loop iterates in reverse.
|
||||
for i := 9; i >= 0; i-- {
|
||||
builder.PrependByte(byte(i))
|
||||
}
|
||||
inv := builder.EndVector(10)
|
||||
sample.MonsterStartInventoryVector(builder, 10)
|
||||
// Note: Since we prepend the bytes, this loop iterates in reverse.
|
||||
for i := 9; i >= 0; i-- {
|
||||
builder.PrependByte(byte(i))
|
||||
}
|
||||
inv := builder.EndVector(10)
|
||||
|
||||
sample.MonsterStartWeaponsVector(builder, 2)
|
||||
// Note: Since we prepend the weapons, prepend in reverse order.
|
||||
builder.PrependUOffsetT(axe)
|
||||
builder.PrependUOffsetT(sword)
|
||||
weapons := builder.EndVector(2)
|
||||
sample.MonsterStartWeaponsVector(builder, 2)
|
||||
// Note: Since we prepend the weapons, prepend in reverse order.
|
||||
builder.PrependUOffsetT(axe)
|
||||
builder.PrependUOffsetT(sword)
|
||||
weapons := builder.EndVector(2)
|
||||
|
||||
pos := sample.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||
pos := sample.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||
|
||||
sample.MonsterStart(builder)
|
||||
sample.MonsterAddPos(builder, pos)
|
||||
sample.MonsterAddHp(builder, 300)
|
||||
sample.MonsterAddName(builder, name)
|
||||
sample.MonsterAddInventory(builder, inv)
|
||||
sample.MonsterAddColor(builder, sample.ColorRed)
|
||||
sample.MonsterAddWeapons(builder, weapons)
|
||||
sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
|
||||
sample.MonsterAddEquipped(builder, axe)
|
||||
orc := sample.MonsterEnd(builder)
|
||||
sample.MonsterStart(builder)
|
||||
sample.MonsterAddPos(builder, pos)
|
||||
sample.MonsterAddHp(builder, 300)
|
||||
sample.MonsterAddName(builder, name)
|
||||
sample.MonsterAddInventory(builder, inv)
|
||||
sample.MonsterAddColor(builder, sample.ColorRed)
|
||||
sample.MonsterAddWeapons(builder, weapons)
|
||||
sample.MonsterAddEquippedType(builder, sample.EquipmentWeapon)
|
||||
sample.MonsterAddEquipped(builder, axe)
|
||||
orc := sample.MonsterEnd(builder)
|
||||
|
||||
builder.Finish(orc)
|
||||
builder.Finish(orc)
|
||||
|
||||
// We now have a FlatBuffer that we could store on disk or send over a network.
|
||||
// We now have a FlatBuffer that we could store on disk or send over a network.
|
||||
|
||||
// ...Saving to file or sending over a network code goes here...
|
||||
// ...Saving to file or sending over a network code goes here...
|
||||
|
||||
// Instead, we are going to access this buffer right away (as if we just received it).
|
||||
// Instead, we are going to access this buffer right away (as if we just received it).
|
||||
|
||||
buf := builder.FinishedBytes()
|
||||
buf := builder.FinishedBytes()
|
||||
|
||||
// Note: We use `0` for the offset here, since we got the data using the
|
||||
// `builder.FinishedBytes()` method. This simulates the data you would store/receive in your
|
||||
// FlatBuffer. If you wanted to read from the `builder.Bytes` directly, you would need to
|
||||
// pass in the offset of `builder.Head()`, as the builder actually constructs the buffer
|
||||
// backwards.
|
||||
monster := sample.GetRootAsMonster(buf, 0)
|
||||
// Note: We use `0` for the offset here, since we got the data using the
|
||||
// `builder.FinishedBytes()` method. This simulates the data you would store/receive in your
|
||||
// FlatBuffer. If you wanted to read from the `builder.Bytes` directly, you would need to
|
||||
// pass in the offset of `builder.Head()`, as the builder actually constructs the buffer
|
||||
// backwards.
|
||||
monster := sample.GetRootAsMonster(buf, 0)
|
||||
|
||||
// Note: We did not set the `mana` field explicitly, so we get the
|
||||
// default value.
|
||||
assert(monster.Mana() == 150, "`monster.Mana()`", strconv.Itoa(int(monster.Mana())), "150")
|
||||
assert(monster.Hp() == 300, "`monster.Hp()`", strconv.Itoa(int(monster.Hp())), "300")
|
||||
assert(string(monster.Name()) == "Orc", "`string(monster.Name())`", string(monster.Name()),
|
||||
"\"Orc\"")
|
||||
assert(monster.Color() == sample.ColorRed, "`monster.Color()`",
|
||||
strconv.Itoa(int(monster.Color())), strconv.Itoa(int(sample.ColorRed)))
|
||||
// Note: We did not set the `mana` field explicitly, so we get the
|
||||
// default value.
|
||||
assert(monster.Mana() == 150, "`monster.Mana()`", strconv.Itoa(int(monster.Mana())), "150")
|
||||
assert(monster.Hp() == 300, "`monster.Hp()`", strconv.Itoa(int(monster.Hp())), "300")
|
||||
assert(string(monster.Name()) == "Orc", "`string(monster.Name())`", string(monster.Name()),
|
||||
"\"Orc\"")
|
||||
assert(monster.Color() == sample.ColorRed, "`monster.Color()`",
|
||||
strconv.Itoa(int(monster.Color())), strconv.Itoa(int(sample.ColorRed)))
|
||||
|
||||
// Note: Whenever you access a new object, like in `Pos()`, a new temporary accessor object
|
||||
// gets created. If your code is very performance sensitive, you can pass in a pointer to an
|
||||
// existing `Vec3` instead of `nil`. This allows you to reuse it across many calls to reduce
|
||||
// the amount of object allocation/garbage collection.
|
||||
assert(monster.Pos(nil).X() == 1.0, "`monster.Pos(nil).X()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).X()), 'f', 1, 32), "1.0")
|
||||
assert(monster.Pos(nil).Y() == 2.0, "`monster.Pos(nil).Y()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).Y()), 'f', 1, 32), "2.0")
|
||||
assert(monster.Pos(nil).Z() == 3.0, "`monster.Pos(nil).Z()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).Z()), 'f', 1, 32), "3.0")
|
||||
// Note: Whenever you access a new object, like in `Pos()`, a new temporary accessor object
|
||||
// gets created. If your code is very performance sensitive, you can pass in a pointer to an
|
||||
// existing `Vec3` instead of `nil`. This allows you to reuse it across many calls to reduce
|
||||
// the amount of object allocation/garbage collection.
|
||||
assert(monster.Pos(nil).X() == 1.0, "`monster.Pos(nil).X()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).X()), 'f', 1, 32), "1.0")
|
||||
assert(monster.Pos(nil).Y() == 2.0, "`monster.Pos(nil).Y()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).Y()), 'f', 1, 32), "2.0")
|
||||
assert(monster.Pos(nil).Z() == 3.0, "`monster.Pos(nil).Z()`",
|
||||
strconv.FormatFloat(float64(monster.Pos(nil).Z()), 'f', 1, 32), "3.0")
|
||||
|
||||
// For vectors, like `Inventory`, they have a method suffixed with 'Length' that can be used
|
||||
// to query the length of the vector. You can index the vector by passing an index value
|
||||
// into the accessor.
|
||||
for i := 0; i < monster.InventoryLength(); i++ {
|
||||
assert(monster.Inventory(i) == byte(i), "`monster.Inventory(i)`",
|
||||
strconv.Itoa(int(monster.Inventory(i))), strconv.Itoa(int(byte(i))))
|
||||
}
|
||||
// For vectors, like `Inventory`, they have a method suffixed with 'Length' that can be used
|
||||
// to query the length of the vector. You can index the vector by passing an index value
|
||||
// into the accessor.
|
||||
for i := 0; i < monster.InventoryLength(); i++ {
|
||||
assert(monster.Inventory(i) == byte(i), "`monster.Inventory(i)`",
|
||||
strconv.Itoa(int(monster.Inventory(i))), strconv.Itoa(int(byte(i))))
|
||||
}
|
||||
|
||||
expectedWeaponNames := []string{"Sword", "Axe"}
|
||||
expectedWeaponDamages := []int{3, 5}
|
||||
weapon := new(sample.Weapon) // We need a `sample.Weapon` to pass into `monster.Weapons()`
|
||||
// to capture the output of that function.
|
||||
for i := 0; i < monster.WeaponsLength(); i++ {
|
||||
if monster.Weapons(weapon, i) {
|
||||
assert(string(weapon.Name()) == expectedWeaponNames[i], "`weapon.Name()`",
|
||||
string(weapon.Name()), expectedWeaponNames[i])
|
||||
assert(int(weapon.Damage()) == expectedWeaponDamages[i],
|
||||
"`weapon.Damage()`", strconv.Itoa(int(weapon.Damage())),
|
||||
strconv.Itoa(expectedWeaponDamages[i]))
|
||||
}
|
||||
}
|
||||
expectedWeaponNames := []string{"Sword", "Axe"}
|
||||
expectedWeaponDamages := []int{3, 5}
|
||||
weapon := new(sample.Weapon) // We need a `sample.Weapon` to pass into `monster.Weapons()`
|
||||
// to capture the output of that function.
|
||||
for i := 0; i < monster.WeaponsLength(); i++ {
|
||||
if monster.Weapons(weapon, i) {
|
||||
assert(string(weapon.Name()) == expectedWeaponNames[i], "`weapon.Name()`",
|
||||
string(weapon.Name()), expectedWeaponNames[i])
|
||||
assert(int(weapon.Damage()) == expectedWeaponDamages[i],
|
||||
"`weapon.Damage()`", strconv.Itoa(int(weapon.Damage())),
|
||||
strconv.Itoa(expectedWeaponDamages[i]))
|
||||
}
|
||||
}
|
||||
|
||||
// For FlatBuffer `union`s, you can get the type of the union, as well as the union
|
||||
// data itself.
|
||||
assert(monster.EquippedType() == sample.EquipmentWeapon, "`monster.EquippedType()`",
|
||||
strconv.Itoa(int(monster.EquippedType())), strconv.Itoa(int(sample.EquipmentWeapon)))
|
||||
// For FlatBuffer `union`s, you can get the type of the union, as well as the union
|
||||
// data itself.
|
||||
assert(monster.EquippedType() == sample.EquipmentWeapon, "`monster.EquippedType()`",
|
||||
strconv.Itoa(int(monster.EquippedType())), strconv.Itoa(int(sample.EquipmentWeapon)))
|
||||
|
||||
unionTable := new(flatbuffers.Table)
|
||||
if monster.Equipped(unionTable) {
|
||||
// An example of how you can appropriately convert the table depending on the
|
||||
// FlatBuffer `union` type. You could add `else if` and `else` clauses to handle
|
||||
// other FlatBuffer `union` types for this field. (Similarly, this could be
|
||||
// done in a switch statement.)
|
||||
if monster.EquippedType() == sample.EquipmentWeapon {
|
||||
unionWeapon := new(sample.Weapon)
|
||||
unionWeapon.Init(unionTable.Bytes, unionTable.Pos)
|
||||
unionTable := new(flatbuffers.Table)
|
||||
if monster.Equipped(unionTable) {
|
||||
// An example of how you can appropriately convert the table depending on the
|
||||
// FlatBuffer `union` type. You could add `else if` and `else` clauses to handle
|
||||
// other FlatBuffer `union` types for this field. (Similarly, this could be
|
||||
// done in a switch statement.)
|
||||
if monster.EquippedType() == sample.EquipmentWeapon {
|
||||
unionWeapon := new(sample.Weapon)
|
||||
unionWeapon.Init(unionTable.Bytes, unionTable.Pos)
|
||||
|
||||
assert(string(unionWeapon.Name()) == "Axe", "`unionWeapon.Name()`",
|
||||
string(unionWeapon.Name()), "Axe")
|
||||
assert(int(unionWeapon.Damage()) == 5, "`unionWeapon.Damage()`",
|
||||
strconv.Itoa(int(unionWeapon.Damage())), strconv.Itoa(5))
|
||||
}
|
||||
}
|
||||
assert(string(unionWeapon.Name()) == "Axe", "`unionWeapon.Name()`",
|
||||
string(unionWeapon.Name()), "Axe")
|
||||
assert(int(unionWeapon.Damage()) == 5, "`unionWeapon.Damage()`",
|
||||
strconv.Itoa(int(unionWeapon.Damage())), strconv.Itoa(5))
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("The FlatBuffer was successfully created and verified!\n")
|
||||
fmt.Printf("The FlatBuffer was successfully created and verified!\n")
|
||||
}
|
||||
|
||||
// A helper function to print out if an assertion failed.
|
||||
func assert(assertPassed bool, codeExecuted string, actualValue string, expectedValue string) {
|
||||
if assertPassed == false {
|
||||
panic("Assert failed! " + codeExecuted + " (" + actualValue +
|
||||
") was not equal to " + expectedValue + ".")
|
||||
}
|
||||
if assertPassed == false {
|
||||
panic("Assert failed! " + codeExecuted + " (" + actualValue +
|
||||
") was not equal to " + expectedValue + ".")
|
||||
}
|
||||
}
|
||||
|
||||
158
src/code_generators.cpp
Normal file
158
src/code_generators.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2016 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "flatbuffers/code_generators.h"
|
||||
#include <assert.h>
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
void CodeWriter::operator+=(std::string text) {
|
||||
|
||||
while (true) {
|
||||
auto begin = text.find("{{");
|
||||
if (begin == std::string::npos) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto end = text.find("}}");
|
||||
if (end == std::string::npos || end < begin) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Write all the text before the first {{ into the stream.
|
||||
stream_.write(text.c_str(), begin);
|
||||
|
||||
// The key is between the {{ and }}.
|
||||
const std::string key = text.substr(begin + 2, end - begin - 2);
|
||||
|
||||
// Find the value associated with the key. If it exists, write the
|
||||
// value into the stream, otherwise write the key itself into the stream.
|
||||
auto iter = value_map_.find(key);
|
||||
if (iter != value_map_.end()) {
|
||||
const std::string &value = iter->second;
|
||||
stream_ << value;
|
||||
} else {
|
||||
assert(false && "could not find key");
|
||||
stream_ << key;
|
||||
}
|
||||
|
||||
// Update the text to everything after the }}.
|
||||
text = text.substr(end + 2);
|
||||
}
|
||||
if (!text.empty() && text.back() == '\\') {
|
||||
text.pop_back();
|
||||
stream_ << text;
|
||||
} else {
|
||||
stream_ << text << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
const char *BaseGenerator::FlatBuffersGeneratedWarning() {
|
||||
return "automatically generated by the FlatBuffers compiler,"
|
||||
" do not modify\n\n";
|
||||
}
|
||||
|
||||
std::string BaseGenerator::NamespaceDir(const Parser &parser,
|
||||
const std::string &path,
|
||||
const Namespace &ns) {
|
||||
EnsureDirExists(path.c_str());
|
||||
if (parser.opts.one_file) return path;
|
||||
std::string namespace_dir = path; // Either empty or ends in separator.
|
||||
auto &namespaces = ns.components;
|
||||
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
||||
namespace_dir += *it + kPathSeparator;
|
||||
EnsureDirExists(namespace_dir.c_str());
|
||||
}
|
||||
return namespace_dir;
|
||||
}
|
||||
|
||||
std::string BaseGenerator::NamespaceDir(const Namespace &ns) const {
|
||||
return BaseGenerator::NamespaceDir(parser_, path_, ns);
|
||||
}
|
||||
|
||||
bool BaseGenerator::IsEverythingGenerated() const {
|
||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||
++it) {
|
||||
if (!(*it)->generated) return false;
|
||||
}
|
||||
for (auto it = parser_.structs_.vec.begin();
|
||||
it != parser_.structs_.vec.end(); ++it) {
|
||||
if (!(*it)->generated) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string BaseGenerator::FullNamespace(const char *separator,
|
||||
const Namespace &ns) {
|
||||
std::string namespace_name;
|
||||
auto &namespaces = ns.components;
|
||||
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
||||
if (namespace_name.length()) namespace_name += separator;
|
||||
namespace_name += *it;
|
||||
}
|
||||
return namespace_name;
|
||||
}
|
||||
|
||||
std::string BaseGenerator::LastNamespacePart(const Namespace &ns) {
|
||||
if (!ns.components.empty())
|
||||
return ns.components.back();
|
||||
else
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
// Ensure that a type is prefixed with its namespace whenever it is used
|
||||
// outside of its namespace.
|
||||
std::string BaseGenerator::WrapInNameSpace(const Namespace *ns,
|
||||
const std::string &name) const {
|
||||
if (CurrentNameSpace() == ns) return name;
|
||||
std::string qualified_name = qualifying_start_;
|
||||
for (auto it = ns->components.begin(); it != ns->components.end(); ++it)
|
||||
qualified_name += *it + qualifying_separator_;
|
||||
return qualified_name + name;
|
||||
}
|
||||
|
||||
|
||||
std::string BaseGenerator::WrapInNameSpace(const Definition &def) const {
|
||||
return WrapInNameSpace(def.defined_namespace, def.name);
|
||||
}
|
||||
|
||||
// Generate a documentation comment, if available.
|
||||
void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
|
||||
const CommentConfig *config, const char *prefix) {
|
||||
if (dc.begin() == dc.end()) {
|
||||
// Don't output empty comment blocks with 0 lines of comment content.
|
||||
return;
|
||||
}
|
||||
|
||||
std::string &code = *code_ptr;
|
||||
if (config != nullptr && config->first_line != nullptr) {
|
||||
code += std::string(prefix) + std::string(config->first_line) + "\n";
|
||||
}
|
||||
std::string line_prefix = std::string(prefix) +
|
||||
((config != nullptr && config->content_line_prefix != nullptr) ?
|
||||
config->content_line_prefix : "///");
|
||||
for (auto it = dc.begin();
|
||||
it != dc.end();
|
||||
++it) {
|
||||
code += line_prefix + *it + "\n";
|
||||
}
|
||||
if (config != nullptr && config->last_line != nullptr) {
|
||||
code += std::string(prefix) + std::string(config->last_line) + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
243
src/flatc.cpp
243
src/flatc.cpp
@@ -14,105 +14,50 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
#include <limits>
|
||||
#include "flatbuffers/flatc.h"
|
||||
|
||||
#define FLATC_VERSION "1.5.0 (" __DATE__ ")"
|
||||
#define FLATC_VERSION "1.6.0 (" __DATE__ ")"
|
||||
|
||||
static void Error(const std::string &err, bool usage = false,
|
||||
bool show_exe_name = true);
|
||||
namespace flatbuffers {
|
||||
|
||||
// This struct allows us to create a table of all possible output generators
|
||||
// for the various programming languages and formats we support.
|
||||
struct Generator {
|
||||
bool (*generate)(const flatbuffers::Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
const char *generator_opt_short;
|
||||
const char *generator_opt_long;
|
||||
const char *lang_name;
|
||||
bool (*generateGRPC)(const flatbuffers::Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
flatbuffers::IDLOptions::Language lang;
|
||||
const char *generator_help;
|
||||
|
||||
std::string (*make_rule)(const flatbuffers::Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
};
|
||||
|
||||
const Generator generators[] = {
|
||||
{ flatbuffers::GenerateBinary, "-b", "--binary", "binary",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate wire format binaries for any data definitions",
|
||||
flatbuffers::BinaryMakeRule },
|
||||
{ flatbuffers::GenerateTextFile, "-t", "--json", "text",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate text output for any data definitions",
|
||||
flatbuffers::TextMakeRule },
|
||||
{ flatbuffers::GenerateCPP, "-c", "--cpp", "C++",
|
||||
flatbuffers::GenerateCppGRPC,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate C++ headers for tables/structs",
|
||||
flatbuffers::CPPMakeRule },
|
||||
{ flatbuffers::GenerateGo, "-g", "--go", "Go",
|
||||
flatbuffers::GenerateGoGRPC,
|
||||
flatbuffers::IDLOptions::kGo,
|
||||
"Generate Go files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateGeneral, "-j", "--java", "Java",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kJava,
|
||||
"Generate Java classes for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateJS, "-s", "--js", "JavaScript",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate JavaScript code for tables/structs",
|
||||
flatbuffers::JSMakeRule },
|
||||
{ flatbuffers::GenerateGeneral, "-n", "--csharp", "C#",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kCSharp,
|
||||
"Generate C# classes for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GeneratePython, "-p", "--python", "Python",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate Python files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate PHP files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
};
|
||||
|
||||
const char *g_program_name = nullptr;
|
||||
flatbuffers::Parser *g_parser = nullptr;
|
||||
|
||||
static void Warn(const std::string &warn, bool show_exe_name = true) {
|
||||
if (show_exe_name) printf("%s: ", g_program_name);
|
||||
printf("warning: %s\n", warn.c_str());
|
||||
void FlatCompiler::ParseFile(
|
||||
flatbuffers::Parser &parser,
|
||||
const std::string &filename,
|
||||
const std::string &contents,
|
||||
std::vector<const char *> &include_directories) const {
|
||||
auto local_include_directory = flatbuffers::StripFileName(filename);
|
||||
include_directories.push_back(local_include_directory.c_str());
|
||||
include_directories.push_back(nullptr);
|
||||
if (!parser.Parse(contents.c_str(), &include_directories[0],
|
||||
filename.c_str()))
|
||||
Error(parser.error_, false, false);
|
||||
include_directories.pop_back();
|
||||
include_directories.pop_back();
|
||||
}
|
||||
|
||||
static void Error(const std::string &err, bool usage, bool show_exe_name) {
|
||||
if (show_exe_name) printf("%s: ", g_program_name);
|
||||
printf("error: %s\n", err.c_str());
|
||||
if (usage) {
|
||||
printf("usage: %s [OPTION]... FILE... [-- FILE...]\n", g_program_name);
|
||||
for (size_t i = 0; i < sizeof(generators) / sizeof(generators[0]); ++i)
|
||||
printf(" %-12s %s %s.\n",
|
||||
generators[i].generator_opt_long,
|
||||
generators[i].generator_opt_short
|
||||
? generators[i].generator_opt_short
|
||||
: " ",
|
||||
generators[i].generator_help);
|
||||
printf(
|
||||
void FlatCompiler::Warn(const std::string &warn, bool show_exe_name) const {
|
||||
params_.warn_fn(this, warn, show_exe_name);
|
||||
}
|
||||
|
||||
void FlatCompiler::Error(const std::string &err, bool usage,
|
||||
bool show_exe_name) const {
|
||||
params_.error_fn(this, err, usage, show_exe_name);
|
||||
}
|
||||
|
||||
std::string FlatCompiler::GetUsageString(const char* program_name) const {
|
||||
std::stringstream ss;
|
||||
ss << "Usageaa: " << program_name << " [OPTION]... FILE... [-- FILE...]\n";
|
||||
for (size_t i = 0; i < params_.num_generators; ++i) {
|
||||
const Generator& g = params_.generators[i];
|
||||
|
||||
std::stringstream full_name;
|
||||
full_name << std::setw(12) << std::left << g.generator_opt_long;
|
||||
const char *name = g.generator_opt_short ? g.generator_opt_short : " ";
|
||||
const char *help = g.generator_help;
|
||||
|
||||
ss << " " << full_name.str() << " " << name << " " << help << ".\n";
|
||||
}
|
||||
ss <<
|
||||
" -o PATH Prefix PATH to all generated files.\n"
|
||||
" -I PATH Search for includes in the specified path.\n"
|
||||
" -M Print make rules for generated files.\n"
|
||||
@@ -141,45 +86,36 @@ static void Error(const std::string &err, bool usage, bool show_exe_name) {
|
||||
" --escape-proto-ids Disable appending '_' in namespaces names.\n"
|
||||
" --gen-object-api Generate an additional object-based API.\n"
|
||||
" --cpp-ptr-type T Set object API pointer type (default std::unique_ptr)\n"
|
||||
" --no-js-exports Removes Node.js style export lines in JS.\n"
|
||||
" --goog-js-export Uses goog.exports* for closure compiler exporting in JS.\n"
|
||||
" --raw-binary Allow binaries without file_indentifier to be read.\n"
|
||||
" This may crash flatc given a mismatched schema.\n"
|
||||
" --proto Input is a .proto, translate to .fbs.\n"
|
||||
" --grpc Generate GRPC interfaces for the specified languages\n"
|
||||
" --schema Serialize schemas instead of JSON (use with -b)\n"
|
||||
" --bfbs-comments Add doc comments to the binary schema files.\n"
|
||||
" --conform FILE Specify a schema the following schemas should be\n"
|
||||
" an evolution of. Gives errors if not.\n"
|
||||
" --conform-includes Include path for the schema given with --conform\n"
|
||||
" PATH \n"
|
||||
" --include-prefix Prefix this path to any generated include statements.\n"
|
||||
" PATH\n"
|
||||
"FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
|
||||
"FILEs after the -- must be binary flatbuffer format files.\n"
|
||||
"Output files are named using the base file name of the input,\n"
|
||||
"and written to the current directory or the path given by -o.\n"
|
||||
"example: %s -c -b schema1.fbs schema2.fbs data.json\n",
|
||||
g_program_name);
|
||||
"example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
int FlatCompiler::Compile(int argc, const char** argv) {
|
||||
if (params_.generators == nullptr || params_.num_generators == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (g_parser) delete g_parser;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void ParseFile(flatbuffers::Parser &parser, const std::string &filename,
|
||||
const std::string &contents,
|
||||
std::vector<const char *> &include_directories) {
|
||||
auto local_include_directory = flatbuffers::StripFileName(filename);
|
||||
include_directories.push_back(local_include_directory.c_str());
|
||||
include_directories.push_back(nullptr);
|
||||
if (!parser.Parse(contents.c_str(), &include_directories[0],
|
||||
filename.c_str()))
|
||||
Error(parser.error_, false, false);
|
||||
include_directories.pop_back();
|
||||
include_directories.pop_back();
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
g_program_name = argv[0];
|
||||
flatbuffers::IDLOptions opts;
|
||||
std::string output_path;
|
||||
const size_t num_generators = sizeof(generators) / sizeof(generators[0]);
|
||||
bool generator_enabled[num_generators] = { false };
|
||||
|
||||
bool any_generator = false;
|
||||
bool print_make_rules = false;
|
||||
bool raw_binary = false;
|
||||
@@ -188,9 +124,11 @@ int main(int argc, const char *argv[]) {
|
||||
std::vector<std::string> filenames;
|
||||
std::vector<const char *> include_directories;
|
||||
std::vector<const char *> conform_include_directories;
|
||||
std::vector<bool> generator_enabled(params_.num_generators, false);
|
||||
size_t binary_files_from = std::numeric_limits<size_t>::max();
|
||||
std::string conform_to_schema;
|
||||
for (int argi = 1; argi < argc; argi++) {
|
||||
|
||||
for (int argi = 0; argi < argc; argi++) {
|
||||
std::string arg = argv[argi];
|
||||
if (arg[0] == '-') {
|
||||
if (filenames.size() && arg[1] != '-')
|
||||
@@ -207,12 +145,19 @@ int main(int argc, const char *argv[]) {
|
||||
} else if (arg == "--conform-includes") {
|
||||
if (++argi >= argc) Error("missing path following" + arg, true);
|
||||
conform_include_directories.push_back(argv[argi]);
|
||||
} else if (arg == "--include-prefix") {
|
||||
if (++argi >= argc) Error("missing path following" + arg, true);
|
||||
opts.include_prefix = argv[argi];
|
||||
if (opts.include_prefix.back() != '/' &&
|
||||
opts.include_prefix.back() != '\\') opts.include_prefix += "/";
|
||||
} else if(arg == "--strict-json") {
|
||||
opts.strict_json = true;
|
||||
} else if(arg == "--allow-non-utf8") {
|
||||
opts.allow_non_utf8 = true;
|
||||
} else if(arg == "--no-js-exports") {
|
||||
opts.skip_js_exports = true;
|
||||
} else if(arg == "--goog-js-export") {
|
||||
opts.use_goog_js_export_format = true;
|
||||
} else if(arg == "--defaults-json") {
|
||||
opts.output_default_scalars_in_json = true;
|
||||
} else if (arg == "--unknown-json") {
|
||||
@@ -260,13 +205,16 @@ int main(int argc, const char *argv[]) {
|
||||
exit(0);
|
||||
} else if(arg == "--grpc") {
|
||||
grpc_enabled = true;
|
||||
} else if(arg == "--bfbs-comments") {
|
||||
opts.binary_schema_comments = true;
|
||||
} else {
|
||||
for (size_t i = 0; i < num_generators; ++i) {
|
||||
if (arg == generators[i].generator_opt_long ||
|
||||
(generators[i].generator_opt_short &&
|
||||
arg == generators[i].generator_opt_short)) {
|
||||
for (size_t i = 0; i < params_.num_generators; ++i) {
|
||||
if (arg == params_.generators[i].generator_opt_long ||
|
||||
(params_.generators[i].generator_opt_short &&
|
||||
arg == params_.generators[i].generator_opt_short)) {
|
||||
generator_enabled[i] = true;
|
||||
any_generator = true;
|
||||
opts.lang_to_generate |= params_.generators[i].lang;
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
@@ -296,8 +244,8 @@ int main(int argc, const char *argv[]) {
|
||||
conform_include_directories);
|
||||
}
|
||||
|
||||
// Now process the files:
|
||||
g_parser = new flatbuffers::Parser(opts);
|
||||
std::unique_ptr<flatbuffers::Parser> parser(new flatbuffers::Parser(opts));
|
||||
|
||||
for (auto file_it = filenames.begin();
|
||||
file_it != filenames.end();
|
||||
++file_it) {
|
||||
@@ -308,8 +256,8 @@ int main(int argc, const char *argv[]) {
|
||||
bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
|
||||
binary_files_from;
|
||||
if (is_binary) {
|
||||
g_parser->builder_.Clear();
|
||||
g_parser->builder_.PushFlatBuffer(
|
||||
parser->builder_.Clear();
|
||||
parser->builder_.PushFlatBuffer(
|
||||
reinterpret_cast<const uint8_t *>(contents.c_str()),
|
||||
contents.length());
|
||||
if (!raw_binary) {
|
||||
@@ -318,17 +266,17 @@ int main(int argc, const char *argv[]) {
|
||||
// does not contain a file identifier.
|
||||
// We'd expect that typically any binary used as a file would have
|
||||
// such an identifier, so by default we require them to match.
|
||||
if (!g_parser->file_identifier_.length()) {
|
||||
if (!parser->file_identifier_.length()) {
|
||||
Error("current schema has no file_identifier: cannot test if \"" +
|
||||
*file_it +
|
||||
"\" matches the schema, use --raw-binary to read this file"
|
||||
" anyway.");
|
||||
} else if (!flatbuffers::BufferHasIdentifier(contents.c_str(),
|
||||
g_parser->file_identifier_.c_str())) {
|
||||
parser->file_identifier_.c_str())) {
|
||||
Error("binary \"" +
|
||||
*file_it +
|
||||
"\" does not have expected file_identifier \"" +
|
||||
g_parser->file_identifier_ +
|
||||
parser->file_identifier_ +
|
||||
"\", use --raw-binary to read this file anyway.");
|
||||
}
|
||||
}
|
||||
@@ -342,63 +290,62 @@ int main(int argc, const char *argv[]) {
|
||||
// If we're processing multiple schemas, make sure to start each
|
||||
// one from scratch. If it depends on previous schemas it must do
|
||||
// so explicitly using an include.
|
||||
delete g_parser;
|
||||
g_parser = new flatbuffers::Parser(opts);
|
||||
parser.reset(new flatbuffers::Parser(opts));
|
||||
}
|
||||
ParseFile(*g_parser, *file_it, contents, include_directories);
|
||||
ParseFile(*parser.get(), *file_it, contents, include_directories);
|
||||
if (is_schema && !conform_to_schema.empty()) {
|
||||
auto err = g_parser->ConformTo(conform_parser);
|
||||
auto err = parser->ConformTo(conform_parser);
|
||||
if (!err.empty()) Error("schemas don\'t conform: " + err);
|
||||
}
|
||||
if (schema_binary) {
|
||||
g_parser->Serialize();
|
||||
g_parser->file_extension_ = reflection::SchemaExtension();
|
||||
parser->Serialize();
|
||||
parser->file_extension_ = reflection::SchemaExtension();
|
||||
}
|
||||
}
|
||||
|
||||
std::string filebase = flatbuffers::StripPath(
|
||||
flatbuffers::StripExtension(*file_it));
|
||||
|
||||
for (size_t i = 0; i < num_generators; ++i) {
|
||||
g_parser->opts.lang = generators[i].lang;
|
||||
for (size_t i = 0; i < params_.num_generators; ++i) {
|
||||
parser->opts.lang = params_.generators[i].lang;
|
||||
if (generator_enabled[i]) {
|
||||
if (!print_make_rules) {
|
||||
flatbuffers::EnsureDirExists(output_path);
|
||||
if (!generators[i].generate(*g_parser, output_path, filebase)) {
|
||||
if (!params_.generators[i].generate(*parser.get(), output_path, filebase)) {
|
||||
Error(std::string("Unable to generate ") +
|
||||
generators[i].lang_name +
|
||||
params_.generators[i].lang_name +
|
||||
" for " +
|
||||
filebase);
|
||||
}
|
||||
} else {
|
||||
std::string make_rule = generators[i].make_rule(
|
||||
*g_parser, output_path, *file_it);
|
||||
std::string make_rule = params_.generators[i].make_rule(
|
||||
*parser.get(), output_path, *file_it);
|
||||
if (!make_rule.empty())
|
||||
printf("%s\n", flatbuffers::WordWrap(
|
||||
make_rule, 80, " ", " \\").c_str());
|
||||
}
|
||||
if (grpc_enabled) {
|
||||
if (generators[i].generateGRPC != nullptr) {
|
||||
if (!generators[i].generateGRPC(*g_parser, output_path,
|
||||
if (params_.generators[i].generateGRPC != nullptr) {
|
||||
if (!params_.generators[i].generateGRPC(*parser.get(), output_path,
|
||||
filebase)) {
|
||||
Error(std::string("Unable to generate GRPC interface for") +
|
||||
generators[i].lang_name);
|
||||
params_.generators[i].lang_name);
|
||||
}
|
||||
} else {
|
||||
Warn(std::string("GRPC interface generator not implemented for ")
|
||||
+ generators[i].lang_name);
|
||||
+ params_.generators[i].lang_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.proto_mode) GenerateFBS(*g_parser, output_path, filebase);
|
||||
if (opts.proto_mode) GenerateFBS(*parser.get(), output_path, filebase);
|
||||
|
||||
// We do not want to generate code for the definitions in this file
|
||||
// in any files coming up next.
|
||||
g_parser->MarkGenerated();
|
||||
parser->MarkGenerated();
|
||||
}
|
||||
|
||||
delete g_parser;
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
104
src/flatc_main.cpp
Normal file
104
src/flatc_main.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "flatbuffers/flatc.h"
|
||||
|
||||
static const char *g_program_name = nullptr;
|
||||
|
||||
static void Warn(const flatbuffers::FlatCompiler *flatc,
|
||||
const std::string &warn,
|
||||
bool show_exe_name) {
|
||||
(void)flatc;
|
||||
if (show_exe_name) {
|
||||
printf("%s: ", g_program_name);
|
||||
}
|
||||
printf("warning: %s\n", warn.c_str());
|
||||
}
|
||||
|
||||
static void Error(const flatbuffers::FlatCompiler *flatc,
|
||||
const std::string &err,
|
||||
bool usage,
|
||||
bool show_exe_name) {
|
||||
if (show_exe_name) {
|
||||
printf("%s: ", g_program_name);
|
||||
}
|
||||
printf("error: %s\n", err.c_str());
|
||||
if (usage) {
|
||||
printf("%s", flatc->GetUsageString(g_program_name).c_str());
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
g_program_name = argv[0];
|
||||
|
||||
const flatbuffers::FlatCompiler::Generator generators[] = {
|
||||
{ flatbuffers::GenerateBinary, "-b", "--binary", "binary",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kBinary,
|
||||
"Generate wire format binaries for any data definitions",
|
||||
flatbuffers::BinaryMakeRule },
|
||||
{ flatbuffers::GenerateTextFile, "-t", "--json", "text",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kJson,
|
||||
"Generate text output for any data definitions",
|
||||
flatbuffers::TextMakeRule },
|
||||
{ flatbuffers::GenerateCPP, "-c", "--cpp", "C++",
|
||||
flatbuffers::GenerateCppGRPC,
|
||||
flatbuffers::IDLOptions::kCpp,
|
||||
"Generate C++ headers for tables/structs",
|
||||
flatbuffers::CPPMakeRule },
|
||||
{ flatbuffers::GenerateGo, "-g", "--go", "Go",
|
||||
flatbuffers::GenerateGoGRPC,
|
||||
flatbuffers::IDLOptions::kGo,
|
||||
"Generate Go files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateGeneral, "-j", "--java", "Java",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kJava,
|
||||
"Generate Java classes for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateJS, "-s", "--js", "JavaScript",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kJs,
|
||||
"Generate JavaScript code for tables/structs",
|
||||
flatbuffers::JSMakeRule },
|
||||
{ flatbuffers::GenerateGeneral, "-n", "--csharp", "C#",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kCSharp,
|
||||
"Generate C# classes for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GeneratePython, "-p", "--python", "Python",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kPython,
|
||||
"Generate Python files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kPhp,
|
||||
"Generate PHP files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
};
|
||||
|
||||
flatbuffers::FlatCompiler::InitParams params;
|
||||
params.generators = generators;
|
||||
params.num_generators = sizeof(generators) / sizeof(generators[0]);
|
||||
params.warn_fn = Warn;
|
||||
params.error_fn = Error;
|
||||
|
||||
flatbuffers::FlatCompiler flatc(params);
|
||||
return flatc.Compile(argc - 1, argv + 1);
|
||||
}
|
||||
2234
src/idl_gen_cpp.cpp
2234
src/idl_gen_cpp.cpp
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,7 @@
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
#include "flatbuffers/code_generators.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
|
||||
@@ -39,37 +39,6 @@ std::string MakeCamel(const std::string &in, bool first) {
|
||||
return s;
|
||||
}
|
||||
|
||||
struct CommentConfig {
|
||||
const char *first_line;
|
||||
const char *content_line_prefix;
|
||||
const char *last_line;
|
||||
};
|
||||
|
||||
// Generate a documentation comment, if available.
|
||||
void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
|
||||
const CommentConfig *config, const char *prefix) {
|
||||
if (dc.begin() == dc.end()) {
|
||||
// Don't output empty comment blocks with 0 lines of comment content.
|
||||
return;
|
||||
}
|
||||
|
||||
std::string &code = *code_ptr;
|
||||
if (config != nullptr && config->first_line != nullptr) {
|
||||
code += std::string(prefix) + std::string(config->first_line) + "\n";
|
||||
}
|
||||
std::string line_prefix = std::string(prefix) +
|
||||
((config != nullptr && config->content_line_prefix != nullptr) ?
|
||||
config->content_line_prefix : "///");
|
||||
for (auto it = dc.begin();
|
||||
it != dc.end();
|
||||
++it) {
|
||||
code += line_prefix + *it + "\n";
|
||||
}
|
||||
if (config != nullptr && config->last_line != nullptr) {
|
||||
code += std::string(prefix) + std::string(config->last_line) + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// These arrays need to correspond to the IDLOptions::k enum.
|
||||
|
||||
struct LanguageParameters {
|
||||
@@ -101,108 +70,80 @@ struct LanguageParameters {
|
||||
CommentConfig comment_config;
|
||||
};
|
||||
|
||||
LanguageParameters language_parameters[] = {
|
||||
{
|
||||
IDLOptions::kJava,
|
||||
false,
|
||||
".java",
|
||||
"String",
|
||||
"boolean ",
|
||||
" {\n",
|
||||
"class ",
|
||||
" final ",
|
||||
"final ",
|
||||
"final class ",
|
||||
";\n",
|
||||
"()",
|
||||
"",
|
||||
" extends ",
|
||||
"package ",
|
||||
";",
|
||||
"",
|
||||
"_bb.order(ByteOrder.LITTLE_ENDIAN); ",
|
||||
"position()",
|
||||
"offset()",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\n"
|
||||
"import com.google.flatbuffers.*;\n\n@SuppressWarnings(\"unused\")\n",
|
||||
const LanguageParameters& GetLangParams(IDLOptions::Language lang) {
|
||||
static LanguageParameters language_parameters[] = {
|
||||
{
|
||||
"/**",
|
||||
" *",
|
||||
" */",
|
||||
IDLOptions::kJava,
|
||||
false,
|
||||
".java",
|
||||
"String",
|
||||
"boolean ",
|
||||
" {\n",
|
||||
"class ",
|
||||
" final ",
|
||||
"final ",
|
||||
"final class ",
|
||||
";\n",
|
||||
"()",
|
||||
"",
|
||||
" extends ",
|
||||
"package ",
|
||||
";",
|
||||
"",
|
||||
"_bb.order(ByteOrder.LITTLE_ENDIAN); ",
|
||||
"position()",
|
||||
"offset()",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\n"
|
||||
"import com.google.flatbuffers.*;\n\n@SuppressWarnings(\"unused\")\n",
|
||||
{
|
||||
"/**",
|
||||
" *",
|
||||
" */",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
IDLOptions::kCSharp,
|
||||
true,
|
||||
".cs",
|
||||
"string",
|
||||
"bool ",
|
||||
"\n{\n",
|
||||
"struct ",
|
||||
" readonly ",
|
||||
"",
|
||||
"enum ",
|
||||
",\n",
|
||||
" { get",
|
||||
"} ",
|
||||
" : ",
|
||||
"namespace ",
|
||||
"\n{",
|
||||
"\n}\n",
|
||||
"",
|
||||
"Position",
|
||||
"Offset",
|
||||
"__p.",
|
||||
"Table.",
|
||||
"?",
|
||||
"using System;\nusing FlatBuffers;\n\n",
|
||||
{
|
||||
nullptr,
|
||||
"///",
|
||||
nullptr,
|
||||
IDLOptions::kCSharp,
|
||||
true,
|
||||
".cs",
|
||||
"string",
|
||||
"bool ",
|
||||
"\n{\n",
|
||||
"struct ",
|
||||
" readonly ",
|
||||
"",
|
||||
"enum ",
|
||||
",\n",
|
||||
" { get",
|
||||
"} ",
|
||||
" : ",
|
||||
"namespace ",
|
||||
"\n{",
|
||||
"\n}\n",
|
||||
"",
|
||||
"Position",
|
||||
"Offset",
|
||||
"__p.",
|
||||
"Table.",
|
||||
"?",
|
||||
"using System;\nusing FlatBuffers;\n\n",
|
||||
{
|
||||
nullptr,
|
||||
"///",
|
||||
nullptr,
|
||||
},
|
||||
},
|
||||
},
|
||||
// TODO: add Go support to the general generator.
|
||||
// WARNING: this is currently only used for generating make rules for Go.
|
||||
{
|
||||
IDLOptions::kGo,
|
||||
true,
|
||||
".go",
|
||||
"string",
|
||||
"bool ",
|
||||
"\n{\n",
|
||||
"class ",
|
||||
"const ",
|
||||
" ",
|
||||
"class ",
|
||||
";\n",
|
||||
"()",
|
||||
"",
|
||||
"",
|
||||
"package ",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"position()",
|
||||
"offset()",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"import (\n\tflatbuffers \"github.com/google/flatbuffers/go\"\n)",
|
||||
{
|
||||
nullptr,
|
||||
"///",
|
||||
nullptr,
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
static_assert(sizeof(language_parameters) / sizeof(LanguageParameters) ==
|
||||
IDLOptions::kMAX,
|
||||
"Please add extra elements to the arrays above.");
|
||||
if (lang == IDLOptions::kJava) {
|
||||
return language_parameters[0];
|
||||
} else {
|
||||
assert(lang == IDLOptions::kCSharp);
|
||||
return language_parameters[1];
|
||||
}
|
||||
}
|
||||
|
||||
namespace general {
|
||||
class GeneralGenerator : public BaseGenerator {
|
||||
@@ -210,10 +151,10 @@ class GeneralGenerator : public BaseGenerator {
|
||||
GeneralGenerator(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name)
|
||||
: BaseGenerator(parser, path, file_name, "", "."),
|
||||
lang_(language_parameters[parser_.opts.lang]),
|
||||
lang_(GetLangParams(parser_.opts.lang)),
|
||||
cur_name_space_( nullptr ) {
|
||||
assert(parser_.opts.lang <= IDLOptions::kMAX);
|
||||
};
|
||||
}
|
||||
|
||||
GeneralGenerator &operator=(const GeneralGenerator &);
|
||||
bool generate() {
|
||||
std::string one_file_code;
|
||||
@@ -276,7 +217,7 @@ class GeneralGenerator : public BaseGenerator {
|
||||
return SaveFile(filename.c_str(), code, false);
|
||||
}
|
||||
|
||||
const Namespace *CurrentNameSpace() { return cur_name_space_; }
|
||||
const Namespace *CurrentNameSpace() const { return cur_name_space_; }
|
||||
|
||||
std::string FunctionStart(char upper) {
|
||||
return std::string() + (lang_.language == IDLOptions::kJava
|
||||
@@ -289,9 +230,16 @@ static bool IsEnum(const Type& type) {
|
||||
}
|
||||
|
||||
std::string GenTypeBasic(const Type &type, bool enableLangOverrides) {
|
||||
static const char *gtypename[] = {
|
||||
static const char *java_typename[] = {
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||
#JTYPE, #NTYPE, #GTYPE,
|
||||
#JTYPE,
|
||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
};
|
||||
|
||||
static const char *csharp_typename[] = {
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||
#NTYPE,
|
||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
};
|
||||
@@ -305,7 +253,12 @@ std::string GenTypeBasic(const Type &type, bool enableLangOverrides) {
|
||||
}
|
||||
}
|
||||
|
||||
return gtypename[type.base_type * IDLOptions::kMAX + lang_.language];
|
||||
if (lang_.language == IDLOptions::kJava) {
|
||||
return java_typename[type.base_type];
|
||||
} else {
|
||||
assert(lang_.language == IDLOptions::kCSharp);
|
||||
return csharp_typename[type.base_type];
|
||||
}
|
||||
}
|
||||
|
||||
std::string GenTypeBasic(const Type &type) {
|
||||
@@ -495,7 +448,7 @@ std::string GenDefaultValue(const Value &value, bool enableLangOverrides) {
|
||||
switch (value.type.base_type) {
|
||||
case BASE_TYPE_FLOAT: return value.constant + "f";
|
||||
case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
|
||||
case BASE_TYPE_ULONG:
|
||||
case BASE_TYPE_ULONG:
|
||||
{
|
||||
if (lang_.language != IDLOptions::kJava)
|
||||
return value.constant;
|
||||
@@ -1383,7 +1336,7 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
code += (lang_.language != IDLOptions::kJava) ? ";" : "";
|
||||
code += "\n\n";
|
||||
}
|
||||
const LanguageParameters & lang_;
|
||||
const LanguageParameters& lang_;
|
||||
// This tracks the current namespace used to determine if a type need to be prefixed by its namespace
|
||||
const Namespace *cur_name_space_;
|
||||
};
|
||||
@@ -1398,7 +1351,7 @@ bool GenerateGeneral(const Parser &parser, const std::string &path,
|
||||
std::string GeneralMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name) {
|
||||
assert(parser.opts.lang <= IDLOptions::kMAX);
|
||||
auto lang = language_parameters[parser.opts.lang];
|
||||
const auto &lang = GetLangParams(parser.opts.lang);
|
||||
|
||||
std::string make_rule;
|
||||
|
||||
|
||||
@@ -113,7 +113,11 @@ class JsGenerator : public BaseGenerator {
|
||||
code += "/**\n * @const\n * @namespace\n */\n";
|
||||
if (it->find('.') == std::string::npos) {
|
||||
code += "var ";
|
||||
exports += "this." + *it + " = " + *it + ";\n";
|
||||
if(parser_.opts.use_goog_js_export_format) {
|
||||
exports += "goog.exportSymbol('" + *it + "', " + *it + ");\n";
|
||||
} else {
|
||||
exports += "this." + *it + " = " + *it + ";\n";
|
||||
}
|
||||
}
|
||||
code += *it + " = " + *it + " || {};\n\n";
|
||||
}
|
||||
@@ -172,7 +176,12 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr,
|
||||
GenDocComment(enum_def.doc_comment, code_ptr, "@enum");
|
||||
if (enum_def.defined_namespace->components.empty()) {
|
||||
code += "var ";
|
||||
exports += "this." + enum_def.name + " = " + enum_def.name + ";\n";
|
||||
if(parser_.opts.use_goog_js_export_format) {
|
||||
exports += "goog.exportSymbol('" + enum_def.name + "', " + enum_def.name +
|
||||
");\n";
|
||||
} else {
|
||||
exports += "this." + enum_def.name + " = " + enum_def.name + ";\n";
|
||||
}
|
||||
}
|
||||
code += WrapInNameSpace(enum_def) + " = {\n";
|
||||
for (auto it = enum_def.vals.vec.begin();
|
||||
@@ -236,6 +245,9 @@ std::string GenDefaultValue(const Value &value, const std::string &context) {
|
||||
if (auto val = value.type.enum_def->ReverseLookup(
|
||||
atoi(value.constant.c_str()), false)) {
|
||||
return WrapInNameSpace(*value.type.enum_def) + "." + val->name;
|
||||
} else {
|
||||
return "/** @type {" + WrapInNameSpace(*value.type.enum_def) + "} */ ("
|
||||
+ value.constant + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +383,12 @@ void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_pt
|
||||
std::string object_name = WrapInNameSpace(struct_def);
|
||||
GenDocComment(struct_def.doc_comment, code_ptr, "@constructor");
|
||||
if (isStatement) {
|
||||
exports += "this." + struct_def.name + " = " + struct_def.name + ";\n";
|
||||
if(parser_.opts.use_goog_js_export_format) {
|
||||
exports += "goog.exportSymbol('" + struct_def.name + "', " +
|
||||
struct_def.name + ");\n";
|
||||
} else {
|
||||
exports += "this." + struct_def.name + " = " + struct_def.name + ";\n";
|
||||
}
|
||||
code += "function " + object_name;
|
||||
} else {
|
||||
code += object_name + " = function";
|
||||
@@ -526,7 +543,13 @@ void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_pt
|
||||
field.value.type.element == BASE_TYPE_ULONG) {
|
||||
code += "this.bb.createLong(0, 0)";
|
||||
} else if (IsScalar(field.value.type.element)) {
|
||||
code += "0";
|
||||
if (field.value.type.enum_def) {
|
||||
code += "/** @type {" +
|
||||
WrapInNameSpace(*field.value.type.enum_def) + "} */ (" +
|
||||
field.value.constant + ")";
|
||||
} else {
|
||||
code += "0";
|
||||
}
|
||||
} else {
|
||||
code += "null";
|
||||
}
|
||||
@@ -550,6 +573,12 @@ void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_pt
|
||||
}
|
||||
code += "};\n\n";
|
||||
|
||||
if(parser_.opts.use_goog_js_export_format) {
|
||||
exports += "goog.exportProperty(" + object_name + ".prototype, '" +
|
||||
MakeCamel(field.name, false) + "', " + object_name + ".prototype." +
|
||||
MakeCamel(field.name, false) + ");\n";
|
||||
}
|
||||
|
||||
// Adds the mutable scalar value to the output
|
||||
if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer) {
|
||||
std::string annotations = "@param {" + GenTypeName(field.value.type, true) + "} value\n";
|
||||
@@ -564,6 +593,12 @@ void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_pt
|
||||
code += " this.bb.write" + MakeCamel(GenType(field.value.type)) + "(this.bb_pos + offset, value);\n";
|
||||
code += " return true;\n";
|
||||
code += "};\n\n";
|
||||
|
||||
if(parser_.opts.use_goog_js_export_format) {
|
||||
exports += "goog.exportProperty(" + object_name +
|
||||
".prototype, 'mutate_" + field.name + "', " + object_name +
|
||||
".prototype.mutate_" + field.name + ");\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Emit vector helpers
|
||||
@@ -574,6 +609,12 @@ void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_pt
|
||||
code += "Length = function() {\n" + offset_prefix;
|
||||
code += "this.bb.__vector_len(this.bb_pos + offset) : 0;\n};\n\n";
|
||||
|
||||
if(parser_.opts.use_goog_js_export_format) {
|
||||
exports += "goog.exportProperty(" + object_name + ".prototype, '" +
|
||||
MakeCamel(field.name, false) + "Length', " + object_name +
|
||||
".prototype." + MakeCamel(field.name, false) + "Length);\n";
|
||||
}
|
||||
|
||||
// For scalar types, emit a typed array helper
|
||||
auto vectorType = field.value.type.VectorType();
|
||||
if (IsScalar(vectorType.base_type) && !IsLong(vectorType.base_type)) {
|
||||
@@ -583,6 +624,12 @@ void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_pt
|
||||
code += "new " + GenType(vectorType) + "Array(this.bb.bytes().buffer, "
|
||||
"this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), "
|
||||
"this.bb.__vector_len(this.bb_pos + offset)) : null;\n};\n\n";
|
||||
|
||||
if(parser_.opts.use_goog_js_export_format) {
|
||||
exports += "goog.exportProperty(" + object_name + ".prototype, '" +
|
||||
MakeCamel(field.name, false) + "Array', " + object_name +
|
||||
".prototype." + MakeCamel(field.name, false) + "Array);\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,6 +109,12 @@ template<typename T> inline CheckedError atot(const char *s, Parser &parser,
|
||||
*val = (T)i;
|
||||
return NoError();
|
||||
}
|
||||
template<> inline CheckedError atot<uint64_t>(const char *s, Parser &parser,
|
||||
uint64_t *val) {
|
||||
(void)parser;
|
||||
*val = StringToUInt(s);
|
||||
return NoError();
|
||||
}
|
||||
template<> inline CheckedError atot<bool>(const char *s, Parser &parser,
|
||||
bool *val) {
|
||||
(void)parser;
|
||||
@@ -149,8 +155,7 @@ std::string Namespace::GetFullyQualifiedName(const std::string &name,
|
||||
}
|
||||
stream << components[i];
|
||||
}
|
||||
|
||||
stream << "." << name;
|
||||
if (name.length()) stream << "." << name;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
@@ -175,7 +180,8 @@ std::string Namespace::GetFullyQualifiedName(const std::string &name,
|
||||
TD(Include, 269, "include") \
|
||||
TD(Attribute, 270, "attribute") \
|
||||
TD(Null, 271, "null") \
|
||||
TD(Service, 272, "rpc_service")
|
||||
TD(Service, 272, "rpc_service") \
|
||||
TD(NativeInclude, 273, "native_include")
|
||||
#ifdef __GNUC__
|
||||
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
|
||||
#endif
|
||||
@@ -213,7 +219,7 @@ std::string Parser::TokenToStringId(int t) {
|
||||
}
|
||||
|
||||
// Parses exactly nibbles worth of hex digits into a number, or error.
|
||||
CheckedError Parser::ParseHexNum(int nibbles, int64_t *val) {
|
||||
CheckedError Parser::ParseHexNum(int nibbles, uint64_t *val) {
|
||||
for (int i = 0; i < nibbles; i++)
|
||||
if (!isxdigit(static_cast<const unsigned char>(cursor_[i])))
|
||||
return Error("escape code must be followed by " + NumToString(nibbles) +
|
||||
@@ -280,14 +286,14 @@ CheckedError Parser::Next() {
|
||||
case '/': attribute_ += '/'; cursor_++; break;
|
||||
case 'x': { // Not in the JSON standard
|
||||
cursor_++;
|
||||
int64_t val;
|
||||
uint64_t val;
|
||||
ECHECK(ParseHexNum(2, &val));
|
||||
attribute_ += static_cast<char>(val);
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
cursor_++;
|
||||
int64_t val;
|
||||
uint64_t val;
|
||||
ECHECK(ParseHexNum(4, &val));
|
||||
if (val >= 0xD800 && val <= 0xDBFF) {
|
||||
if (unicode_high_surrogate != -1) {
|
||||
@@ -433,12 +439,17 @@ CheckedError Parser::Next() {
|
||||
token_ = kTokenService;
|
||||
return NoError();
|
||||
}
|
||||
if (attribute_ == "native_include") {
|
||||
token_ = kTokenNativeInclude;
|
||||
return NoError();
|
||||
}
|
||||
// If not, it is a user-defined identifier:
|
||||
token_ = kTokenIdentifier;
|
||||
return NoError();
|
||||
} else if (isdigit(static_cast<unsigned char>(c)) || c == '-') {
|
||||
const char *start = cursor_ - 1;
|
||||
if (c == '-' && *cursor_ == '0' && (cursor_[1] == 'x' || cursor_[1] == 'X')) {
|
||||
if (c == '-' && *cursor_ == '0' &&
|
||||
(cursor_[1] == 'x' || cursor_[1] == 'X')) {
|
||||
++start;
|
||||
++cursor_;
|
||||
attribute_.append(&c, &c + 1);
|
||||
@@ -448,7 +459,8 @@ CheckedError Parser::Next() {
|
||||
cursor_++;
|
||||
while (isxdigit(static_cast<unsigned char>(*cursor_))) cursor_++;
|
||||
attribute_.append(start + 2, cursor_);
|
||||
attribute_ = NumToString(StringToUInt(attribute_.c_str(), nullptr, 16));
|
||||
attribute_ = NumToString(static_cast<int64_t>(
|
||||
StringToUInt(attribute_.c_str(), nullptr, 16)));
|
||||
token_ = kTokenIntegerConstant;
|
||||
return NoError();
|
||||
}
|
||||
@@ -550,12 +562,6 @@ CheckedError Parser::ParseType(Type &type) {
|
||||
return Error(
|
||||
"nested vector types not supported (wrap in table first).");
|
||||
}
|
||||
if (subtype.base_type == BASE_TYPE_UNION) {
|
||||
// We could support this if we stored a struct of 2 elements per
|
||||
// union element.
|
||||
return Error(
|
||||
"vector of union types not supported (wrap in table first).");
|
||||
}
|
||||
type = Type(BASE_TYPE_VECTOR, subtype.struct_def, subtype.enum_def);
|
||||
type.element = subtype.base_type;
|
||||
EXPECT(']');
|
||||
@@ -607,6 +613,19 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
||||
// with a special suffix.
|
||||
ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(),
|
||||
type.enum_def->underlying_type, &typefield));
|
||||
} else if (type.base_type == BASE_TYPE_VECTOR &&
|
||||
type.element == BASE_TYPE_UNION) {
|
||||
// Only cpp supports the union vector feature so far.
|
||||
if (opts.lang_to_generate != IDLOptions::kCpp) {
|
||||
return Error("Vectors of unions are not yet supported in all "
|
||||
"the specified programming languages.");
|
||||
}
|
||||
// For vector of union fields, add a second auto-generated vector field to
|
||||
// hold the types, with a special suffix.
|
||||
Type union_vector(BASE_TYPE_VECTOR, nullptr, type.enum_def);
|
||||
union_vector.element = BASE_TYPE_UTYPE;
|
||||
ECHECK(AddField(struct_def, name + UnionTypeFieldSuffix(),
|
||||
union_vector, &typefield));
|
||||
}
|
||||
|
||||
FieldDef *field;
|
||||
@@ -723,8 +742,17 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
|
||||
case BASE_TYPE_UNION: {
|
||||
assert(field);
|
||||
std::string constant;
|
||||
if (!parent_fieldn ||
|
||||
field_stack_.back().second->value.type.base_type != BASE_TYPE_UTYPE) {
|
||||
// Find corresponding type field we may have already parsed.
|
||||
for (auto elem = field_stack_.rbegin();
|
||||
elem != field_stack_.rbegin() + parent_fieldn; ++elem) {
|
||||
auto &type = elem->second->value.type;
|
||||
if (type.base_type == BASE_TYPE_UTYPE &&
|
||||
type.enum_def == val.type.enum_def) {
|
||||
constant = elem->first.constant;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (constant.empty()) {
|
||||
// We haven't seen the type field yet. Sadly a lot of JSON writers
|
||||
// output these in alphabetical order, meaning it comes after this
|
||||
// value. So we scan past the value to find it, then come back here.
|
||||
@@ -751,8 +779,6 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
|
||||
constant = type_val.constant;
|
||||
// Got the information we needed, now rewind:
|
||||
*static_cast<ParserState *>(this) = backup;
|
||||
} else {
|
||||
constant = field_stack_.back().first.constant;
|
||||
}
|
||||
uint8_t enum_idx;
|
||||
ECHECK(atot(constant.c_str(), *this, &enum_idx));
|
||||
@@ -831,16 +857,18 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
||||
} else {
|
||||
Value val = field->value;
|
||||
ECHECK(ParseAnyValue(val, field, fieldn, &struct_def));
|
||||
size_t i = field_stack_.size();
|
||||
// Hardcoded insertion-sort with error-check.
|
||||
// If fields are specified in order, then this loop exits immediately.
|
||||
for (; i > field_stack_.size() - fieldn; i--) {
|
||||
auto existing_field = field_stack_[i - 1].second;
|
||||
auto elem = field_stack_.rbegin();
|
||||
for (; elem != field_stack_.rbegin() + fieldn; ++elem) {
|
||||
auto existing_field = elem->second;
|
||||
if (existing_field == field)
|
||||
return Error("field set more than once: " + field->name);
|
||||
if (existing_field->value.offset < field->value.offset) break;
|
||||
}
|
||||
field_stack_.insert(field_stack_.begin() + i, std::make_pair(val, field));
|
||||
// Note: elem points to before the insertion point, thus .base() points
|
||||
// to the correct spot.
|
||||
field_stack_.insert(elem.base(), std::make_pair(val, field));
|
||||
fieldn++;
|
||||
}
|
||||
}
|
||||
@@ -1294,6 +1322,8 @@ CheckedError Parser::ParseEnum(bool is_union, EnumDef **dest) {
|
||||
}
|
||||
}
|
||||
if (dest) *dest = &enum_def;
|
||||
types_.Add(namespaces_.back()->GetFullyQualifiedName(enum_def.name),
|
||||
new Type(BASE_TYPE_UNION, nullptr, &enum_def));
|
||||
return NoError();
|
||||
}
|
||||
|
||||
@@ -1399,6 +1429,8 @@ CheckedError Parser::ParseDecl() {
|
||||
ECHECK(CheckClash(fields, struct_def, "_byte_vector", BASE_TYPE_STRING));
|
||||
ECHECK(CheckClash(fields, struct_def, "ByteVector", BASE_TYPE_STRING));
|
||||
EXPECT('}');
|
||||
types_.Add(namespaces_.back()->GetFullyQualifiedName(struct_def->name),
|
||||
new Type(BASE_TYPE_STRUCT, struct_def, nullptr));
|
||||
return NoError();
|
||||
}
|
||||
|
||||
@@ -1849,6 +1881,10 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
|
||||
(attribute_ == "option" || attribute_ == "syntax" ||
|
||||
attribute_ == "package")) {
|
||||
ECHECK(ParseProtoDecl());
|
||||
} else if (Is(kTokenNativeInclude)) {
|
||||
NEXT();
|
||||
native_included_files_.emplace_back(attribute_);
|
||||
EXPECT(kTokenStringConstant);
|
||||
} else if (Is(kTokenInclude) ||
|
||||
(opts.proto_mode &&
|
||||
attribute_ == "import" &&
|
||||
@@ -2050,7 +2086,11 @@ Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder,
|
||||
fixed,
|
||||
static_cast<int>(minalign),
|
||||
static_cast<int>(bytesize),
|
||||
SerializeAttributes(builder, parser));
|
||||
SerializeAttributes(builder, parser),
|
||||
parser.opts.binary_schema_comments
|
||||
? builder->CreateVectorOfStrings(
|
||||
doc_comment)
|
||||
: 0);
|
||||
}
|
||||
|
||||
Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
|
||||
@@ -2070,7 +2110,10 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
|
||||
deprecated,
|
||||
required,
|
||||
key,
|
||||
SerializeAttributes(builder, parser));
|
||||
SerializeAttributes(builder, parser),
|
||||
parser.opts.binary_schema_comments
|
||||
? builder->CreateVectorOfStrings(doc_comment)
|
||||
: 0);
|
||||
// TODO: value.constant is almost always "0", we could save quite a bit of
|
||||
// space by sharing it. Same for common values of value.type.
|
||||
}
|
||||
@@ -2087,7 +2130,10 @@ Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder,
|
||||
builder->CreateVector(enumval_offsets),
|
||||
is_union,
|
||||
underlying_type.Serialize(builder),
|
||||
SerializeAttributes(builder, parser));
|
||||
SerializeAttributes(builder, parser),
|
||||
parser.opts.binary_schema_comments
|
||||
? builder->CreateVectorOfStrings(doc_comment)
|
||||
: 0);
|
||||
}
|
||||
|
||||
Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder) const
|
||||
|
||||
@@ -16,7 +16,7 @@ type MonsterStorageClient interface{
|
||||
Store(ctx context.Context, in *flatbuffers.Builder,
|
||||
opts... grpc.CallOption) (* Stat, error)
|
||||
Retrieve(ctx context.Context, in *flatbuffers.Builder,
|
||||
opts... grpc.CallOption) (* Monster, error)
|
||||
opts... grpc.CallOption) (MonsterStorage_RetrieveClient, error)
|
||||
}
|
||||
|
||||
type monsterStorageClient struct {
|
||||
@@ -36,17 +36,34 @@ func (c *monsterStorageClient) Store(ctx context.Context, in *flatbuffers.Builde
|
||||
}
|
||||
|
||||
func (c *monsterStorageClient) Retrieve(ctx context.Context, in *flatbuffers.Builder,
|
||||
opts... grpc.CallOption) (* Monster, error) {
|
||||
out := new(Monster)
|
||||
err := grpc.Invoke(ctx, "/Example.MonsterStorage/Retrieve", in, out, c.cc, opts...)
|
||||
opts... grpc.CallOption) (MonsterStorage_RetrieveClient, error) {
|
||||
stream, err := grpc.NewClientStream(ctx, &_MonsterStorage_serviceDesc.Streams[0], c.cc, "/Example.MonsterStorage/Retrieve", opts...)
|
||||
if err != nil { return nil, err }
|
||||
return out, nil
|
||||
x := &monsterStorageRetrieveClient{stream}
|
||||
if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }
|
||||
if err := x.ClientStream.CloseSend(); err != nil { return nil, err }
|
||||
return x,nil
|
||||
}
|
||||
|
||||
type MonsterStorage_RetrieveClient interface {
|
||||
Recv() (*Monster, error)
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
type monsterStorageRetrieveClient struct{
|
||||
grpc.ClientStream
|
||||
}
|
||||
|
||||
func (x *monsterStorageRetrieveClient) Recv() (*Monster, error) {
|
||||
m := new(Monster)
|
||||
if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// Server API for MonsterStorage service
|
||||
type MonsterStorageServer interface {
|
||||
Store(context.Context, *Monster) (*flatbuffers.Builder, error)
|
||||
Retrieve(context.Context, *Stat) (*flatbuffers.Builder, error)
|
||||
Retrieve(*Stat, MonsterStorage_RetrieveServer) error
|
||||
}
|
||||
|
||||
func RegisterMonsterStorageServer(s *grpc.Server, srv MonsterStorageServer) {
|
||||
@@ -70,20 +87,23 @@ func _MonsterStorage_Store_Handler(srv interface{}, ctx context.Context,
|
||||
}
|
||||
|
||||
|
||||
func _MonsterStorage_Retrieve_Handler(srv interface{}, ctx context.Context,
|
||||
dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Stat)
|
||||
if err := dec(in); err != nil { return nil, err }
|
||||
if interceptor == nil { return srv.(MonsterStorageServer).Retrieve(ctx, in) }
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/Example.MonsterStorage/Retrieve",
|
||||
}
|
||||
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MonsterStorageServer).Retrieve(ctx, req.(* Stat))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
func _MonsterStorage_Retrieve_Handler(srv interface{}, stream grpc.ServerStream) error {
|
||||
m := new(Stat)
|
||||
if err := stream.RecvMsg(m); err != nil { return err }
|
||||
return srv.(MonsterStorageServer).Retrieve(m, &monsterStorageRetrieveServer{stream})
|
||||
}
|
||||
|
||||
type MonsterStorage_RetrieveServer interface {
|
||||
Send(* flatbuffers.Builder) error
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
type monsterStorageRetrieveServer struct {
|
||||
grpc.ServerStream
|
||||
}
|
||||
|
||||
func (x *monsterStorageRetrieveServer) Send(m *flatbuffers.Builder) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
|
||||
@@ -95,12 +115,13 @@ var _MonsterStorage_serviceDesc = grpc.ServiceDesc{
|
||||
MethodName: "Store",
|
||||
Handler: _MonsterStorage_Store_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Retrieve",
|
||||
Handler: _MonsterStorage_Retrieve_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
{
|
||||
StreamName: "Retrieve",
|
||||
Handler: _MonsterStorage_Retrieve_Handler,
|
||||
ServerStreams: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --gen-object-api --no-includes monster_test.fbs monsterdata_test.json
|
||||
../flatc --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
|
||||
../flatc --binary --schema monster_test.fbs
|
||||
../flatc --cpp -o union_vector ./union_vector/union_vector.fbs
|
||||
../flatc -b --schema --bfbs-comments monster_test.fbs
|
||||
cd ../samples
|
||||
../flatc --cpp --gen-mutable --gen-object-api monster.fbs
|
||||
cd ../reflection
|
||||
|
||||
@@ -1251,9 +1251,9 @@ func CheckVtableDeduplication(fail func(string, ...interface{})) {
|
||||
len(want), want, len(got), got)
|
||||
}
|
||||
|
||||
table0 := &flatbuffers.Table{b.Bytes, flatbuffers.UOffsetT(len(b.Bytes)) - obj0}
|
||||
table1 := &flatbuffers.Table{b.Bytes, flatbuffers.UOffsetT(len(b.Bytes)) - obj1}
|
||||
table2 := &flatbuffers.Table{b.Bytes, flatbuffers.UOffsetT(len(b.Bytes)) - obj2}
|
||||
table0 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj0}
|
||||
table1 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj1}
|
||||
table2 := &flatbuffers.Table{Bytes: b.Bytes, Pos: flatbuffers.UOffsetT(len(b.Bytes)) - obj2}
|
||||
|
||||
testTable := func(tab *flatbuffers.Table, a flatbuffers.VOffsetT, b, c, d byte) {
|
||||
// vtable size
|
||||
|
||||
Binary file not shown.
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "monster_test_generated.h"
|
||||
#include "monster_test.grpc.fb.h"
|
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h>
|
||||
#include <grpc++/impl/codegen/async_unary_call.h>
|
||||
#include <grpc++/impl/codegen/channel_interface.h>
|
||||
@@ -12,12 +13,13 @@
|
||||
#include <grpc++/impl/codegen/rpc_service_method.h>
|
||||
#include <grpc++/impl/codegen/service_type.h>
|
||||
#include <grpc++/impl/codegen/sync_stream.h>
|
||||
|
||||
namespace MyGame {
|
||||
namespace Example {
|
||||
|
||||
static const char* MonsterStorage_method_names[] = {
|
||||
"/MyGame.Example..MonsterStorage/Store",
|
||||
"/MyGame.Example..MonsterStorage/Retrieve",
|
||||
"/MyGame.Example.MonsterStorage/Store",
|
||||
"/MyGame.Example.MonsterStorage/Retrieve",
|
||||
};
|
||||
|
||||
std::unique_ptr< MonsterStorage::Stub> MonsterStorage::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "monster_test_generated.h"
|
||||
#include "flatbuffers/grpc.h"
|
||||
|
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h>
|
||||
#include <grpc++/impl/codegen/async_unary_call.h>
|
||||
#include <grpc++/impl/codegen/rpc_method.h>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,5 +1,6 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
|
||||
#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
|
||||
#define FLATBUFFERS_GENERATED_NAMESPACETEST1_NAMESPACEA_NAMESPACEB_H_
|
||||
|
||||
@@ -21,11 +22,19 @@ enum EnumInNestedNS {
|
||||
};
|
||||
|
||||
inline const char **EnumNamesEnumInNestedNS() {
|
||||
static const char *names[] = { "A", "B", "C", nullptr };
|
||||
static const char *names[] = {
|
||||
"A",
|
||||
"B",
|
||||
"C",
|
||||
nullptr
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameEnumInNestedNS(EnumInNestedNS e) { return EnumNamesEnumInNestedNS()[static_cast<int>(e)]; }
|
||||
inline const char *EnumNameEnumInNestedNS(EnumInNestedNS e) {
|
||||
const size_t index = static_cast<int>(e);
|
||||
return EnumNamesEnumInNestedNS()[index];
|
||||
}
|
||||
|
||||
MANUALLY_ALIGNED_STRUCT(4) StructInNestedNS FLATBUFFERS_FINAL_CLASS {
|
||||
private:
|
||||
@@ -33,15 +42,28 @@ MANUALLY_ALIGNED_STRUCT(4) StructInNestedNS FLATBUFFERS_FINAL_CLASS {
|
||||
int32_t b_;
|
||||
|
||||
public:
|
||||
StructInNestedNS() { memset(this, 0, sizeof(StructInNestedNS)); }
|
||||
StructInNestedNS(const StructInNestedNS &_o) { memcpy(this, &_o, sizeof(StructInNestedNS)); }
|
||||
StructInNestedNS() {
|
||||
memset(this, 0, sizeof(StructInNestedNS));
|
||||
}
|
||||
StructInNestedNS(const StructInNestedNS &_o) {
|
||||
memcpy(this, &_o, sizeof(StructInNestedNS));
|
||||
}
|
||||
StructInNestedNS(int32_t _a, int32_t _b)
|
||||
: a_(flatbuffers::EndianScalar(_a)), b_(flatbuffers::EndianScalar(_b)) { }
|
||||
|
||||
int32_t a() const { return flatbuffers::EndianScalar(a_); }
|
||||
void mutate_a(int32_t _a) { flatbuffers::WriteScalar(&a_, _a); }
|
||||
int32_t b() const { return flatbuffers::EndianScalar(b_); }
|
||||
void mutate_b(int32_t _b) { flatbuffers::WriteScalar(&b_, _b); }
|
||||
: a_(flatbuffers::EndianScalar(_a)),
|
||||
b_(flatbuffers::EndianScalar(_b)) {
|
||||
}
|
||||
int32_t a() const {
|
||||
return flatbuffers::EndianScalar(a_);
|
||||
}
|
||||
void mutate_a(int32_t _a) {
|
||||
flatbuffers::WriteScalar(&a_, _a);
|
||||
}
|
||||
int32_t b() const {
|
||||
return flatbuffers::EndianScalar(b_);
|
||||
}
|
||||
void mutate_b(int32_t _b) {
|
||||
flatbuffers::WriteScalar(&b_, _b);
|
||||
}
|
||||
};
|
||||
STRUCT_END(StructInNestedNS, 8);
|
||||
|
||||
@@ -49,8 +71,12 @@ struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
VT_FOO = 4
|
||||
};
|
||||
int32_t foo() const { return GetField<int32_t>(VT_FOO, 0); }
|
||||
bool mutate_foo(int32_t _foo) { return SetField(VT_FOO, _foo); }
|
||||
int32_t foo() const {
|
||||
return GetField<int32_t>(VT_FOO, 0);
|
||||
}
|
||||
bool mutate_foo(int32_t _foo) {
|
||||
return SetField(VT_FOO, _foo);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<int32_t>(verifier, VT_FOO) &&
|
||||
@@ -61,16 +87,23 @@ struct TableInNestedNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct TableInNestedNSBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_foo(int32_t foo) { fbb_.AddElement<int32_t>(TableInNestedNS::VT_FOO, foo, 0); }
|
||||
TableInNestedNSBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_foo(int32_t foo) {
|
||||
fbb_.AddElement<int32_t>(TableInNestedNS::VT_FOO, foo, 0);
|
||||
}
|
||||
TableInNestedNSBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
TableInNestedNSBuilder &operator=(const TableInNestedNSBuilder &);
|
||||
flatbuffers::Offset<TableInNestedNS> Finish() {
|
||||
auto o = flatbuffers::Offset<TableInNestedNS>(fbb_.EndTable(start_, 1));
|
||||
const auto end = fbb_.EndTable(start_, 1);
|
||||
auto o = flatbuffers::Offset<TableInNestedNS>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<TableInNestedNS> CreateTableInNestedNS(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
int32_t foo = 0) {
|
||||
TableInNestedNSBuilder builder_(_fbb);
|
||||
builder_.add_foo(foo);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
|
||||
#ifndef FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
|
||||
#define FLATBUFFERS_GENERATED_NAMESPACETEST2_NAMESPACEA_H_
|
||||
|
||||
@@ -29,12 +30,24 @@ struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_FOO_ENUM = 6,
|
||||
VT_FOO_STRUCT = 8
|
||||
};
|
||||
const NamespaceA::NamespaceB::TableInNestedNS *foo_table() const { return GetPointer<const NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE); }
|
||||
NamespaceA::NamespaceB::TableInNestedNS *mutable_foo_table() { return GetPointer<NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE); }
|
||||
NamespaceA::NamespaceB::EnumInNestedNS foo_enum() const { return static_cast<NamespaceA::NamespaceB::EnumInNestedNS>(GetField<int8_t>(VT_FOO_ENUM, 0)); }
|
||||
bool mutate_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS _foo_enum) { return SetField(VT_FOO_ENUM, static_cast<int8_t>(_foo_enum)); }
|
||||
const NamespaceA::NamespaceB::StructInNestedNS *foo_struct() const { return GetStruct<const NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT); }
|
||||
NamespaceA::NamespaceB::StructInNestedNS *mutable_foo_struct() { return GetStruct<NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT); }
|
||||
const NamespaceA::NamespaceB::TableInNestedNS *foo_table() const {
|
||||
return GetPointer<const NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE);
|
||||
}
|
||||
NamespaceA::NamespaceB::TableInNestedNS *mutable_foo_table() {
|
||||
return GetPointer<NamespaceA::NamespaceB::TableInNestedNS *>(VT_FOO_TABLE);
|
||||
}
|
||||
NamespaceA::NamespaceB::EnumInNestedNS foo_enum() const {
|
||||
return static_cast<NamespaceA::NamespaceB::EnumInNestedNS>(GetField<int8_t>(VT_FOO_ENUM, 0));
|
||||
}
|
||||
bool mutate_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS _foo_enum) {
|
||||
return SetField(VT_FOO_ENUM, static_cast<int8_t>(_foo_enum));
|
||||
}
|
||||
const NamespaceA::NamespaceB::StructInNestedNS *foo_struct() const {
|
||||
return GetStruct<const NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT);
|
||||
}
|
||||
NamespaceA::NamespaceB::StructInNestedNS *mutable_foo_struct() {
|
||||
return GetStruct<NamespaceA::NamespaceB::StructInNestedNS *>(VT_FOO_STRUCT);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_FOO_TABLE) &&
|
||||
@@ -48,18 +61,29 @@ struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct TableInFirstNSBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_foo_table(flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table) { fbb_.AddOffset(TableInFirstNS::VT_FOO_TABLE, foo_table); }
|
||||
void add_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS foo_enum) { fbb_.AddElement<int8_t>(TableInFirstNS::VT_FOO_ENUM, static_cast<int8_t>(foo_enum), 0); }
|
||||
void add_foo_struct(const NamespaceA::NamespaceB::StructInNestedNS *foo_struct) { fbb_.AddStruct(TableInFirstNS::VT_FOO_STRUCT, foo_struct); }
|
||||
TableInFirstNSBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_foo_table(flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table) {
|
||||
fbb_.AddOffset(TableInFirstNS::VT_FOO_TABLE, foo_table);
|
||||
}
|
||||
void add_foo_enum(NamespaceA::NamespaceB::EnumInNestedNS foo_enum) {
|
||||
fbb_.AddElement<int8_t>(TableInFirstNS::VT_FOO_ENUM, static_cast<int8_t>(foo_enum), 0);
|
||||
}
|
||||
void add_foo_struct(const NamespaceA::NamespaceB::StructInNestedNS *foo_struct) {
|
||||
fbb_.AddStruct(TableInFirstNS::VT_FOO_STRUCT, foo_struct);
|
||||
}
|
||||
TableInFirstNSBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
TableInFirstNSBuilder &operator=(const TableInFirstNSBuilder &);
|
||||
flatbuffers::Offset<TableInFirstNS> Finish() {
|
||||
auto o = flatbuffers::Offset<TableInFirstNS>(fbb_.EndTable(start_, 3));
|
||||
const auto end = fbb_.EndTable(start_, 3);
|
||||
auto o = flatbuffers::Offset<TableInFirstNS>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<TableInFirstNS> CreateTableInFirstNS(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<NamespaceA::NamespaceB::TableInNestedNS> foo_table = 0,
|
||||
NamespaceA::NamespaceB::EnumInNestedNS foo_enum = NamespaceA::NamespaceB::EnumInNestedNS_A,
|
||||
const NamespaceA::NamespaceB::StructInNestedNS *foo_struct = 0) {
|
||||
@@ -79,10 +103,18 @@ struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VT_REFER_TO_A1 = 4,
|
||||
VT_REFER_TO_A2 = 6
|
||||
};
|
||||
const NamespaceA::TableInFirstNS *refer_to_a1() const { return GetPointer<const NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1); }
|
||||
NamespaceA::TableInFirstNS *mutable_refer_to_a1() { return GetPointer<NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1); }
|
||||
const NamespaceA::SecondTableInA *refer_to_a2() const { return GetPointer<const NamespaceA::SecondTableInA *>(VT_REFER_TO_A2); }
|
||||
NamespaceA::SecondTableInA *mutable_refer_to_a2() { return GetPointer<NamespaceA::SecondTableInA *>(VT_REFER_TO_A2); }
|
||||
const NamespaceA::TableInFirstNS *refer_to_a1() const {
|
||||
return GetPointer<const NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1);
|
||||
}
|
||||
NamespaceA::TableInFirstNS *mutable_refer_to_a1() {
|
||||
return GetPointer<NamespaceA::TableInFirstNS *>(VT_REFER_TO_A1);
|
||||
}
|
||||
const NamespaceA::SecondTableInA *refer_to_a2() const {
|
||||
return GetPointer<const NamespaceA::SecondTableInA *>(VT_REFER_TO_A2);
|
||||
}
|
||||
NamespaceA::SecondTableInA *mutable_refer_to_a2() {
|
||||
return GetPointer<NamespaceA::SecondTableInA *>(VT_REFER_TO_A2);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_REFER_TO_A1) &&
|
||||
@@ -96,17 +128,26 @@ struct TableInC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct TableInCBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_refer_to_a1(flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1) { fbb_.AddOffset(TableInC::VT_REFER_TO_A1, refer_to_a1); }
|
||||
void add_refer_to_a2(flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2) { fbb_.AddOffset(TableInC::VT_REFER_TO_A2, refer_to_a2); }
|
||||
TableInCBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_refer_to_a1(flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1) {
|
||||
fbb_.AddOffset(TableInC::VT_REFER_TO_A1, refer_to_a1);
|
||||
}
|
||||
void add_refer_to_a2(flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2) {
|
||||
fbb_.AddOffset(TableInC::VT_REFER_TO_A2, refer_to_a2);
|
||||
}
|
||||
TableInCBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
TableInCBuilder &operator=(const TableInCBuilder &);
|
||||
flatbuffers::Offset<TableInC> Finish() {
|
||||
auto o = flatbuffers::Offset<TableInC>(fbb_.EndTable(start_, 2));
|
||||
const auto end = fbb_.EndTable(start_, 2);
|
||||
auto o = flatbuffers::Offset<TableInC>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<TableInC> CreateTableInC(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<TableInC> CreateTableInC(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<NamespaceA::TableInFirstNS> refer_to_a1 = 0,
|
||||
flatbuffers::Offset<NamespaceA::SecondTableInA> refer_to_a2 = 0) {
|
||||
TableInCBuilder builder_(_fbb);
|
||||
@@ -123,8 +164,12 @@ struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
VT_REFER_TO_C = 4
|
||||
};
|
||||
const NamespaceC::TableInC *refer_to_c() const { return GetPointer<const NamespaceC::TableInC *>(VT_REFER_TO_C); }
|
||||
NamespaceC::TableInC *mutable_refer_to_c() { return GetPointer<NamespaceC::TableInC *>(VT_REFER_TO_C); }
|
||||
const NamespaceC::TableInC *refer_to_c() const {
|
||||
return GetPointer<const NamespaceC::TableInC *>(VT_REFER_TO_C);
|
||||
}
|
||||
NamespaceC::TableInC *mutable_refer_to_c() {
|
||||
return GetPointer<NamespaceC::TableInC *>(VT_REFER_TO_C);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_REFER_TO_C) &&
|
||||
@@ -136,16 +181,23 @@ struct SecondTableInA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
struct SecondTableInABuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_refer_to_c(flatbuffers::Offset<NamespaceC::TableInC> refer_to_c) { fbb_.AddOffset(SecondTableInA::VT_REFER_TO_C, refer_to_c); }
|
||||
SecondTableInABuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); }
|
||||
void add_refer_to_c(flatbuffers::Offset<NamespaceC::TableInC> refer_to_c) {
|
||||
fbb_.AddOffset(SecondTableInA::VT_REFER_TO_C, refer_to_c);
|
||||
}
|
||||
SecondTableInABuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
SecondTableInABuilder &operator=(const SecondTableInABuilder &);
|
||||
flatbuffers::Offset<SecondTableInA> Finish() {
|
||||
auto o = flatbuffers::Offset<SecondTableInA>(fbb_.EndTable(start_, 1));
|
||||
const auto end = fbb_.EndTable(start_, 1);
|
||||
auto o = flatbuffers::Offset<SecondTableInA>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(flatbuffers::FlatBufferBuilder &_fbb,
|
||||
inline flatbuffers::Offset<SecondTableInA> CreateSecondTableInA(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<NamespaceC::TableInC> refer_to_c = 0) {
|
||||
SecondTableInABuilder builder_(_fbb);
|
||||
builder_.add_refer_to_c(refer_to_c);
|
||||
|
||||
157
tests/test.cpp
157
tests/test.cpp
@@ -21,11 +21,14 @@
|
||||
#include "monster_test_generated.h"
|
||||
#include "namespace_test/namespace_test1_generated.h"
|
||||
#include "namespace_test/namespace_test2_generated.h"
|
||||
#include "union_vector/union_vector_generated.h"
|
||||
|
||||
#ifndef FLATBUFFERS_CPP98_STL
|
||||
#include <random>
|
||||
#endif
|
||||
|
||||
#include "flatbuffers/flexbuffers.h"
|
||||
|
||||
using namespace MyGame::Example;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -490,8 +493,6 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
|
||||
TEST_NOTNULL(pos_table_ptr);
|
||||
TEST_EQ_STR(pos_table_ptr->name()->c_str(), "MyGame.Example.Vec3");
|
||||
|
||||
|
||||
|
||||
// Now use it to dynamically access a buffer.
|
||||
auto &root = *flatbuffers::GetAnyRoot(flatbuf);
|
||||
|
||||
@@ -606,11 +607,11 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
|
||||
reinterpret_cast<const uint8_t *>(resizingbuf.data()),
|
||||
resizingbuf.size());
|
||||
TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
|
||||
|
||||
|
||||
// Test buffer is valid using reflection as well
|
||||
TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), resizingbuf.data(),
|
||||
resizingbuf.size()), true);
|
||||
|
||||
|
||||
// As an additional test, also set it on the name field.
|
||||
// Note: unlike the name change above, this just overwrites the offset,
|
||||
// rather than changing the string in-place.
|
||||
@@ -954,7 +955,6 @@ void ErrorTest() {
|
||||
TestError("@", "illegal");
|
||||
TestError("table 1", "expecting");
|
||||
TestError("table X { Y:[[int]]; }", "nested vector");
|
||||
TestError("union Z { X } table X { Y:[Z]; }", "vector of union");
|
||||
TestError("table X { Y:1; }", "illegal type");
|
||||
TestError("table X { Y:int; Y:int; }", "field already");
|
||||
TestError("struct X { Y:string; }", "only scalar");
|
||||
@@ -994,14 +994,13 @@ template<typename T> T TestValue(const char *json, const char *type_name) {
|
||||
flatbuffers::Parser parser;
|
||||
|
||||
// Simple schema.
|
||||
TEST_EQ(parser.Parse(std::string("table X { Y:" + std::string(type_name) + "; } root_type X;").c_str()), true);
|
||||
TEST_EQ(parser.Parse(std::string("table X { Y:" + std::string(type_name) +
|
||||
"; } root_type X;").c_str()), true);
|
||||
|
||||
TEST_EQ(parser.Parse(json), true);
|
||||
auto root = flatbuffers::GetRoot<T>(parser.builder_.GetBufferPointer());
|
||||
// root will point to the table, which is a 32bit vtable offset followed
|
||||
// by a float:
|
||||
TEST_EQ(sizeof(flatbuffers::soffset_t), 4); // Test assumes 32bit offsets
|
||||
return root[1];
|
||||
auto root = flatbuffers::GetRoot<flatbuffers::Table>(
|
||||
parser.builder_.GetBufferPointer());
|
||||
return root->GetField<T>(flatbuffers::FieldIndexToOffset(0), 0);
|
||||
}
|
||||
|
||||
bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
|
||||
@@ -1009,13 +1008,19 @@ bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
|
||||
// Additional parser testing not covered elsewhere.
|
||||
void ValueTest() {
|
||||
// Test scientific notation numbers.
|
||||
TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }","float"), (float)3.14159), true);
|
||||
TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }","float"),
|
||||
(float)3.14159), true);
|
||||
|
||||
// Test conversion functions.
|
||||
TEST_EQ(FloatCompare(TestValue<float>("{ Y:cos(rad(180)) }","float"), -1), true);
|
||||
TEST_EQ(FloatCompare(TestValue<float>("{ Y:cos(rad(180)) }","float"), -1),
|
||||
true);
|
||||
|
||||
// Test negative hex constant.
|
||||
TEST_EQ(TestValue<int>("{ Y:-0x80 }","int") == -128, true);
|
||||
TEST_EQ(TestValue<int>("{ Y:-0x80 }","int"), -128);
|
||||
|
||||
// Make sure we do unsigned 64bit correctly.
|
||||
TEST_EQ(TestValue<uint64_t>("{ Y:12335089644688340133 }","ulong"),
|
||||
12335089644688340133ULL);
|
||||
}
|
||||
|
||||
void EnumStringsTest() {
|
||||
@@ -1276,6 +1281,67 @@ void ParseUnionTest() {
|
||||
"{ e_type: N_A, e: {} }"), true);
|
||||
}
|
||||
|
||||
void UnionVectorTest() {
|
||||
// load FlatBuffer fbs schema.
|
||||
// TODO: load a JSON file with such a vector when JSON support is ready.
|
||||
std::string schemafile;
|
||||
TEST_EQ(flatbuffers::LoadFile(
|
||||
"tests/union_vector/union_vector.fbs", false, &schemafile), true);
|
||||
|
||||
// parse schema.
|
||||
flatbuffers::IDLOptions idl_opts;
|
||||
idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kCpp;
|
||||
flatbuffers::Parser parser(idl_opts);
|
||||
const char *include_directories[] = { "tests/union_vector", nullptr };
|
||||
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
||||
|
||||
flatbuffers::FlatBufferBuilder fbb;
|
||||
|
||||
// union types.
|
||||
std::vector<uint8_t> types;
|
||||
types.push_back(static_cast<uint8_t>(Character_Belle));
|
||||
types.push_back(static_cast<uint8_t>(Character_Rapunzel));
|
||||
types.push_back(static_cast<uint8_t>(Character_MuLan));
|
||||
|
||||
// union values.
|
||||
std::vector<flatbuffers::Offset<void>> characters;
|
||||
characters.push_back(CreateBelle(fbb, /*books_read=*/7).Union());
|
||||
characters.push_back(CreateRapunzel(fbb, /*hair_length=*/6).Union());
|
||||
characters.push_back(CreateMuLan(fbb, /*sword_attack_damage=*/5).Union());
|
||||
|
||||
// create Movie.
|
||||
const auto movie_offset =
|
||||
CreateMovie(fbb, fbb.CreateVector(types), fbb.CreateVector(characters));
|
||||
FinishMovieBuffer(fbb, movie_offset);
|
||||
uint8_t *buf = fbb.GetBufferPointer();
|
||||
|
||||
flatbuffers::Verifier verifier(buf, fbb.GetSize());
|
||||
TEST_EQ(VerifyMovieBuffer(verifier), true);
|
||||
|
||||
const Movie *movie = GetMovie(buf);
|
||||
TEST_EQ(movie->characters_type()->size(), 3);
|
||||
TEST_EQ(
|
||||
movie->characters_type()->GetEnum<Character>(0) == Character_Belle,
|
||||
true);
|
||||
TEST_EQ(
|
||||
movie->characters_type()->GetEnum<Character>(1) == Character_Rapunzel,
|
||||
true);
|
||||
TEST_EQ(
|
||||
movie->characters_type()->GetEnum<Character>(2) == Character_MuLan,
|
||||
true);
|
||||
|
||||
TEST_EQ(movie->characters()->size(), 3);
|
||||
const Belle *belle =
|
||||
reinterpret_cast<const Belle*>(movie->characters()->Get(0));
|
||||
TEST_EQ(belle->books_read(), 7);
|
||||
const Rapunzel *rapunzel =
|
||||
reinterpret_cast<const Rapunzel*>(movie->characters()->Get(1));
|
||||
TEST_EQ(rapunzel->hair_length(), 6);
|
||||
const MuLan *mu_lan =
|
||||
reinterpret_cast<const MuLan*>(movie->characters()->Get(2));
|
||||
TEST_EQ(mu_lan->sword_attack_damage(), 5);
|
||||
}
|
||||
|
||||
void ConformTest() {
|
||||
flatbuffers::Parser parser;
|
||||
TEST_EQ(parser.Parse("table T { A:int; } enum E:byte { A }"), true);
|
||||
@@ -1294,6 +1360,66 @@ void ConformTest() {
|
||||
test_conform("enum E:byte { B, A }", "values differ for enum");
|
||||
}
|
||||
|
||||
void FlexBuffersTest() {
|
||||
flexbuffers::Builder slb(512,
|
||||
flexbuffers::BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
|
||||
|
||||
// Write the equivalent of:
|
||||
// { vec: [ -100, "Fred", 4.0 ], bar: [ 1, 2, 3 ], foo: 100 }
|
||||
slb.Map([&]() {
|
||||
slb.Vector("vec", [&]() {
|
||||
slb += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
|
||||
slb += "Fred";
|
||||
slb.IndirectFloat(4.0f);
|
||||
});
|
||||
int ints[] = { 1, 2, 3 };
|
||||
slb.Vector("bar", ints, 3);
|
||||
slb.FixedTypedVector("bar3", ints, 3);
|
||||
slb.Double("foo", 100);
|
||||
slb.Map("mymap", [&]() {
|
||||
slb.String("foo", "Fred"); // Testing key and string reuse.
|
||||
});
|
||||
});
|
||||
slb.Finish();
|
||||
|
||||
for (size_t i = 0; i < slb.GetBuffer().size(); i++)
|
||||
printf("%d ", slb.GetBuffer().data()[i]);
|
||||
printf("\n");
|
||||
|
||||
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
|
||||
TEST_EQ(map.size(), 5);
|
||||
auto vec = map["vec"].AsVector();
|
||||
TEST_EQ(vec.size(), 3);
|
||||
TEST_EQ(vec[0].AsInt64(), -100);
|
||||
TEST_EQ_STR(vec[1].AsString().c_str(), "Fred");
|
||||
TEST_EQ(vec[1].AsInt64(), 0); // Number parsing failed.
|
||||
TEST_EQ(vec[2].AsDouble(), 4.0);
|
||||
TEST_EQ(vec[2].AsString().IsTheEmptyString(), true); // Wrong Type.
|
||||
TEST_EQ_STR(vec[2].AsString().c_str(), ""); // This still works though.
|
||||
TEST_EQ_STR(vec[2].ToString().c_str(), "4"); // Or have it converted.
|
||||
auto tvec = map["bar"].AsTypedVector();
|
||||
TEST_EQ(tvec.size(), 3);
|
||||
TEST_EQ(tvec[2].AsInt8(), 3);
|
||||
auto tvec3 = map["bar3"].AsFixedTypedVector();
|
||||
TEST_EQ(tvec3.size(), 3);
|
||||
TEST_EQ(tvec3[2].AsInt8(), 3);
|
||||
TEST_EQ(map["foo"].AsUInt8(), 100);
|
||||
TEST_EQ(map["unknown"].IsNull(), true);
|
||||
auto mymap = map["mymap"].AsMap();
|
||||
// These should be equal by pointer equality, since key and value are shared.
|
||||
TEST_EQ(mymap.Keys()[0].AsKey(), map.Keys()[2].AsKey());
|
||||
TEST_EQ(mymap.Values()[0].AsString().c_str(), vec[1].AsString().c_str());
|
||||
// We can mutate values in the buffer.
|
||||
TEST_EQ(vec[0].MutateInt(-99), true);
|
||||
TEST_EQ(vec[0].AsInt64(), -99);
|
||||
TEST_EQ(vec[1].MutateString("John"), true); // Size must match.
|
||||
TEST_EQ_STR(vec[1].AsString().c_str(), "John");
|
||||
TEST_EQ(vec[1].MutateString("Alfred"), false); // Too long.
|
||||
TEST_EQ(vec[2].MutateFloat(2.0f), true);
|
||||
TEST_EQ(vec[2].AsFloat(), 2.0f);
|
||||
TEST_EQ(vec[2].MutateFloat(3.14159), false); // Double does not fit in float.
|
||||
}
|
||||
|
||||
int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
// Run our various test suites:
|
||||
|
||||
@@ -1313,6 +1439,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
ParseAndGenerateTextTest();
|
||||
ReflectionTest(flatbuf.get(), rawbuf.length());
|
||||
ParseProtoTest();
|
||||
UnionVectorTest();
|
||||
#endif
|
||||
|
||||
FuzzTest1();
|
||||
@@ -1332,6 +1459,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
ParseUnionTest();
|
||||
ConformTest();
|
||||
|
||||
FlexBuffersTest();
|
||||
|
||||
if (!testing_fails) {
|
||||
TEST_OUTPUT_LINE("ALL TESTS PASSED");
|
||||
return 0;
|
||||
|
||||
24
tests/union_vector/union_vector.fbs
Normal file
24
tests/union_vector/union_vector.fbs
Normal file
@@ -0,0 +1,24 @@
|
||||
table MuLan {
|
||||
sword_attack_damage: int;
|
||||
}
|
||||
|
||||
table Rapunzel {
|
||||
hair_length: int;
|
||||
}
|
||||
|
||||
table Belle {
|
||||
books_read: int;
|
||||
}
|
||||
|
||||
union Character {
|
||||
MuLan,
|
||||
Rapunzel,
|
||||
Belle,
|
||||
}
|
||||
|
||||
table Movie {
|
||||
characters: [Character];
|
||||
}
|
||||
|
||||
root_type Movie;
|
||||
file_identifier "MOVI";
|
||||
300
tests/union_vector/union_vector_generated.h
Normal file
300
tests/union_vector/union_vector_generated.h
Normal file
@@ -0,0 +1,300 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
|
||||
#ifndef FLATBUFFERS_GENERATED_UNIONVECTOR_H_
|
||||
#define FLATBUFFERS_GENERATED_UNIONVECTOR_H_
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
|
||||
struct MuLan;
|
||||
|
||||
struct Rapunzel;
|
||||
|
||||
struct Belle;
|
||||
|
||||
struct Movie;
|
||||
|
||||
enum Character {
|
||||
Character_NONE = 0,
|
||||
Character_MuLan = 1,
|
||||
Character_Rapunzel = 2,
|
||||
Character_Belle = 3,
|
||||
Character_MIN = Character_NONE,
|
||||
Character_MAX = Character_Belle
|
||||
};
|
||||
|
||||
inline const char **EnumNamesCharacter() {
|
||||
static const char *names[] = {
|
||||
"NONE",
|
||||
"MuLan",
|
||||
"Rapunzel",
|
||||
"Belle",
|
||||
nullptr
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameCharacter(Character e) {
|
||||
const size_t index = static_cast<int>(e);
|
||||
return EnumNamesCharacter()[index];
|
||||
}
|
||||
|
||||
template<typename T> struct CharacterTraits {
|
||||
static const Character enum_value = Character_NONE;
|
||||
};
|
||||
|
||||
template<> struct CharacterTraits<MuLan> {
|
||||
static const Character enum_value = Character_MuLan;
|
||||
};
|
||||
|
||||
template<> struct CharacterTraits<Rapunzel> {
|
||||
static const Character enum_value = Character_Rapunzel;
|
||||
};
|
||||
|
||||
template<> struct CharacterTraits<Belle> {
|
||||
static const Character enum_value = Character_Belle;
|
||||
};
|
||||
|
||||
bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type);
|
||||
bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
|
||||
|
||||
struct MuLan FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
VT_SWORD_ATTACK_DAMAGE = 4
|
||||
};
|
||||
int32_t sword_attack_damage() const {
|
||||
return GetField<int32_t>(VT_SWORD_ATTACK_DAMAGE, 0);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<int32_t>(verifier, VT_SWORD_ATTACK_DAMAGE) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
||||
struct MuLanBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_sword_attack_damage(int32_t sword_attack_damage) {
|
||||
fbb_.AddElement<int32_t>(MuLan::VT_SWORD_ATTACK_DAMAGE, sword_attack_damage, 0);
|
||||
}
|
||||
MuLanBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
MuLanBuilder &operator=(const MuLanBuilder &);
|
||||
flatbuffers::Offset<MuLan> Finish() {
|
||||
const auto end = fbb_.EndTable(start_, 1);
|
||||
auto o = flatbuffers::Offset<MuLan>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<MuLan> CreateMuLan(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
int32_t sword_attack_damage = 0) {
|
||||
MuLanBuilder builder_(_fbb);
|
||||
builder_.add_sword_attack_damage(sword_attack_damage);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
struct Rapunzel FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
VT_HAIR_LENGTH = 4
|
||||
};
|
||||
int32_t hair_length() const {
|
||||
return GetField<int32_t>(VT_HAIR_LENGTH, 0);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<int32_t>(verifier, VT_HAIR_LENGTH) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
||||
struct RapunzelBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_hair_length(int32_t hair_length) {
|
||||
fbb_.AddElement<int32_t>(Rapunzel::VT_HAIR_LENGTH, hair_length, 0);
|
||||
}
|
||||
RapunzelBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
RapunzelBuilder &operator=(const RapunzelBuilder &);
|
||||
flatbuffers::Offset<Rapunzel> Finish() {
|
||||
const auto end = fbb_.EndTable(start_, 1);
|
||||
auto o = flatbuffers::Offset<Rapunzel>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Rapunzel> CreateRapunzel(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
int32_t hair_length = 0) {
|
||||
RapunzelBuilder builder_(_fbb);
|
||||
builder_.add_hair_length(hair_length);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
struct Belle FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
VT_BOOKS_READ = 4
|
||||
};
|
||||
int32_t books_read() const {
|
||||
return GetField<int32_t>(VT_BOOKS_READ, 0);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<int32_t>(verifier, VT_BOOKS_READ) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
||||
struct BelleBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_books_read(int32_t books_read) {
|
||||
fbb_.AddElement<int32_t>(Belle::VT_BOOKS_READ, books_read, 0);
|
||||
}
|
||||
BelleBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
BelleBuilder &operator=(const BelleBuilder &);
|
||||
flatbuffers::Offset<Belle> Finish() {
|
||||
const auto end = fbb_.EndTable(start_, 1);
|
||||
auto o = flatbuffers::Offset<Belle>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Belle> CreateBelle(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
int32_t books_read = 0) {
|
||||
BelleBuilder builder_(_fbb);
|
||||
builder_.add_books_read(books_read);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
struct Movie FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
enum {
|
||||
VT_CHARACTERS_TYPE = 4,
|
||||
VT_CHARACTERS = 6
|
||||
};
|
||||
const flatbuffers::Vector<uint8_t> *characters_type() const {
|
||||
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_CHARACTERS_TYPE);
|
||||
}
|
||||
const flatbuffers::Vector<flatbuffers::Offset<void>> *characters() const {
|
||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<void>> *>(VT_CHARACTERS);
|
||||
}
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_CHARACTERS_TYPE) &&
|
||||
verifier.Verify(characters_type()) &&
|
||||
VerifyField<flatbuffers::uoffset_t>(verifier, VT_CHARACTERS) &&
|
||||
verifier.Verify(characters()) &&
|
||||
VerifyCharacterVector(verifier, characters(), characters_type()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
||||
struct MovieBuilder {
|
||||
flatbuffers::FlatBufferBuilder &fbb_;
|
||||
flatbuffers::uoffset_t start_;
|
||||
void add_characters_type(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> characters_type) {
|
||||
fbb_.AddOffset(Movie::VT_CHARACTERS_TYPE, characters_type);
|
||||
}
|
||||
void add_characters(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters) {
|
||||
fbb_.AddOffset(Movie::VT_CHARACTERS, characters);
|
||||
}
|
||||
MovieBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
MovieBuilder &operator=(const MovieBuilder &);
|
||||
flatbuffers::Offset<Movie> Finish() {
|
||||
const auto end = fbb_.EndTable(start_, 2);
|
||||
auto o = flatbuffers::Offset<Movie>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline flatbuffers::Offset<Movie> CreateMovie(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> characters_type = 0,
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<void>>> characters = 0) {
|
||||
MovieBuilder builder_(_fbb);
|
||||
builder_.add_characters(characters);
|
||||
builder_.add_characters_type(characters_type);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Movie> CreateMovieDirect(
|
||||
flatbuffers::FlatBufferBuilder &_fbb,
|
||||
const std::vector<uint8_t> *characters_type = nullptr,
|
||||
const std::vector<flatbuffers::Offset<void>> *characters = nullptr) {
|
||||
return CreateMovie(
|
||||
_fbb,
|
||||
characters_type ? _fbb.CreateVector<uint8_t>(*characters_type) : 0,
|
||||
characters ? _fbb.CreateVector<flatbuffers::Offset<void>>(*characters) : 0);
|
||||
}
|
||||
|
||||
inline bool VerifyCharacter(flatbuffers::Verifier &verifier, const void *obj, Character type) {
|
||||
switch (type) {
|
||||
case Character_NONE: {
|
||||
return true;
|
||||
}
|
||||
case Character_MuLan: {
|
||||
auto ptr = reinterpret_cast<const MuLan *>(obj);
|
||||
return verifier.VerifyTable(ptr);
|
||||
}
|
||||
case Character_Rapunzel: {
|
||||
auto ptr = reinterpret_cast<const Rapunzel *>(obj);
|
||||
return verifier.VerifyTable(ptr);
|
||||
}
|
||||
case Character_Belle: {
|
||||
auto ptr = reinterpret_cast<const Belle *>(obj);
|
||||
return verifier.VerifyTable(ptr);
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool VerifyCharacterVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
|
||||
if (values->size() != types->size()) return false;
|
||||
for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
|
||||
if (!VerifyCharacter(
|
||||
verifier, values->Get(i), types->GetEnum<Character>(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline const Movie *GetMovie(const void *buf) {
|
||||
return flatbuffers::GetRoot<Movie>(buf);
|
||||
}
|
||||
|
||||
inline const char *MovieIdentifier() {
|
||||
return "MOVI";
|
||||
}
|
||||
|
||||
inline bool MovieBufferHasIdentifier(const void *buf) {
|
||||
return flatbuffers::BufferHasIdentifier(
|
||||
buf, MovieIdentifier());
|
||||
}
|
||||
|
||||
inline bool VerifyMovieBuffer(
|
||||
flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifyBuffer<Movie>(MovieIdentifier());
|
||||
}
|
||||
|
||||
inline void FinishMovieBuffer(
|
||||
flatbuffers::FlatBufferBuilder &fbb,
|
||||
flatbuffers::Offset<Movie> root) {
|
||||
fbb.Finish(root, MovieIdentifier());
|
||||
}
|
||||
|
||||
#endif // FLATBUFFERS_GENERATED_UNIONVECTOR_H_
|
||||
Reference in New Issue
Block a user