Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
flatbuffers
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
flatbuffers
Commits
d75d29e2
Commit
d75d29e2
authored
Jan 19, 2016
by
Wouter van Oortmerssen
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
https://github.com/google/flatbuffers
parents
049f3f79
7d700825
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
278 additions
and
91 deletions
+278
-91
flatbuffers.h
include/flatbuffers/flatbuffers.h
+38
-10
hash.h
include/flatbuffers/hash.h
+4
-2
idl.h
include/flatbuffers/idl.h
+5
-0
util.h
include/flatbuffers/util.h
+5
-3
monster_generated.h
samples/monster_generated.h
+1
-1
flatc.cpp
src/flatc.cpp
+1
-0
idl_gen_cpp.cpp
src/idl_gen_cpp.cpp
+40
-17
idl_gen_general.cpp
src/idl_gen_general.cpp
+21
-1
idl_parser.cpp
src/idl_parser.cpp
+55
-39
FlatBuffersExampleTests.cs
tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
+39
-0
JavaTest.java
tests/JavaTest.java
+38
-0
Monster.cs
tests/MyGame/Example/Monster.cs
+2
-0
Monster.java
tests/MyGame/Example/Monster.java
+2
-0
monster_test_generated.h
tests/monster_test_generated.h
+3
-3
namespace_test1_generated.h
tests/namespace_test/namespace_test1_generated.h
+1
-1
namespace_test2_generated.h
tests/namespace_test/namespace_test2_generated.h
+1
-1
test.cpp
tests/test.cpp
+22
-13
No files found.
include/flatbuffers/flatbuffers.h
View file @
d75d29e2
...
...
@@ -33,11 +33,30 @@
#if __cplusplus <= 199711L && \
(!defined(_MSC_VER) || _MSC_VER < 1600) && \
(!defined(__GNUC__) || \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40
603
))
#error A C++11 compatible compiler is required for FlatBuffers.
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40
400
))
#error A C++11 compatible compiler
with support for the auto typing
is required for FlatBuffers.
#error __cplusplus _MSC_VER __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__
#endif
#if !defined(__clang__) && \
defined(__GNUC__) && \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
// Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr and constexpr
// keywords. Note the __clang__ check is needed, because clang presents itself as an older GNUC
// compiler.
#ifndef nullptr_t
const
class
nullptr_t
{
public
:
template
<
class
T
>
inline
operator
T
*
()
const
{
return
0
;
}
private
:
void
operator
&
()
const
;
}
nullptr
=
{};
#endif
#ifndef constexpr
#define constexpr const
#endif
#endif
// The wire format uses a little endian encoding (since that's efficient for
// the common platforms).
#if !defined(FLATBUFFERS_LITTLEENDIAN)
...
...
@@ -154,7 +173,11 @@ template<typename T> size_t AlignOf() {
#ifdef _MSC_VER
return
__alignof
(
T
);
#else
return
alignof
(
T
);
#ifndef alignof
return
__alignof__
(
T
);
#else
return
alignof
(
T
);
#endif
#endif
}
...
...
@@ -836,15 +859,20 @@ class FlatBufferBuilder FLATBUFFERS_FINAL_CLASS {
return
CreateVectorOfStructs
(
v
.
data
(),
v
.
size
());
}
template
<
typename
T
>
struct
TableKeyComparator
{
TableKeyComparator
(
vector_downward
&
buf
)
:
buf_
(
buf
)
{}
bool
operator
()(
const
Offset
<
T
>
&
a
,
const
Offset
<
T
>
&
b
)
const
{
auto
table_a
=
reinterpret_cast
<
T
*>
(
buf_
.
data_at
(
a
.
o
));
auto
table_b
=
reinterpret_cast
<
T
*>
(
buf_
.
data_at
(
b
.
o
));
return
table_a
->
KeyCompareLessThan
(
table_b
);
}
vector_downward
&
buf_
;
};
template
<
typename
T
>
Offset
<
Vector
<
Offset
<
T
>>>
CreateVectorOfSortedTables
(
Offset
<
T
>
*
v
,
size_t
len
)
{
std
::
sort
(
v
,
v
+
len
,
[
this
](
const
Offset
<
T
>
&
a
,
const
Offset
<
T
>
&
b
)
->
bool
{
auto
table_a
=
reinterpret_cast
<
T
*>
(
buf_
.
data_at
(
a
.
o
));
auto
table_b
=
reinterpret_cast
<
T
*>
(
buf_
.
data_at
(
b
.
o
));
return
table_a
->
KeyCompareLessThan
(
table_b
);
}
);
std
::
sort
(
v
,
v
+
len
,
TableKeyComparator
<
T
>
(
buf_
));
return
CreateVector
(
v
,
len
);
}
...
...
include/flatbuffers/hash.h
View file @
d75d29e2
...
...
@@ -20,6 +20,8 @@
#include <cstdint>
#include <cstring>
#include "flatbuffers/flatbuffers.h"
namespace
flatbuffers
{
template
<
typename
T
>
...
...
@@ -36,8 +38,8 @@ struct FnvTraits<uint32_t> {
template
<>
struct
FnvTraits
<
uint64_t
>
{
static
const
uint64_t
kFnvPrime
=
0x00000100000001b3
;
static
const
uint64_t
kOffsetBasis
=
0xcbf29ce484222645
;
static
const
uint64_t
kFnvPrime
=
0x00000100000001b3
ULL
;
static
const
uint64_t
kOffsetBasis
=
0xcbf29ce484222645
ULL
;
};
template
<
typename
T
>
...
...
include/flatbuffers/idl.h
View file @
d75d29e2
...
...
@@ -444,6 +444,7 @@ private:
FLATBUFFERS_CHECKED_ERROR
Error
(
const
std
::
string
&
msg
);
FLATBUFFERS_CHECKED_ERROR
ParseHexNum
(
int
nibbles
,
int64_t
*
val
);
FLATBUFFERS_CHECKED_ERROR
Next
();
FLATBUFFERS_CHECKED_ERROR
SkipByteOrderMark
();
bool
Is
(
int
t
);
FLATBUFFERS_CHECKED_ERROR
Expect
(
int
t
);
std
::
string
TokenToStringId
(
int
t
);
...
...
@@ -491,6 +492,10 @@ private:
FLATBUFFERS_CHECKED_ERROR
DoParse
(
const
char
*
_source
,
const
char
**
include_paths
,
const
char
*
source_filename
);
FLATBUFFERS_CHECKED_ERROR
CheckClash
(
std
::
vector
<
FieldDef
*>
&
fields
,
StructDef
*
struct_def
,
const
char
*
suffix
,
BaseType
baseType
);
public
:
SymbolTable
<
StructDef
>
structs_
;
...
...
include/flatbuffers/util.h
View file @
d75d29e2
...
...
@@ -38,6 +38,8 @@
#include <limits.h>
#endif
#include "flatbuffers/flatbuffers.h"
namespace
flatbuffers
{
// Convert an integer or floating point value to a string.
...
...
@@ -68,7 +70,7 @@ template<> inline std::string NumToString<double>(double t) {
auto
p
=
s
.
find_last_not_of
(
'0'
);
if
(
p
!=
std
::
string
::
npos
)
{
s
.
resize
(
p
+
1
);
// Strip trailing zeroes.
if
(
s
.
back
()
==
'.'
)
if
(
s
[
s
.
size
()
-
1
]
==
'.'
)
s
.
erase
(
s
.
size
()
-
1
,
1
);
// Strip '.' if a whole number.
}
return
s
;
...
...
@@ -197,8 +199,8 @@ inline std::string StripFileName(const std::string &filepath) {
inline
std
::
string
ConCatPathFileName
(
const
std
::
string
&
path
,
const
std
::
string
&
filename
)
{
std
::
string
filepath
=
path
;
if
(
path
.
length
()
&&
path
.
back
()
!=
kPathSeparator
&&
path
.
back
()
!=
kPosixPathSeparator
)
if
(
path
.
length
()
&&
path
[
path
.
size
()
-
1
]
!=
kPathSeparator
&&
path
[
path
.
size
()
-
1
]
!=
kPosixPathSeparator
)
filepath
+=
kPathSeparator
;
filepath
+=
filename
;
return
filepath
;
...
...
samples/monster_generated.h
View file @
d75d29e2
...
...
@@ -69,7 +69,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_HP
=
8
,
VT_NAME
=
10
,
VT_INVENTORY
=
14
,
VT_COLOR
=
16
,
VT_COLOR
=
16
};
const
Vec3
*
pos
()
const
{
return
GetStruct
<
const
Vec3
*>
(
VT_POS
);
}
Vec3
*
mutable_pos
()
{
return
GetStruct
<
Vec3
*>
(
VT_POS
);
}
...
...
src/flatc.cpp
View file @
d75d29e2
...
...
@@ -17,6 +17,7 @@
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h"
#include "flatbuffers/util.h"
#include <limits>
static
void
Error
(
const
std
::
string
&
err
,
bool
usage
=
false
,
bool
show_exe_name
=
true
);
...
...
src/idl_gen_cpp.cpp
View file @
d75d29e2
...
...
@@ -274,16 +274,24 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
// Generate field id constants.
if
(
struct_def
.
fields
.
vec
.
size
()
>
0
)
{
code
+=
" enum {
\n
"
;
bool
is_first_field
=
true
;
// track the first field that's not deprecated
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
auto
&
field
=
**
it
;
if
(
!
field
.
deprecated
)
{
// Deprecated fields won't be accessible.
if
(
!
is_first_field
)
{
// Add trailing comma and newline to previous element. Don't add trailing comma to
// last element since older versions of gcc complain about this.
code
+=
",
\n
"
;
}
else
{
is_first_field
=
false
;
}
code
+=
" "
+
GenFieldOffsetName
(
field
)
+
" = "
;
code
+=
NumToString
(
field
.
value
.
offset
)
+
",
\n
"
;
code
+=
NumToString
(
field
.
value
.
offset
);
}
}
code
+=
" };
\n
"
;
code
+=
"
\n
};
\n
"
;
}
// Generate the accessors.
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
...
...
@@ -520,15 +528,32 @@ static void GenTable(const Parser &parser, StructDef &struct_def,
}
static
void
GenPadding
(
const
FieldDef
&
field
,
const
std
::
function
<
void
(
int
bits
)
>
&
f
)
{
std
::
string
&
code
,
int
&
padding_id
,
const
std
::
function
<
void
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
>
&
f
)
{
if
(
field
.
padding
)
{
for
(
int
i
=
0
;
i
<
4
;
i
++
)
if
(
static_cast
<
int
>
(
field
.
padding
)
&
(
1
<<
i
))
f
((
1
<<
i
)
*
8
);
f
((
1
<<
i
)
*
8
,
code
,
padding_id
);
assert
(
!
(
field
.
padding
&
~
0xF
));
}
}
static
void
PaddingDefinition
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
code
+=
" int"
+
NumToString
(
bits
)
+
"_t __padding"
+
NumToString
(
padding_id
++
)
+
";
\n
"
;
}
static
void
PaddingDeclaration
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
(
void
)
bits
;
code
+=
" (void)__padding"
+
NumToString
(
padding_id
++
)
+
";"
;
}
static
void
PaddingInitializer
(
int
bits
,
std
::
string
&
code
,
int
&
padding_id
)
{
(
void
)
bits
;
code
+=
", __padding"
+
NumToString
(
padding_id
++
)
+
"(0)"
;
}
// Generate an accessor struct with constructor for a flatbuffers struct.
static
void
GenStruct
(
const
Parser
&
parser
,
StructDef
&
struct_def
,
std
::
string
*
code_ptr
)
{
...
...
@@ -550,10 +575,7 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
auto
&
field
=
**
it
;
code
+=
" "
+
GenTypeGet
(
parser
,
field
.
value
.
type
,
" "
,
""
,
" "
,
false
);
code
+=
field
.
name
+
"_;
\n
"
;
GenPadding
(
field
,
[
&
code
,
&
padding_id
](
int
bits
)
{
code
+=
" int"
+
NumToString
(
bits
)
+
"_t __padding"
+
NumToString
(
padding_id
++
)
+
";
\n
"
;
});
GenPadding
(
field
,
code
,
padding_id
,
PaddingDefinition
);
}
// Generate a constructor that takes all fields as arguments.
...
...
@@ -581,21 +603,16 @@ static void GenStruct(const Parser &parser, StructDef &struct_def,
}
else
{
code
+=
"_"
+
field
.
name
+
")"
;
}
GenPadding
(
field
,
[
&
code
,
&
padding_id
](
int
bits
)
{
(
void
)
bits
;
code
+=
", __padding"
+
NumToString
(
padding_id
++
)
+
"(0)"
;
});
GenPadding
(
field
,
code
,
padding_id
,
PaddingInitializer
);
}
code
+=
" {"
;
padding_id
=
0
;
for
(
auto
it
=
struct_def
.
fields
.
vec
.
begin
();
it
!=
struct_def
.
fields
.
vec
.
end
();
++
it
)
{
auto
&
field
=
**
it
;
GenPadding
(
field
,
[
&
code
,
&
padding_id
](
int
bits
)
{
(
void
)
bits
;
code
+=
" (void)__padding"
+
NumToString
(
padding_id
++
)
+
";"
;
});
GenPadding
(
field
,
code
,
padding_id
,
PaddingDeclaration
);
}
code
+=
" }
\n\n
"
;
...
...
@@ -649,6 +666,12 @@ void CloseNestedNameSpaces(Namespace *ns, std::string *code_ptr) {
}
// namespace cpp
struct
IsAlnum
{
bool
operator
()(
char
c
)
{
return
!
isalnum
(
c
);
}
};
// Iterate through all definitions we haven't generate code for (enums, structs,
// and tables) and output them to a single file.
std
::
string
GenerateCPP
(
const
Parser
&
parser
,
...
...
@@ -719,7 +742,7 @@ std::string GenerateCPP(const Parser &parser,
include_guard_ident
.
erase
(
std
::
remove_if
(
include_guard_ident
.
begin
(),
include_guard_ident
.
end
(),
[](
char
c
)
{
return
!
isalnum
(
c
);
}
),
IsAlnum
()
),
include_guard_ident
.
end
());
std
::
string
include_guard
=
"FLATBUFFERS_GENERATED_"
+
include_guard_ident
;
include_guard
+=
"_"
;
...
...
src/idl_gen_general.cpp
View file @
d75d29e2
...
...
@@ -876,7 +876,27 @@ static void GenStruct(const LanguageParameters &lang, const Parser &parser,
break
;
}
}
// generate object accessors if is nested_flatbuffer
auto
nested
=
field
.
attributes
.
Lookup
(
"nested_flatbuffer"
);
if
(
nested
)
{
auto
nested_qualified_name
=
parser
.
namespaces_
.
back
()
->
GetFullyQualifiedName
(
nested
->
constant
);
auto
nested_type
=
parser
.
structs_
.
Lookup
(
nested_qualified_name
);
auto
nested_type_name
=
WrapInNameSpace
(
parser
,
*
nested_type
);
auto
nestedMethodName
=
MakeCamel
(
field
.
name
,
lang
.
first_camel_upper
)
+
"As"
+
nested_type_name
;
auto
getNestedMethodName
=
nestedMethodName
;
if
(
lang
.
language
==
IDLOptions
::
kCSharp
)
{
getNestedMethodName
=
"Get"
+
nestedMethodName
;
}
code
+=
" public "
+
nested_type_name
+
" "
;
code
+=
nestedMethodName
+
"() { return "
;
code
+=
getNestedMethodName
+
"(new "
+
nested_type_name
+
"()); }
\n
"
;
code
+=
" public "
+
nested_type_name
+
" "
+
getNestedMethodName
;
code
+=
"("
+
nested_type_name
+
" obj) { "
;
code
+=
"int o = __offset("
+
NumToString
(
field
.
value
.
offset
)
+
"); "
;
code
+=
"return o != 0 ? obj.__init(__indirect(__vector(o)), bb) : null; }
\n
"
;
}
// generate mutators for scalar fields or vectors of scalars
if
(
parser
.
opts
.
mutable_buffer
)
{
auto
underlying_type
=
field
.
value
.
type
.
base_type
==
BASE_TYPE_VECTOR
...
...
src/idl_parser.cpp
View file @
d75d29e2
...
...
@@ -201,6 +201,14 @@ CheckedError Parser::ParseHexNum(int nibbles, int64_t *val) {
return
NoError
();
}
CheckedError
Parser
::
SkipByteOrderMark
()
{
if
(
static_cast
<
unsigned
char
>
(
*
cursor_
)
!=
0xef
)
return
NoError
();
cursor_
++
;
if
(
static_cast
<
unsigned
char
>
(
*
cursor_
++
)
!=
0xbb
)
return
Error
(
"invalid utf-8 byte order mark"
);
if
(
static_cast
<
unsigned
char
>
(
*
cursor_
++
)
!=
0xbf
)
return
Error
(
"invalid utf-8 byte order mark"
);
return
NoError
();
}
CheckedError
Parser
::
Next
()
{
doc_comment_
.
clear
();
bool
seen_newline
=
false
;
...
...
@@ -1118,6 +1126,33 @@ CheckedError Parser::StartStruct(const std::string &name, StructDef **dest) {
return
NoError
();
}
CheckedError
Parser
::
CheckClash
(
std
::
vector
<
FieldDef
*>
&
fields
,
StructDef
*
struct_def
,
const
char
*
suffix
,
BaseType
basetype
)
{
auto
len
=
strlen
(
suffix
);
for
(
auto
it
=
fields
.
begin
();
it
!=
fields
.
end
();
++
it
)
{
auto
&
fname
=
(
*
it
)
->
name
;
if
(
fname
.
length
()
>
len
&&
fname
.
compare
(
fname
.
length
()
-
len
,
len
,
suffix
)
==
0
&&
(
*
it
)
->
value
.
type
.
base_type
!=
BASE_TYPE_UTYPE
)
{
auto
field
=
struct_def
->
fields
.
Lookup
(
fname
.
substr
(
0
,
fname
.
length
()
-
len
));
if
(
field
&&
field
->
value
.
type
.
base_type
==
basetype
)
return
Error
(
"Field "
+
fname
+
" would clash with generated functions for field "
+
field
->
name
);
}
}
return
NoError
();
}
static
bool
compareFieldDefs
(
const
FieldDef
*
a
,
const
FieldDef
*
b
)
{
auto
a_id
=
atoi
(
a
->
attributes
.
Lookup
(
"id"
)
->
constant
.
c_str
());
auto
b_id
=
atoi
(
b
->
attributes
.
Lookup
(
"id"
)
->
constant
.
c_str
());
return
a_id
<
b_id
;
}
CheckedError
Parser
::
ParseDecl
()
{
std
::
vector
<
std
::
string
>
dc
=
doc_comment_
;
bool
fixed
=
Is
(
kTokenStruct
);
...
...
@@ -1160,12 +1195,7 @@ CheckedError Parser::ParseDecl() {
"either all fields or no fields must have an 'id' attribute"
);
// Simply sort by id, then the fields are the same as if no ids had
// been specified.
std
::
sort
(
fields
.
begin
(),
fields
.
end
(),
[](
const
FieldDef
*
a
,
const
FieldDef
*
b
)
->
bool
{
auto
a_id
=
atoi
(
a
->
attributes
.
Lookup
(
"id"
)
->
constant
.
c_str
());
auto
b_id
=
atoi
(
b
->
attributes
.
Lookup
(
"id"
)
->
constant
.
c_str
());
return
a_id
<
b_id
;
});
std
::
sort
(
fields
.
begin
(),
fields
.
end
(),
compareFieldDefs
);
// Verify we have a contiguous set, and reassign vtable offsets.
for
(
int
i
=
0
;
i
<
static_cast
<
int
>
(
fields
.
size
());
i
++
)
{
if
(
i
!=
atoi
(
fields
[
i
]
->
attributes
.
Lookup
(
"id"
)
->
constant
.
c_str
()))
...
...
@@ -1175,34 +1205,13 @@ CheckedError Parser::ParseDecl() {
}
}
}
// Check that no identifiers clash with auto generated fields.
// This is not an ideal situation, but should occur very infrequently,
// and allows us to keep using very readable names for type & length fields
// without inducing compile errors.
auto
CheckClash
=
[
&
fields
,
&
struct_def
,
this
](
const
char
*
suffix
,
BaseType
basetype
)
->
CheckedError
{
auto
len
=
strlen
(
suffix
);
for
(
auto
it
=
fields
.
begin
();
it
!=
fields
.
end
();
++
it
)
{
auto
&
fname
=
(
*
it
)
->
name
;
if
(
fname
.
length
()
>
len
&&
fname
.
compare
(
fname
.
length
()
-
len
,
len
,
suffix
)
==
0
&&
(
*
it
)
->
value
.
type
.
base_type
!=
BASE_TYPE_UTYPE
)
{
auto
field
=
struct_def
->
fields
.
Lookup
(
fname
.
substr
(
0
,
fname
.
length
()
-
len
));
if
(
field
&&
field
->
value
.
type
.
base_type
==
basetype
)
return
Error
(
"Field "
+
fname
+
" would clash with generated functions for field "
+
field
->
name
);
}
}
return
NoError
();
};
ECHECK
(
CheckClash
(
"_type"
,
BASE_TYPE_UNION
));
ECHECK
(
CheckClash
(
"Type"
,
BASE_TYPE_UNION
));
ECHECK
(
CheckClash
(
"_length"
,
BASE_TYPE_VECTOR
));
ECHECK
(
CheckClash
(
"Length"
,
BASE_TYPE_VECTOR
));
ECHECK
(
CheckClash
(
"_byte_vector"
,
BASE_TYPE_STRING
));
ECHECK
(
CheckClash
(
"ByteVector"
,
BASE_TYPE_STRING
));
ECHECK
(
CheckClash
(
fields
,
struct_def
,
"_type"
,
BASE_TYPE_UNION
));
ECHECK
(
CheckClash
(
fields
,
struct_def
,
"Type"
,
BASE_TYPE_UNION
));
ECHECK
(
CheckClash
(
fields
,
struct_def
,
"_length"
,
BASE_TYPE_VECTOR
));
ECHECK
(
CheckClash
(
fields
,
struct_def
,
"Length"
,
BASE_TYPE_VECTOR
));
ECHECK
(
CheckClash
(
fields
,
struct_def
,
"_byte_vector"
,
BASE_TYPE_STRING
));
ECHECK
(
CheckClash
(
fields
,
struct_def
,
"ByteVector"
,
BASE_TYPE_STRING
));
EXPECT
(
'}'
);
return
NoError
();
}
...
...
@@ -1244,6 +1253,10 @@ CheckedError Parser::ParseNamespace() {
return
NoError
();
}
static
bool
compareEnumVals
(
const
EnumVal
*
a
,
const
EnumVal
*
b
)
{
return
a
->
value
<
b
->
value
;
}
// Best effort parsing of .proto declarations, with the aim to turn them
// in the closest corresponding FlatBuffer equivalent.
// We parse everything as identifiers instead of keywords, since we don't
...
...
@@ -1294,9 +1307,8 @@ CheckedError Parser::ParseProtoDecl() {
if
(
Is
(
';'
))
NEXT
();
// Protobuf allows them to be specified in any order, so sort afterwards.
auto
&
v
=
enum_def
->
vals
.
vec
;
std
::
sort
(
v
.
begin
(),
v
.
end
(),
[](
const
EnumVal
*
a
,
const
EnumVal
*
b
)
{
return
a
->
value
<
b
->
value
;
});
std
::
sort
(
v
.
begin
(),
v
.
end
(),
compareEnumVals
);
// Temp: remove any duplicates, as .fbs files can't handle them.
for
(
auto
it
=
v
.
begin
();
it
!=
v
.
end
();
)
{
if
(
it
!=
v
.
begin
()
&&
it
[
0
]
->
value
==
it
[
-
1
]
->
value
)
it
=
v
.
erase
(
it
);
...
...
@@ -1593,6 +1605,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
builder_
.
Clear
();
// Start with a blank namespace just in case this file doesn't have one.
namespaces_
.
push_back
(
new
Namespace
());
ECHECK
(
SkipByteOrderMark
());
NEXT
();
// Includes must come before type declarations:
for
(;;)
{
...
...
@@ -1744,11 +1757,14 @@ std::set<std::string> Parser::GetIncludedFilesRecursive(
// Schema serialization functionality:
template
<
typename
T
>
bool
compareName
(
const
T
*
a
,
const
T
*
b
)
{
return
a
->
name
<
b
->
name
;
}
template
<
typename
T
>
void
AssignIndices
(
const
std
::
vector
<
T
*>
&
defvec
)
{
// Pre-sort these vectors, such that we can set the correct indices for them.
auto
vec
=
defvec
;
std
::
sort
(
vec
.
begin
(),
vec
.
end
(),
[](
const
T
*
a
,
const
T
*
b
)
{
return
a
->
name
<
b
->
name
;
});
std
::
sort
(
vec
.
begin
(),
vec
.
end
(),
compareName
<
T
>
);
for
(
int
i
=
0
;
i
<
static_cast
<
int
>
(
vec
.
size
());
i
++
)
vec
[
i
]
->
index
=
i
;
}
...
...
tests/FlatBuffers.Test/FlatBuffersExampleTests.cs
View file @
d75d29e2
...
...
@@ -215,5 +215,44 @@ namespace FlatBuffers.Test
Assert
.
AreEqual
(
"NONE"
,
Any
.
NONE
.
ToString
());
Assert
.
AreEqual
(
"Monster"
,
Any
.
Monster
.
ToString
());
}
[
FlatBuffersTestMethod
]
public
void
TestNestedFlatBuffer
()
{
const
string
nestedMonsterName
=
"NestedMonsterName"
;
const
short
nestedMonsterHp
=
600
;
const
short
nestedMonsterMana
=
1024
;
// Create nested buffer as a Monster type
var
fbb1
=
new
FlatBufferBuilder
(
16
);
var
str1
=
fbb1
.
CreateString
(
nestedMonsterName
);
Monster
.
StartMonster
(
fbb1
);
Monster
.
AddName
(
fbb1
,
str1
);
Monster
.
AddHp
(
fbb1
,
nestedMonsterHp
);
Monster
.
AddMana
(
fbb1
,
nestedMonsterMana
);
var
monster1
=
Monster
.
EndMonster
(
fbb1
);
Monster
.
FinishMonsterBuffer
(
fbb1
,
monster1
);
var
fbb1Bytes
=
fbb1
.
SizedByteArray
();
fbb1
=
null
;
// Create a Monster which has the first buffer as a nested buffer
var
fbb2
=
new
FlatBufferBuilder
(
16
);
var
str2
=
fbb2
.
CreateString
(
"My Monster"
);
var
nestedBuffer
=
Monster
.
CreateTestnestedflatbufferVector
(
fbb2
,
fbb1Bytes
);
Monster
.
StartMonster
(
fbb2
);
Monster
.
AddName
(
fbb2
,
str2
);
Monster
.
AddHp
(
fbb2
,
50
);
Monster
.
AddMana
(
fbb2
,
32
);
Monster
.
AddTestnestedflatbuffer
(
fbb2
,
nestedBuffer
);
var
monster
=
Monster
.
EndMonster
(
fbb2
);
Monster
.
FinishMonsterBuffer
(
fbb2
,
monster
);
// Now test the data extracted from the nested buffer
var
mons
=
Monster
.
GetRootAsMonster
(
fbb2
.
DataBuffer
);
var
nestedMonster
=
mons
.
TestnestedflatbufferAsMonster
();
Assert
.
AreEqual
(
nestedMonsterMana
,
nestedMonster
.
Mana
);
Assert
.
AreEqual
(
nestedMonsterHp
,
nestedMonster
.
Hp
);
Assert
.
AreEqual
(
nestedMonsterName
,
nestedMonster
.
Name
);
}
}
}
tests/JavaTest.java
View file @
d75d29e2
...
...
@@ -159,6 +159,8 @@ class JavaTest {
TestNamespaceNesting
();
TestNestedFlatBuffer
();
System
.
out
.
println
(
"FlatBuffers test: completed successfully"
);
}
...
...
@@ -242,6 +244,42 @@ class JavaTest {
TableInFirstNS
.
addFooTable
(
fbb
,
nestedTableOff
);
int
off
=
TableInFirstNS
.
endTableInFirstNS
(
fbb
);
}
static
void
TestNestedFlatBuffer
()
{
final
String
nestedMonsterName
=
"NestedMonsterName"
;
final
short
nestedMonsterHp
=
600
;
final
short
nestedMonsterMana
=
1024
;
FlatBufferBuilder
fbb1
=
new
FlatBufferBuilder
(
16
);
int
str1
=
fbb1
.
createString
(
nestedMonsterName
);
Monster
.
startMonster
(
fbb1
);
Monster
.
addName
(
fbb1
,
str1
);
Monster
.
addHp
(
fbb1
,
nestedMonsterHp
);
Monster
.
addMana
(
fbb1
,
nestedMonsterMana
);
int
monster1
=
Monster
.
endMonster
(
fbb1
);
Monster
.
finishMonsterBuffer
(
fbb1
,
monster1
);
byte
[]
fbb1Bytes
=
fbb1
.
sizedByteArray
();
fbb1
=
null
;
FlatBufferBuilder
fbb2
=
new
FlatBufferBuilder
(
16
);
int
str2
=
fbb2
.
createString
(
"My Monster"
);
int
nestedBuffer
=
Monster
.
createTestnestedflatbufferVector
(
fbb2
,
fbb1Bytes
);
Monster
.
startMonster
(
fbb2
);
Monster
.
addName
(
fbb2
,
str2
);
Monster
.
addHp
(
fbb2
,
(
short
)
50
);
Monster
.
addMana
(
fbb2
,
(
short
)
32
);
Monster
.
addTestnestedflatbuffer
(
fbb2
,
nestedBuffer
);
int
monster
=
Monster
.
endMonster
(
fbb2
);
Monster
.
finishMonsterBuffer
(
fbb2
,
monster
);
// Now test the data extracted from the nested buffer
Monster
mons
=
Monster
.
getRootAsMonster
(
fbb2
.
dataBuffer
());
Monster
nestedMonster
=
mons
.
testnestedflatbufferAsMonster
();
TestEq
(
nestedMonsterMana
,
nestedMonster
.
mana
());
TestEq
(
nestedMonsterHp
,
nestedMonster
.
hp
());
TestEq
(
nestedMonsterName
,
nestedMonster
.
name
());
}
static
<
T
>
void
TestEq
(
T
a
,
T
b
)
{
if
(!
a
.
equals
(
b
))
{
...
...
tests/MyGame/Example/Monster.cs
View file @
d75d29e2
...
...
@@ -45,6 +45,8 @@ public sealed class Monster : Table {
public
byte
GetTestnestedflatbuffer
(
int
j
)
{
int
o
=
__offset
(
30
);
return
o
!=
0
?
bb
.
Get
(
__vector
(
o
)
+
j
*
1
)
:
(
byte
)
0
;
}
public
int
TestnestedflatbufferLength
{
get
{
int
o
=
__offset
(
30
);
return
o
!=
0
?
__vector_len
(
o
)
:
0
;
}
}
public
ArraySegment
<
byte
>?
GetTestnestedflatbufferBytes
()
{
return
__vector_as_arraysegment
(
30
);
}
public
Monster
TestnestedflatbufferAsMonster
()
{
return
GetTestnestedflatbufferAsMonster
(
new
Monster
());
}
public
Monster
GetTestnestedflatbufferAsMonster
(
Monster
obj
)
{
int
o
=
__offset
(
30
);
return
o
!=
0
?
obj
.
__init
(
__indirect
(
__vector
(
o
)),
bb
)
:
null
;
}
public
bool
MutateTestnestedflatbuffer
(
int
j
,
byte
testnestedflatbuffer
)
{
int
o
=
__offset
(
30
);
if
(
o
!=
0
)
{
bb
.
Put
(
__vector
(
o
)
+
j
*
1
,
testnestedflatbuffer
);
return
true
;
}
else
{
return
false
;
}
}
public
Stat
Testempty
{
get
{
return
GetTestempty
(
new
Stat
());
}
}
public
Stat
GetTestempty
(
Stat
obj
)
{
int
o
=
__offset
(
32
);
return
o
!=
0
?
obj
.
__init
(
__indirect
(
o
+
bb_pos
),
bb
)
:
null
;
}
...
...
tests/MyGame/Example/Monster.java
View file @
d75d29e2
...
...
@@ -51,6 +51,8 @@ public final class Monster extends Table {
public
int
testnestedflatbuffer
(
int
j
)
{
int
o
=
__offset
(
30
);
return
o
!=
0
?
bb
.
get
(
__vector
(
o
)
+
j
*
1
)
&
0xFF
:
0
;
}
public
int
testnestedflatbufferLength
()
{
int
o
=
__offset
(
30
);
return
o
!=
0
?
__vector_len
(
o
)
:
0
;
}
public
ByteBuffer
testnestedflatbufferAsByteBuffer
()
{
return
__vector_as_bytebuffer
(
30
,
1
);
}
public
Monster
testnestedflatbufferAsMonster
()
{
return
testnestedflatbufferAsMonster
(
new
Monster
());
}
public
Monster
testnestedflatbufferAsMonster
(
Monster
obj
)
{
int
o
=
__offset
(
30
);
return
o
!=
0
?
obj
.
__init
(
__indirect
(
__vector
(
o
)),
bb
)
:
null
;
}
public
boolean
mutateTestnestedflatbuffer
(
int
j
,
int
testnestedflatbuffer
)
{
int
o
=
__offset
(
30
);
if
(
o
!=
0
)
{
bb
.
put
(
__vector
(
o
)
+
j
*
1
,
(
byte
)
testnestedflatbuffer
);
return
true
;
}
else
{
return
false
;
}
}
public
Stat
testempty
()
{
return
testempty
(
new
Stat
());
}
public
Stat
testempty
(
Stat
obj
)
{
int
o
=
__offset
(
32
);
return
o
!=
0
?
obj
.
__init
(
__indirect
(
o
+
bb_pos
),
bb
)
:
null
;
}
...
...
tests/monster_test_generated.h
View file @
d75d29e2
...
...
@@ -102,7 +102,7 @@ STRUCT_END(Vec3, 32);
struct
TestSimpleTableWithEnum
FLATBUFFERS_FINAL_CLASS
:
private
flatbuffers
::
Table
{
enum
{
VT_COLOR
=
4
,
VT_COLOR
=
4
};
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
));
}
...
...
@@ -136,7 +136,7 @@ struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum
{
VT_ID
=
4
,
VT_VAL
=
6
,
VT_COUNT
=
8
,
VT_COUNT
=
8
};
const
flatbuffers
::
String
*
id
()
const
{
return
GetPointer
<
const
flatbuffers
::
String
*>
(
VT_ID
);
}
flatbuffers
::
String
*
mutable_id
()
{
return
GetPointer
<
flatbuffers
::
String
*>
(
VT_ID
);
}
...
...
@@ -205,7 +205,7 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_TESTHASHU32_FNV1A
=
46
,
VT_TESTHASHS64_FNV1A
=
48
,
VT_TESTHASHU64_FNV1A
=
50
,
VT_TESTARRAYOFBOOLS
=
52
,
VT_TESTARRAYOFBOOLS
=
52
};
const
Vec3
*
pos
()
const
{
return
GetStruct
<
const
Vec3
*>
(
VT_POS
);
}
Vec3
*
mutable_pos
()
{
return
GetStruct
<
Vec3
*>
(
VT_POS
);
}
...
...
tests/namespace_test/namespace_test1_generated.h
View file @
d75d29e2
...
...
@@ -45,7 +45,7 @@ STRUCT_END(StructInNestedNS, 8);
struct
TableInNestedNS
FLATBUFFERS_FINAL_CLASS
:
private
flatbuffers
::
Table
{
enum
{
VT_FOO
=
4
,
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
);
}
...
...
tests/namespace_test/namespace_test2_generated.h
View file @
d75d29e2
...
...
@@ -22,7 +22,7 @@ struct TableInFirstNS FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum
{
VT_FOO_TABLE
=
4
,
VT_FOO_ENUM
=
6
,
VT_FOO_STRUCT
=
8
,
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
);
}
...
...
tests/test.cpp
View file @
d75d29e2
...
...
@@ -478,8 +478,8 @@ void FuzzTest1() {
const
uint16_t
ushort_val
=
0xFEEE
;
const
int32_t
int_val
=
0x83333333
;
const
uint32_t
uint_val
=
0xFDDDDDDD
;
const
int64_t
long_val
=
0x8444444444444444
;
const
uint64_t
ulong_val
=
0xFCCCCCCCCCCCCCCC
;
const
int64_t
long_val
=
0x8444444444444444
LL
;
const
uint64_t
ulong_val
=
0xFCCCCCCCCCCCCCCC
ULL
;
const
float
float_val
=
3.14159
f
;
const
double
double_val
=
3.14159265359
;
...
...
@@ -564,8 +564,28 @@ void FuzzTest2() {
struct
RndDef
{
std
::
string
instances
[
instances_per_definition
];
// Since we're generating schema and corresponding data in tandem,
// this convenience function adds strings to both at once.
static
void
Add
(
RndDef
(
&
definitions_l
)[
num_definitions
],
std
::
string
&
schema_l
,
const
int
instances_per_definition_l
,
const
char
*
schema_add
,
const
char
*
instance_add
,
int
definition
)
{
schema_l
+=
schema_add
;
for
(
int
i
=
0
;
i
<
instances_per_definition_l
;
i
++
)
definitions_l
[
definition
].
instances
[
i
]
+=
instance_add
;
}
};
#define AddToSchemaAndInstances(schema_add, instance_add) \
RndDef::Add(definitions, schema, instances_per_definition, \
schema_add, instance_add, definition)
#define Dummy() \
RndDef::Add(definitions, schema, instances_per_definition, \
"byte", "1", definition)
RndDef
definitions
[
num_definitions
];
// We are going to generate num_definitions, the first
...
...
@@ -577,17 +597,6 @@ void FuzzTest2() {
// being generated. We generate multiple instances such that when creating
// hierarchy, we get some variety by picking one randomly.
for
(
int
definition
=
0
;
definition
<
num_definitions
;
definition
++
)
{
// Since we're generating schema & and corresponding data in tandem,
// this convenience function adds strings to both at once.
auto
AddToSchemaAndInstances
=
[
&
](
const
char
*
schema_add
,
const
char
*
instance_add
)
{
schema
+=
schema_add
;
for
(
int
i
=
0
;
i
<
instances_per_definition
;
i
++
)
definitions
[
definition
].
instances
[
i
]
+=
instance_add
;
};
// Generate a default type if we can't generate something else.
auto
Dummy
=
[
&
]()
{
AddToSchemaAndInstances
(
"byte"
,
"1"
);
};
std
::
string
definition_name
=
"D"
+
flatbuffers
::
NumToString
(
definition
);
bool
is_struct
=
definition
<
num_struct_definitions
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment