[C++] Refactor to conform to Google C++ style guide (#5608)

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

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

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

* Fixed clang-format issues by running clang-format twice to correct itself. Kotlin was missing clang-format on after turning it off, so it was changed,
This commit is contained in:
Derek Bailey
2019-11-07 12:22:54 -08:00
committed by Wouter van Oortmerssen
parent e837d5a296
commit f0f0efe7b8
36 changed files with 3157 additions and 3294 deletions

View File

@@ -19,6 +19,7 @@
#include <map> #include <map>
#include <sstream> #include <sstream>
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
namespace flatbuffers { namespace flatbuffers {
@@ -95,8 +96,7 @@ class BaseGenerator {
protected: protected:
BaseGenerator(const Parser &parser, const std::string &path, BaseGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, const std::string &file_name, std::string qualifying_start,
std::string qualifying_start,
std::string qualifying_separator) std::string qualifying_separator)
: parser_(parser), : parser_(parser),
path_(path), path_(path),

View File

@@ -20,7 +20,7 @@
#include "flatbuffers/base.h" #include "flatbuffers/base.h"
#if defined(FLATBUFFERS_NAN_DEFAULTS) #if defined(FLATBUFFERS_NAN_DEFAULTS)
#include <cmath> # include <cmath>
#endif #endif
namespace flatbuffers { namespace flatbuffers {
@@ -203,11 +203,10 @@ template<typename T, typename IT> struct VectorIterator {
const uint8_t *data_; const uint8_t *data_;
}; };
template<typename Iterator> struct VectorReverseIterator : template<typename Iterator>
public std::reverse_iterator<Iterator> { struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
explicit VectorReverseIterator(Iterator iter)
explicit VectorReverseIterator(Iterator iter) : : std::reverse_iterator<Iterator>(iter) {}
std::reverse_iterator<Iterator>(iter) {}
typename Iterator::value_type operator*() const { typename Iterator::value_type operator*() const {
return *(std::reverse_iterator<Iterator>::current); return *(std::reverse_iterator<Iterator>::current);
@@ -277,10 +276,14 @@ template<typename T> class Vector {
const_iterator end() const { return const_iterator(Data(), size()); } const_iterator end() const { return const_iterator(Data(), size()); }
reverse_iterator rbegin() { return reverse_iterator(end() - 1); } reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end() - 1); } const_reverse_iterator rbegin() const {
return const_reverse_iterator(end() - 1);
}
reverse_iterator rend() { return reverse_iterator(begin() - 1); } reverse_iterator rend() { return reverse_iterator(begin() - 1); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin() - 1); } const_reverse_iterator rend() const {
return const_reverse_iterator(begin() - 1);
}
const_iterator cbegin() const { return begin(); } const_iterator cbegin() const { return begin(); }
@@ -403,7 +406,8 @@ template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
// This is used as a helper type for accessing arrays. // This is used as a helper type for accessing arrays.
template<typename T, uint16_t length> class Array { template<typename T, uint16_t length> class Array {
typedef typedef
typename flatbuffers::integral_constant<bool, flatbuffers::is_scalar<T>::value> typename flatbuffers::integral_constant<bool,
flatbuffers::is_scalar<T>::value>
scalar_tag; scalar_tag;
typedef typedef
typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type
@@ -449,9 +453,7 @@ template<typename T, uint16_t length> class Array {
} }
// Change elements if you have a non-const pointer to this object. // Change elements if you have a non-const pointer to this object.
void Mutate(uoffset_t i, const T &val) { void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); }
MutateImpl(scalar_tag(), i, val);
}
// The raw data in little endian format. Use with care. // The raw data in little endian format. Use with care.
const uint8_t *Data() const { return data_; } const uint8_t *Data() const { return data_; }
@@ -544,13 +546,13 @@ struct String : public Vector<char> {
// Convenience function to get std::string from a String returning an empty // Convenience function to get std::string from a String returning an empty
// string on null pointer. // string on null pointer.
static inline std::string GetString(const String * str) { static inline std::string GetString(const String *str) {
return str ? str->str() : ""; return str ? str->str() : "";
} }
// Convenience function to get char* from a String returning an empty string on // Convenience function to get char* from a String returning an empty string on
// null pointer. // null pointer.
static inline const char * GetCstring(const String * str) { static inline const char *GetCstring(const String *str) {
return str ? str->c_str() : ""; return str ? str->c_str() : "";
} }
@@ -587,9 +589,9 @@ class Allocator {
// to `new_p` of `new_size`. Only memory of size `in_use_front` and // to `new_p` of `new_size`. Only memory of size `in_use_front` and
// `in_use_back` will be copied from the front and back of the old memory // `in_use_back` will be copied from the front and back of the old memory
// allocation. // allocation.
void memcpy_downward(uint8_t *old_p, size_t old_size, void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
uint8_t *new_p, size_t new_size, size_t new_size, size_t in_use_back,
size_t in_use_back, size_t in_use_front) { size_t in_use_front) {
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back, memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
in_use_back); in_use_back);
memcpy(new_p, old_p, in_use_front); memcpy(new_p, old_p, in_use_front);
@@ -603,13 +605,9 @@ class DefaultAllocator : public Allocator {
return new uint8_t[size]; return new uint8_t[size];
} }
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
delete[] p;
}
static void dealloc(void *p, size_t) { static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
delete[] static_cast<uint8_t *>(p);
}
}; };
// These functions allow for a null allocator to mean use the default allocator, // These functions allow for a null allocator to mean use the default allocator,
@@ -622,18 +620,19 @@ inline uint8_t *Allocate(Allocator *allocator, size_t size) {
} }
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) { inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
if (allocator) allocator->deallocate(p, size); if (allocator)
else DefaultAllocator().deallocate(p, size); allocator->deallocate(p, size);
else
DefaultAllocator().deallocate(p, size);
} }
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p, inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
size_t old_size, size_t new_size, size_t old_size, size_t new_size,
size_t in_use_back, size_t in_use_front) { size_t in_use_back, size_t in_use_front) {
return allocator return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
? allocator->reallocate_downward(old_p, old_size, new_size, in_use_back, in_use_front)
in_use_back, in_use_front) : DefaultAllocator().reallocate_downward(
: DefaultAllocator().reallocate_downward(old_p, old_size, new_size, old_p, old_size, new_size, in_use_back, in_use_front);
in_use_back, in_use_front);
} }
// DetachedBuffer is a finished flatbuffer memory region, detached from its // DetachedBuffer is a finished flatbuffer memory region, detached from its
@@ -678,8 +677,7 @@ class DetachedBuffer {
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
DetachedBuffer &operator=(DetachedBuffer &&other) { DetachedBuffer &operator=(DetachedBuffer &&other) {
if (this == &other) if (this == &other) return *this;
return *this;
destroy(); destroy();
@@ -737,7 +735,7 @@ class DetachedBuffer {
#endif // !defined(FLATBUFFERS_CPP98_STL) #endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
protected: protected:
Allocator *allocator_; Allocator *allocator_;
bool own_allocator_; bool own_allocator_;
uint8_t *buf_; uint8_t *buf_;
@@ -769,10 +767,8 @@ protected:
// Essentially, this supports 2 std::vectors in a single buffer. // Essentially, this supports 2 std::vectors in a single buffer.
class vector_downward { class vector_downward {
public: public:
explicit vector_downward(size_t initial_size, explicit vector_downward(size_t initial_size, Allocator *allocator,
Allocator *allocator, bool own_allocator, size_t buffer_minalign)
bool own_allocator,
size_t buffer_minalign)
: allocator_(allocator), : allocator_(allocator),
own_allocator_(own_allocator), own_allocator_(own_allocator),
initial_size_(initial_size), initial_size_(initial_size),
@@ -788,15 +784,15 @@ class vector_downward {
#else #else
vector_downward(vector_downward &other) vector_downward(vector_downward &other)
#endif // defined(FLATBUFFERS_CPP98_STL) #endif // defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
: allocator_(other.allocator_), : allocator_(other.allocator_),
own_allocator_(other.own_allocator_), own_allocator_(other.own_allocator_),
initial_size_(other.initial_size_), initial_size_(other.initial_size_),
buffer_minalign_(other.buffer_minalign_), buffer_minalign_(other.buffer_minalign_),
reserved_(other.reserved_), reserved_(other.reserved_),
buf_(other.buf_), buf_(other.buf_),
cur_(other.cur_), cur_(other.cur_),
scratch_(other.scratch_) { scratch_(other.scratch_) {
// No change in other.allocator_ // No change in other.allocator_
// No change in other.initial_size_ // No change in other.initial_size_
// No change in other.buffer_minalign_ // No change in other.buffer_minalign_
@@ -840,9 +836,7 @@ class vector_downward {
clear_scratch(); clear_scratch();
} }
void clear_scratch() { void clear_scratch() { scratch_ = buf_; }
scratch_ = buf_;
}
void clear_allocator() { void clear_allocator() {
if (own_allocator_ && allocator_) { delete allocator_; } if (own_allocator_ && allocator_) { delete allocator_; }
@@ -995,8 +989,8 @@ class vector_downward {
auto old_reserved = reserved_; auto old_reserved = reserved_;
auto old_size = size(); auto old_size = size();
auto old_scratch_size = scratch_size(); auto old_scratch_size = scratch_size();
reserved_ += (std::max)(len, reserved_ +=
old_reserved ? old_reserved / 2 : initial_size_); (std::max)(len, old_reserved ? old_reserved / 2 : initial_size_);
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1); reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
if (buf_) { if (buf_) {
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_, buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
@@ -1021,13 +1015,13 @@ const T *data(const std::vector<T, Alloc> &v) {
// Eventually the returned pointer gets passed down to memcpy, so // Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior. // we need it to be non-null to avoid undefined behavior.
static uint8_t t; static uint8_t t;
return v.empty() ? reinterpret_cast<const T*>(&t) : &v.front(); return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
} }
template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) { template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
// Eventually the returned pointer gets passed down to memcpy, so // Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior. // we need it to be non-null to avoid undefined behavior.
static uint8_t t; static uint8_t t;
return v.empty() ? reinterpret_cast<T*>(&t) : &v.front(); return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
} }
/// @endcond /// @endcond
@@ -1054,11 +1048,10 @@ class FlatBufferBuilder {
/// minimum alignment upon reallocation. Only needed if you intend to store /// minimum alignment upon reallocation. Only needed if you intend to store
/// types with custom alignment AND you wish to read the buffer in-place /// types with custom alignment AND you wish to read the buffer in-place
/// directly after creation. /// directly after creation.
explicit FlatBufferBuilder(size_t initial_size = 1024, explicit FlatBufferBuilder(
Allocator *allocator = nullptr, size_t initial_size = 1024, Allocator *allocator = nullptr,
bool own_allocator = false, bool own_allocator = false,
size_t buffer_minalign = size_t buffer_minalign = AlignOf<largest_scalar_t>())
AlignOf<largest_scalar_t>())
: buf_(initial_size, allocator, own_allocator, buffer_minalign), : buf_(initial_size, allocator, own_allocator, buffer_minalign),
num_field_loc(0), num_field_loc(0),
max_voffset_(0), max_voffset_(0),
@@ -1161,8 +1154,8 @@ class FlatBufferBuilder {
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
/// @return A `FlatBuffer` that owns the buffer and its allocator and /// @return A `FlatBuffer` that owns the buffer and its allocator and
/// behaves similar to a `unique_ptr` with a deleter. /// behaves similar to a `unique_ptr` with a deleter.
FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead"))
ReleaseBufferPointer() { DetachedBuffer ReleaseBufferPointer() {
Finished(); Finished();
return buf_.release(); return buf_.release();
} }
@@ -1181,7 +1174,8 @@ class FlatBufferBuilder {
/// `FlatBuffer` starts. /// `FlatBuffer` starts.
/// @return A raw pointer to the start of the memory block containing /// @return A raw pointer to the start of the memory block containing
/// the serialized `FlatBuffer`. /// the serialized `FlatBuffer`.
/// @remark If the allocator is owned, it gets deleted when the destructor is called.. /// @remark If the allocator is owned, it gets deleted when the destructor is
/// called..
uint8_t *ReleaseRaw(size_t &size, size_t &offset) { uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
Finished(); Finished();
return buf_.release_raw(size, offset); return buf_.release_raw(size, offset);
@@ -1210,8 +1204,9 @@ class FlatBufferBuilder {
/// @brief In order to save space, fields that are set to their default value /// @brief In order to save space, fields that are set to their default value
/// don't get serialized into the buffer. /// don't get serialized into the buffer.
/// @param[in] fd When set to `true`, always serializes default values that are set. /// @param[in] fd When set to `true`, always serializes default values that
/// Optional fields which are not set explicitly, will still not be serialized. /// are set. Optional fields which are not set explicitly, will still not be
/// serialized.
void ForceDefaults(bool fd) { force_defaults_ = fd; } void ForceDefaults(bool fd) { force_defaults_ = fd; }
/// @brief By default vtables are deduped in order to save space. /// @brief By default vtables are deduped in order to save space.
@@ -1835,7 +1830,7 @@ class FlatBufferBuilder {
extern T Pack(const S &); extern T Pack(const S &);
typedef T (*Pack_t)(const S &); typedef T (*Pack_t)(const S &);
std::vector<T> vv(len); std::vector<T> vv(len);
std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack)); std::transform(v, v + len, vv.begin(), static_cast<Pack_t &>(Pack));
return CreateVectorOfSortedStructs<T>(vv, len); return CreateVectorOfSortedStructs<T>(vv, len);
} }
@@ -1916,12 +1911,12 @@ class FlatBufferBuilder {
} }
template<typename T> template<typename T>
Offset<Vector<const T*>> CreateUninitializedVectorOfStructs(size_t len, T **buf) { Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
T **buf) {
return CreateUninitializedVector(len, sizeof(T), return CreateUninitializedVector(len, sizeof(T),
reinterpret_cast<uint8_t **>(buf)); reinterpret_cast<uint8_t **>(buf));
} }
// @brief Create a vector of scalar type T given as input a vector of scalar // @brief Create a vector of scalar type T given as input a vector of scalar
// type U, useful with e.g. pre "enum class" enums, or any existing scalar // type U, useful with e.g. pre "enum class" enums, or any existing scalar
// data of the wrong type. // data of the wrong type.
@@ -1970,8 +1965,7 @@ class FlatBufferBuilder {
buf_.swap_allocator(other.buf_); buf_.swap_allocator(other.buf_);
} }
protected: protected:
// You shouldn't really be copying instances of this class. // You shouldn't really be copying instances of this class.
FlatBufferBuilder(const FlatBufferBuilder &); FlatBufferBuilder(const FlatBufferBuilder &);
FlatBufferBuilder &operator=(const FlatBufferBuilder &); FlatBufferBuilder &operator=(const FlatBufferBuilder &);
@@ -2024,8 +2018,8 @@ protected:
bool operator()(const Offset<String> &a, const Offset<String> &b) const { bool operator()(const Offset<String> &a, const Offset<String> &b) const {
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o)); auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o)); auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
return StringLessThan(stra->data(), stra->size(), return StringLessThan(stra->data(), stra->size(), strb->data(),
strb->data(), strb->size()); strb->size());
} }
const vector_downward *buf_; const vector_downward *buf_;
}; };
@@ -2089,13 +2083,15 @@ const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
/// This function is UNDEFINED for FlatBuffers whose schema does not include /// This function is UNDEFINED for FlatBuffers whose schema does not include
/// a file_identifier (likely points at padding or the start of a the root /// a file_identifier (likely points at padding or the start of a the root
/// vtable). /// vtable).
inline const char *GetBufferIdentifier(const void *buf, bool size_prefixed = false) { inline const char *GetBufferIdentifier(const void *buf,
bool size_prefixed = false) {
return reinterpret_cast<const char *>(buf) + return reinterpret_cast<const char *>(buf) +
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t)); ((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
} }
// Helper to see if the identifier in a buffer has the expected value. // Helper to see if the identifier in a buffer has the expected value.
inline bool BufferHasIdentifier(const void *buf, const char *identifier, bool size_prefixed = false) { inline bool BufferHasIdentifier(const void *buf, const char *identifier,
bool size_prefixed = false) {
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier, return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
FlatBufferBuilder::kFileIdentifierLength) == 0; FlatBufferBuilder::kFileIdentifierLength) == 0;
} }
@@ -2112,8 +2108,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
num_tables_(0), num_tables_(0),
max_tables_(_max_tables), max_tables_(_max_tables),
upper_bound_(0), upper_bound_(0),
check_alignment_(_check_alignment) check_alignment_(_check_alignment) {
{
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE); FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
} }
@@ -2162,8 +2157,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len); return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
} }
template<typename T> bool Verify(const uint8_t *base, voffset_t elem_off) template<typename T>
const { bool Verify(const uint8_t *base, voffset_t elem_off) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T)); return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
} }
@@ -2186,16 +2181,15 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
// Verify a pointer (may be NULL) to string. // Verify a pointer (may be NULL) to string.
bool VerifyString(const String *str) const { bool VerifyString(const String *str) const {
size_t end; size_t end;
return !str || return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
(VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str), 1, &end) &&
1, &end) && Verify(end, 1) && // Must have terminator
Verify(end, 1) && // Must have terminator Check(buf_[end] == '\0')); // Terminating byte must be 0.
Check(buf_[end] == '\0')); // Terminating byte must be 0.
} }
// Common code between vectors and strings. // Common code between vectors and strings.
bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size, bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size,
size_t *end = nullptr) const { size_t *end = nullptr) const {
auto veco = static_cast<size_t>(vec - buf_); auto veco = static_cast<size_t>(vec - buf_);
// Check we can read the size field. // Check we can read the size field.
if (!Verify<uoffset_t>(veco)) return false; if (!Verify<uoffset_t>(veco)) return false;
@@ -2230,8 +2224,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return true; return true;
} }
__supress_ubsan__("unsigned-integer-overflow") __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
bool VerifyTableStart(const uint8_t *table) { const uint8_t *table) {
// Check the vtable offset. // Check the vtable offset.
auto tableo = static_cast<size_t>(table - buf_); auto tableo = static_cast<size_t>(table - buf_);
if (!Verify<soffset_t>(tableo)) return false; if (!Verify<soffset_t>(tableo)) return false;
@@ -2246,9 +2240,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
template<typename T> template<typename T>
bool VerifyBufferFromStart(const char *identifier, size_t start) { bool VerifyBufferFromStart(const char *identifier, size_t start) {
if (identifier && if (identifier && (size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
(size_ < 2 * sizeof(flatbuffers::uoffset_t) || !BufferHasIdentifier(buf_ + start, identifier))) {
!BufferHasIdentifier(buf_ + start, identifier))) {
return false; return false;
} }
@@ -2496,8 +2489,8 @@ class Table {
uint8_t data_[1]; uint8_t data_[1];
}; };
template<typename T> void FlatBufferBuilder::Required(Offset<T> table, template<typename T>
voffset_t field) { void FlatBufferBuilder::Required(Offset<T> table, voffset_t field) {
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o)); auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
// If this fails, the caller will show what field needs to be set. // If this fails, the caller will show what field needs to be set.
@@ -2544,7 +2537,9 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
} }
/// @brief This return the prefixed size of a FlatBuffer. /// @brief This return the prefixed size of a FlatBuffer.
inline uoffset_t GetPrefixedSize(const uint8_t* buf){ return ReadScalar<uoffset_t>(buf); } inline uoffset_t GetPrefixedSize(const uint8_t *buf) {
return ReadScalar<uoffset_t>(buf);
}
// Base class for native objects (FlatBuffer data de-serialized into native // Base class for native objects (FlatBuffer data de-serialized into native
// C++ data structures). // C++ data structures).
@@ -2687,10 +2682,10 @@ typedef const TypeTable *(*TypeFunction)();
struct TypeTable { struct TypeTable {
SequenceType st; SequenceType st;
size_t num_elems; // of type_codes, values, names (but not type_refs). size_t num_elems; // of type_codes, values, names (but not type_refs).
const TypeCode *type_codes; // num_elems count const TypeCode *type_codes; // num_elems count
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode). const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
const int64_t *values; // Only set for non-consecutive enum/union or structs. const int64_t *values; // Only set for non-consecutive enum/union or structs.
const char * const *names; // Only set if compiled with --reflect-names. const char *const *names; // Only set if compiled with --reflect-names.
}; };
// String which identifies the current version of FlatBuffers. // String which identifies the current version of FlatBuffers.

View File

@@ -17,6 +17,7 @@
#include <functional> #include <functional>
#include <limits> #include <limits>
#include <string> #include <string>
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"

View File

@@ -339,12 +339,12 @@ class Map : public Vector {
template<typename T> template<typename T>
void AppendToString(std::string &s, T &&v, bool keys_quoted) { void AppendToString(std::string &s, T &&v, bool keys_quoted) {
s += "[ "; s += "[ ";
for (size_t i = 0; i < v.size(); i++) { for (size_t i = 0; i < v.size(); i++) {
if (i) s += ", "; if (i) s += ", ";
v[i].ToString(true, keys_quoted, s); v[i].ToString(true, keys_quoted, s);
} }
s += " ]"; s += " ]";
} }
class Reference { class Reference {
@@ -386,13 +386,17 @@ class Reference {
bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; } bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
bool IsUntypedVector() const { return type_ == FBT_VECTOR; } bool IsUntypedVector() const { return type_ == FBT_VECTOR; }
bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); } bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
bool IsFixedTypedVector() const { return flexbuffers::IsFixedTypedVector(type_); } bool IsFixedTypedVector() const {
bool IsAnyVector() const { return (IsTypedVector() || IsFixedTypedVector() || IsVector());} return flexbuffers::IsFixedTypedVector(type_);
}
bool IsAnyVector() const {
return (IsTypedVector() || IsFixedTypedVector() || IsVector());
}
bool IsMap() const { return type_ == FBT_MAP; } bool IsMap() const { return type_ == FBT_MAP; }
bool IsBlob() const { return type_ == FBT_BLOB; } bool IsBlob() const { return type_ == FBT_BLOB; }
bool AsBool() const { bool AsBool() const {
return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_) return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_)
: AsUInt64()) != 0; : AsUInt64()) != 0;
} }
// Reads any type as a int64_t. Never fails, does most sensible conversion. // Reads any type as a int64_t. Never fails, does most sensible conversion.
@@ -555,7 +559,8 @@ class Reference {
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted); AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
} else if (IsBlob()) { } else if (IsBlob()) {
auto blob = AsBlob(); auto blob = AsBlob();
flatbuffers::EscapeString(reinterpret_cast<const char*>(blob.data()), blob.size(), &s, true, false); flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
blob.size(), &s, true, false);
} else { } else {
s += "(?)"; s += "(?)";
} }
@@ -729,9 +734,15 @@ template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); }
template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); } template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); } template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
template<> inline uint16_t Reference::As<uint16_t>() const { return AsUInt16(); } template<> inline uint16_t Reference::As<uint16_t>() const {
template<> inline uint32_t Reference::As<uint32_t>() const { return AsUInt32(); } return AsUInt16();
template<> inline uint64_t Reference::As<uint64_t>() const { return AsUInt64(); } }
template<> inline uint32_t Reference::As<uint32_t>() const {
return AsUInt32();
}
template<> inline uint64_t Reference::As<uint64_t>() const {
return AsUInt64();
}
template<> inline double Reference::As<double>() const { return AsDouble(); } template<> inline double Reference::As<double>() const { return AsDouble(); }
template<> inline float Reference::As<float>() const { return AsFloat(); } template<> inline float Reference::As<float>() const { return AsFloat(); }
@@ -920,9 +931,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Bool(b); Bool(b);
} }
void IndirectInt(int64_t i) { void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); }
PushIndirect(i, FBT_INDIRECT_INT, WidthI(i));
}
void IndirectInt(const char *key, int64_t i) { void IndirectInt(const char *key, int64_t i) {
Key(key); Key(key);
IndirectInt(i); IndirectInt(i);
@@ -1214,9 +1223,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// Works on any data type. // Works on any data type.
struct Value; struct Value;
Value LastValue() { return stack_.back(); } Value LastValue() { return stack_.back(); }
void ReuseValue(Value v) { void ReuseValue(Value v) { stack_.push_back(v); }
stack_.push_back(v);
}
void ReuseValue(const char *key, Value v) { void ReuseValue(const char *key, Value v) {
Key(key); Key(key);
ReuseValue(v); ReuseValue(v);
@@ -1462,7 +1469,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed, Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
bool fixed, const Value *keys = nullptr) { bool fixed, const Value *keys = nullptr) {
FLATBUFFERS_ASSERT(!fixed || typed); // typed=false, fixed=true combination is not supported. FLATBUFFERS_ASSERT(
!fixed ||
typed); // typed=false, fixed=true combination is not supported.
// Figure out smallest bit width we can store this vector with. // Figure out smallest bit width we can store this vector with.
auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len)); auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
auto prefix_elems = 1; auto prefix_elems = 1;
@@ -1542,7 +1551,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
typedef std::pair<size_t, size_t> StringOffset; typedef std::pair<size_t, size_t> StringOffset;
struct StringOffsetCompare { struct StringOffsetCompare {
explicit StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {} explicit StringOffsetCompare(const std::vector<uint8_t> &buf)
: buf_(&buf) {}
bool operator()(const StringOffset &a, const StringOffset &b) const { bool operator()(const StringOffset &a, const StringOffset &b) const {
auto stra = reinterpret_cast<const char *>( auto stra = reinterpret_cast<const char *>(
flatbuffers::vector_data(*buf_) + a.first); flatbuffers::vector_data(*buf_) + a.first);
@@ -1562,8 +1572,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
} // namespace flexbuffers } // namespace flexbuffers
# if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(pop) # pragma warning(pop)
# endif #endif
#endif // FLATBUFFERS_FLEXBUFFERS_H_ #endif // FLATBUFFERS_FLEXBUFFERS_H_

View File

@@ -88,8 +88,7 @@ class SliceAllocator : public Allocator {
SliceAllocator(const SliceAllocator &other) = delete; SliceAllocator(const SliceAllocator &other) = delete;
SliceAllocator &operator=(const SliceAllocator &other) = delete; SliceAllocator &operator=(const SliceAllocator &other) = delete;
SliceAllocator(SliceAllocator &&other) SliceAllocator(SliceAllocator &&other) : slice_(grpc_empty_slice()) {
: slice_(grpc_empty_slice()) {
// default-construct and swap idiom // default-construct and swap idiom
swap(other); swap(other);
} }
@@ -164,34 +163,36 @@ class MessageBuilder : private detail::SliceAllocatorMember,
public FlatBufferBuilder { public FlatBufferBuilder {
public: public:
explicit MessageBuilder(uoffset_t initial_size = 1024) explicit MessageBuilder(uoffset_t initial_size = 1024)
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {} : FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
MessageBuilder(const MessageBuilder &other) = delete; MessageBuilder(const MessageBuilder &other) = delete;
MessageBuilder &operator=(const MessageBuilder &other) = delete; MessageBuilder &operator=(const MessageBuilder &other) = delete;
MessageBuilder(MessageBuilder &&other) MessageBuilder(MessageBuilder &&other)
: FlatBufferBuilder(1024, &slice_allocator_, false) { : FlatBufferBuilder(1024, &slice_allocator_, false) {
// Default construct and swap idiom. // Default construct and swap idiom.
Swap(other); Swap(other);
} }
/// Create a MessageBuilder from a FlatBufferBuilder. /// Create a MessageBuilder from a FlatBufferBuilder.
explicit MessageBuilder(FlatBufferBuilder &&src, void (*dealloc)(void*, size_t) = &DefaultAllocator::dealloc) explicit MessageBuilder(FlatBufferBuilder &&src,
: FlatBufferBuilder(1024, &slice_allocator_, false) { void (*dealloc)(void *,
size_t) = &DefaultAllocator::dealloc)
: FlatBufferBuilder(1024, &slice_allocator_, false) {
src.Swap(*this); src.Swap(*this);
src.SwapBufAllocator(*this); src.SwapBufAllocator(*this);
if (buf_.capacity()) { if (buf_.capacity()) {
uint8_t *buf = buf_.scratch_data(); // pointer to memory uint8_t *buf = buf_.scratch_data(); // pointer to memory
size_t capacity = buf_.capacity(); // size of memory size_t capacity = buf_.capacity(); // size of memory
slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc); slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
} } else {
else {
slice_allocator_.slice_ = grpc_empty_slice(); slice_allocator_.slice_ = grpc_empty_slice();
} }
} }
/// Move-assign a FlatBufferBuilder to a MessageBuilder. /// Move-assign a FlatBufferBuilder to a MessageBuilder.
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is supported. /// Only FlatBufferBuilder with default allocator (basically, nullptr) is
/// supported.
MessageBuilder &operator=(FlatBufferBuilder &&src) { MessageBuilder &operator=(FlatBufferBuilder &&src) {
// Move construct a temporary and swap // Move construct a temporary and swap
MessageBuilder temp(std::move(src)); MessageBuilder temp(std::move(src));
@@ -209,10 +210,11 @@ class MessageBuilder : private detail::SliceAllocatorMember,
void Swap(MessageBuilder &other) { void Swap(MessageBuilder &other) {
slice_allocator_.swap(other.slice_allocator_); slice_allocator_.swap(other.slice_allocator_);
FlatBufferBuilder::Swap(other); FlatBufferBuilder::Swap(other);
// After swapping the FlatBufferBuilder, we swap back the allocator, which restores // After swapping the FlatBufferBuilder, we swap back the allocator, which
// the original allocator back in place. This is necessary because MessageBuilder's // restores the original allocator back in place. This is necessary because
// allocator is its own member (SliceAllocatorMember). The allocator passed to // MessageBuilder's allocator is its own member (SliceAllocatorMember). The
// FlatBufferBuilder::vector_downward must point to this member. // allocator passed to FlatBufferBuilder::vector_downward must point to this
// member.
buf_.swap_allocator(other.buf_); buf_.swap_allocator(other.buf_);
} }
@@ -232,10 +234,10 @@ class MessageBuilder : private detail::SliceAllocatorMember,
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer // flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
// ownership. // ownership.
template<class T> Message<T> GetMessage() { template<class T> Message<T> GetMessage() {
auto buf_data = buf_.scratch_data(); // pointer to memory auto buf_data = buf_.scratch_data(); // pointer to memory
auto buf_size = buf_.capacity(); // size of memory auto buf_size = buf_.capacity(); // size of memory
auto msg_data = buf_.data(); // pointer to msg auto msg_data = buf_.data(); // pointer to msg
auto msg_size = buf_.size(); // size of msg auto msg_size = buf_.size(); // size of msg
// Do some sanity checks on data/size // Do some sanity checks on data/size
FLATBUFFERS_ASSERT(msg_data); FLATBUFFERS_ASSERT(msg_data);
FLATBUFFERS_ASSERT(msg_size); FLATBUFFERS_ASSERT(msg_size);

View File

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

View File

@@ -338,13 +338,12 @@ struct StructDef : public Definition {
flatbuffers::unique_ptr<std::string> original_location; flatbuffers::unique_ptr<std::string> original_location;
}; };
struct EnumDef; struct EnumDef;
struct EnumValBuilder; struct EnumValBuilder;
struct EnumVal { struct EnumVal {
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(const Parser &parser, const reflection::EnumVal *val); bool Deserialize(const Parser &parser, const reflection::EnumVal *val);
@@ -449,21 +448,21 @@ inline bool IsEnum(const Type &type) {
inline size_t InlineSize(const Type &type) { inline size_t InlineSize(const Type &type) {
return IsStruct(type) return IsStruct(type)
? type.struct_def->bytesize ? type.struct_def->bytesize
: (IsArray(type) : (IsArray(type)
? InlineSize(type.VectorType()) * type.fixed_length ? InlineSize(type.VectorType()) * type.fixed_length
: SizeOf(type.base_type)); : SizeOf(type.base_type));
} }
inline size_t InlineAlignment(const Type &type) { inline size_t InlineAlignment(const Type &type) {
if (IsStruct(type)) { if (IsStruct(type)) {
return type.struct_def->minalign; return type.struct_def->minalign;
} else if (IsArray(type)) { } else if (IsArray(type)) {
return IsStruct(type.VectorType()) ? type.struct_def->minalign return IsStruct(type.VectorType()) ? type.struct_def->minalign
: SizeOf(type.element); : SizeOf(type.element);
} else { } else {
return SizeOf(type.base_type); return SizeOf(type.base_type);
} }
} }
inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) { inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) {
return lhs.value == rhs.value; return lhs.value == rhs.value;
@@ -480,7 +479,8 @@ inline bool EqualByName(const Type &a, const Type &b) {
} }
struct RPCCall : public Definition { struct RPCCall : public Definition {
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::RPCCall *call); bool Deserialize(Parser &parser, const reflection::RPCCall *call);
@@ -488,7 +488,8 @@ struct RPCCall : public Definition {
}; };
struct ServiceDef : public Definition { struct ServiceDef : public Definition {
Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::Service *service); bool Deserialize(Parser &parser, const reflection::Service *service);
SymbolTable<RPCCall> calls; SymbolTable<RPCCall> calls;
@@ -722,9 +723,7 @@ class Parser : public ParserState {
source_(nullptr), source_(nullptr),
anonymous_counter(0), anonymous_counter(0),
recurse_protection_counter(0) { recurse_protection_counter(0) {
if (opts.force_defaults) { if (opts.force_defaults) { builder_.ForceDefaults(true); }
builder_.ForceDefaults(true);
}
// Start out with the empty namespace being current. // Start out with the empty namespace being current.
empty_namespace_ = new Namespace(); empty_namespace_ = new Namespace();
namespaces_.push_back(empty_namespace_); namespaces_.push_back(empty_namespace_);
@@ -795,9 +794,9 @@ class Parser : public ParserState {
// Fills internal structure as if the schema passed had been loaded by parsing // Fills internal structure as if the schema passed had been loaded by parsing
// with Parse except that included filenames will not be populated. // with Parse except that included filenames will not be populated.
bool Deserialize(const reflection::Schema* schema); bool Deserialize(const reflection::Schema *schema);
Type* DeserializeType(const reflection::Type* type); Type *DeserializeType(const reflection::Type *type);
// Checks that the schema represented by this parser is a safe evolution // Checks that the schema represented by this parser is a safe evolution
// of the schema provided. Returns non-empty error on any problems. // of the schema provided. Returns non-empty error on any problems.
@@ -854,16 +853,19 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue, FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
FieldDef *field, size_t fieldn); FieldDef *field, size_t fieldn);
FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array); FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field, FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
size_t fieldn, Value &val, FieldDef *field, size_t fieldn,
const StructDef *parent_struct_def); const StructDef *parent_struct_def);
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes); FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, bool check, Value &e, FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
BaseType req, bool *destmatch); bool check, Value &e, BaseType req,
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field); bool *destmatch);
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field);
FLATBUFFERS_CHECKED_ERROR TokenError(); FLATBUFFERS_CHECKED_ERROR TokenError();
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, bool check_now); FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, std::string *result); bool check_now);
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
std::string *result);
StructDef *LookupCreateStruct(const std::string &name, StructDef *LookupCreateStruct(const std::string &name,
bool create_if_new = true, bool create_if_new = true,
bool definition = false); bool definition = false);
@@ -871,8 +873,7 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR ParseNamespace(); FLATBUFFERS_CHECKED_ERROR ParseNamespace();
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name, FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
StructDef **dest); StructDef **dest);
FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
bool is_union,
EnumDef **dest); EnumDef **dest);
FLATBUFFERS_CHECKED_ERROR ParseDecl(); FLATBUFFERS_CHECKED_ERROR ParseDecl();
FLATBUFFERS_CHECKED_ERROR ParseService(); FLATBUFFERS_CHECKED_ERROR ParseService();
@@ -888,16 +889,15 @@ class Parser : public ParserState {
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source, FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
const char *source_filename); const char *source_filename);
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source, FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
const char **include_paths, const char **include_paths,
const char *source_filename); const char *source_filename);
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source, FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
const char **include_paths, const char **include_paths,
const char *source_filename, const char *source_filename,
const char *include_filename); const char *include_filename);
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields, FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
StructDef *struct_def, StructDef *struct_def,
const char *suffix, const char *suffix, BaseType baseType);
BaseType baseType);
bool SupportsAdvancedUnionFeatures() const; bool SupportsAdvancedUnionFeatures() const;
bool SupportsAdvancedArrayFeatures() const; bool SupportsAdvancedArrayFeatures() const;
@@ -914,7 +914,7 @@ class Parser : public ParserState {
std::vector<Namespace *> namespaces_; std::vector<Namespace *> namespaces_;
Namespace *current_namespace_; Namespace *current_namespace_;
Namespace *empty_namespace_; Namespace *empty_namespace_;
std::string error_; // User readable error_ if Parse() == false std::string error_; // User readable error_ if Parse() == false
FlatBufferBuilder builder_; // any data contained in the file FlatBufferBuilder builder_; // any data contained in the file
flexbuffers::Builder flex_builder_; flexbuffers::Builder flex_builder_;
@@ -957,121 +957,101 @@ extern std::string MakeScreamingCamel(const std::string &in);
// strict_json adds "quotes" around field names if true. // strict_json adds "quotes" around field names if true.
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 // If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
// byte arrays in String values), returns false. // byte arrays in String values), returns false.
extern bool GenerateTextFromTable(const Parser &parser, extern bool GenerateTextFromTable(const Parser &parser, const void *table,
const void *table,
const std::string &tablename, const std::string &tablename,
std::string *text); std::string *text);
extern bool GenerateText(const Parser &parser, extern bool GenerateText(const Parser &parser, const void *flatbuffer,
const void *flatbuffer,
std::string *text); std::string *text);
extern bool GenerateTextFile(const Parser &parser, extern bool GenerateTextFile(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate binary files from a given FlatBuffer, and a given Parser // Generate binary files from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema. // object that has been populated with the corresponding schema.
// See idl_gen_general.cpp. // See idl_gen_general.cpp.
extern bool GenerateBinary(const Parser &parser, extern bool GenerateBinary(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a C++ header from the definitions in the Parser object. // Generate a C++ header from the definitions in the Parser object.
// See idl_gen_cpp. // See idl_gen_cpp.
extern bool GenerateCPP(const Parser &parser, extern bool GenerateCPP(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
extern bool GenerateDart(const Parser &parser, extern bool GenerateDart(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate JavaScript or TypeScript code from the definitions in the Parser object. // Generate JavaScript or TypeScript code from the definitions in the Parser
// See idl_gen_js. // object. See idl_gen_js.
extern bool GenerateJSTS(const Parser &parser, extern bool GenerateJSTS(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
// Generate Go files from the definitions in the Parser object. // Generate Go files from the definitions in the Parser object.
// See idl_gen_go.cpp. // See idl_gen_go.cpp.
extern bool GenerateGo(const Parser &parser, extern bool GenerateGo(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Php code from the definitions in the Parser object. // Generate Php code from the definitions in the Parser object.
// See idl_gen_php. // See idl_gen_php.
extern bool GeneratePhp(const Parser &parser, extern bool GeneratePhp(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Python files from the definitions in the Parser object. // Generate Python files from the definitions in the Parser object.
// See idl_gen_python.cpp. // See idl_gen_python.cpp.
extern bool GeneratePython(const Parser &parser, extern bool GeneratePython(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Lobster files from the definitions in the Parser object. // Generate Lobster files from the definitions in the Parser object.
// See idl_gen_lobster.cpp. // See idl_gen_lobster.cpp.
extern bool GenerateLobster(const Parser &parser, extern bool GenerateLobster(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Lua files from the definitions in the Parser object. // Generate Lua files from the definitions in the Parser object.
// See idl_gen_lua.cpp. // See idl_gen_lua.cpp.
extern bool GenerateLua(const Parser &parser, extern bool GenerateLua(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
// Generate Rust files from the definitions in the Parser object. // Generate Rust files from the definitions in the Parser object.
// See idl_gen_rust.cpp. // See idl_gen_rust.cpp.
extern bool GenerateRust(const Parser &parser, extern bool GenerateRust(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Json schema file // Generate Json schema file
// See idl_gen_json_schema.cpp. // See idl_gen_json_schema.cpp.
extern bool GenerateJsonSchema(const Parser &parser, extern bool GenerateJsonSchema(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
extern bool GenerateKotlin(const Parser &parser, const std::string &path, extern bool GenerateKotlin(const Parser &parser, const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Java/C#/.. files from the definitions in the Parser object. // Generate Java/C#/.. files from the definitions in the Parser object.
// See idl_gen_general.cpp. // See idl_gen_general.cpp.
extern bool GenerateGeneral(const Parser &parser, extern bool GenerateGeneral(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a schema file from the internal representation, useful after // Generate a schema file from the internal representation, useful after
// parsing a .proto schema. // parsing a .proto schema.
extern std::string GenerateFBS(const Parser &parser, extern std::string GenerateFBS(const Parser &parser,
const std::string &file_name); const std::string &file_name);
extern bool GenerateFBS(const Parser &parser, extern bool GenerateFBS(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated JavaScript or TypeScript code. // Generate a make rule for the generated JavaScript or TypeScript code.
// See idl_gen_js.cpp. // See idl_gen_js.cpp.
extern std::string JSTSMakeRule(const Parser &parser, extern std::string JSTSMakeRule(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
// Generate a make rule for the generated C++ header. // Generate a make rule for the generated C++ header.
// See idl_gen_cpp.cpp. // See idl_gen_cpp.cpp.
extern std::string CPPMakeRule(const Parser &parser, extern std::string CPPMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Dart code // Generate a make rule for the generated Dart code
// see idl_gen_dart.cpp // see idl_gen_dart.cpp
extern std::string DartMakeRule(const Parser &parser, extern std::string DartMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Rust code. // Generate a make rule for the generated Rust code.
// See idl_gen_rust.cpp. // See idl_gen_rust.cpp.
extern std::string RustMakeRule(const Parser &parser, extern std::string RustMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Java/C#/... files. // Generate a make rule for the generated Java/C#/... files.
@@ -1082,32 +1062,27 @@ extern std::string GeneralMakeRule(const Parser &parser,
// Generate a make rule for the generated text (JSON) files. // Generate a make rule for the generated text (JSON) files.
// See idl_gen_text.cpp. // See idl_gen_text.cpp.
extern std::string TextMakeRule(const Parser &parser, extern std::string TextMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_names); const std::string &file_names);
// Generate a make rule for the generated binary files. // Generate a make rule for the generated binary files.
// See idl_gen_general.cpp. // See idl_gen_general.cpp.
extern std::string BinaryMakeRule(const Parser &parser, extern std::string BinaryMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Cpp interfaces. // Generate GRPC Cpp interfaces.
// See idl_gen_grpc.cpp. // See idl_gen_grpc.cpp.
bool GenerateCppGRPC(const Parser &parser, bool GenerateCppGRPC(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Go interfaces. // Generate GRPC Go interfaces.
// See idl_gen_grpc.cpp. // See idl_gen_grpc.cpp.
bool GenerateGoGRPC(const Parser &parser, bool GenerateGoGRPC(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Java classes. // Generate GRPC Java classes.
// See idl_gen_grpc.cpp // See idl_gen_grpc.cpp
bool GenerateJavaGRPC(const Parser &parser, bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
} // namespace flatbuffers } // namespace flatbuffers

View File

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

View File

@@ -17,10 +17,10 @@
#ifndef FLATBUFFERS_UTIL_H_ #ifndef FLATBUFFERS_UTIL_H_
#define FLATBUFFERS_UTIL_H_ #define FLATBUFFERS_UTIL_H_
#include "flatbuffers/base.h"
#include <errno.h> #include <errno.h>
#include "flatbuffers/base.h"
#ifndef FLATBUFFERS_PREFER_PRINTF #ifndef FLATBUFFERS_PREFER_PRINTF
# include <sstream> # include <sstream>
#else // FLATBUFFERS_PREFER_PRINTF #else // FLATBUFFERS_PREFER_PRINTF

View File

@@ -15,12 +15,14 @@
*/ */
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include <assert.h> #include <assert.h>
#include "flatbuffers/base.h"
#include "flatbuffers/util.h"
#include <cmath> #include <cmath>
#include "flatbuffers/base.h"
#include "flatbuffers/util.h"
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)
# pragma warning(disable : 4127) // C4127: conditional expression is constant # pragma warning(disable : 4127) // C4127: conditional expression is constant

View File

@@ -42,7 +42,7 @@ void FlatCompiler::LoadBinarySchema(flatbuffers::Parser &parser,
const std::string &filename, const std::string &filename,
const std::string &contents) { const std::string &contents) {
if (!parser.Deserialize(reinterpret_cast<const uint8_t *>(contents.c_str()), if (!parser.Deserialize(reinterpret_cast<const uint8_t *>(contents.c_str()),
contents.size())) { contents.size())) {
Error("failed to load binary schema: " + filename, false, false); Error("failed to load binary schema: " + filename, false, false);
} }
} }
@@ -402,7 +402,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
"\" matches the schema, use --raw-binary to read this file" "\" matches the schema, use --raw-binary to read this file"
" anyway."); " anyway.");
} else if (!flatbuffers::BufferHasIdentifier( } else if (!flatbuffers::BufferHasIdentifier(
contents.c_str(), parser->file_identifier_.c_str(), opts.size_prefixed)) { contents.c_str(), parser->file_identifier_.c_str(),
opts.size_prefixed)) {
Error("binary \"" + filename + Error("binary \"" + filename +
"\" does not have expected file_identifier \"" + "\" does not have expected file_identifier \"" +
parser->file_identifier_ + parser->file_identifier_ +

View File

@@ -61,13 +61,15 @@ int main(int argc, const char *argv[]) {
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateJSTS, "-s", "--js", "JavaScript", true, nullptr, { flatbuffers::GenerateJSTS, "-s", "--js", "JavaScript", true, nullptr,
flatbuffers::IDLOptions::kJs, flatbuffers::IDLOptions::kJs,
"Generate JavaScript code for tables/structs", flatbuffers::JSTSMakeRule }, "Generate JavaScript code for tables/structs",
flatbuffers::JSTSMakeRule },
{ flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr, { flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr,
flatbuffers::IDLOptions::kDart, flatbuffers::IDLOptions::kDart,
"Generate Dart classes for tables/structs", flatbuffers::DartMakeRule }, "Generate Dart classes for tables/structs", flatbuffers::DartMakeRule },
{ flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr, { flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr,
flatbuffers::IDLOptions::kTs, flatbuffers::IDLOptions::kTs,
"Generate TypeScript code for tables/structs", flatbuffers::JSTSMakeRule }, "Generate TypeScript code for tables/structs",
flatbuffers::JSTSMakeRule },
{ flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", true, nullptr, { flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", true, nullptr,
flatbuffers::IDLOptions::kCSharp, flatbuffers::IDLOptions::kCSharp,
"Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule }, "Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule },
@@ -75,23 +77,22 @@ int main(int argc, const char *argv[]) {
flatbuffers::IDLOptions::kPython, flatbuffers::IDLOptions::kPython,
"Generate Python files for tables/structs", "Generate Python files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true, nullptr, { flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true,
flatbuffers::IDLOptions::kLobster, nullptr, flatbuffers::IDLOptions::kLobster,
"Generate Lobster files for tables/structs", "Generate Lobster files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr, { flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr,
flatbuffers::IDLOptions::kLua, flatbuffers::IDLOptions::kLua, "Generate Lua files for tables/structs",
"Generate Lua files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr, { flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr,
flatbuffers::IDLOptions::kRust, flatbuffers::IDLOptions::kRust, "Generate Rust files for tables/structs",
"Generate Rust files for tables/structs",
flatbuffers::RustMakeRule }, flatbuffers::RustMakeRule },
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr, { flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr,
flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs", flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr, { flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr,
flatbuffers::IDLOptions::kKotlin, "Generate Kotlin classes for tables/structs", flatbuffers::IDLOptions::kKotlin,
"Generate Kotlin classes for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema", { flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema",
true, nullptr, flatbuffers::IDLOptions::kJsonSchema, true, nullptr, flatbuffers::IDLOptions::kJsonSchema,

View File

@@ -15,9 +15,11 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include "flatbuffers/hash.h" #include "flatbuffers/hash.h"
enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x }; enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x };
@@ -35,7 +37,7 @@ int main(int argc, char *argv[]) {
} }
printf(" 32 bit:\n"); printf(" 32 bit:\n");
size = sizeof(flatbuffers::kHashFunctions32) / size = sizeof(flatbuffers::kHashFunctions32) /
sizeof(flatbuffers::kHashFunctions32[0]); sizeof(flatbuffers::kHashFunctions32[0]);
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
printf(" * %s\n", flatbuffers::kHashFunctions32[i].name); printf(" * %s\n", flatbuffers::kHashFunctions32[i].name);
} }

View File

@@ -16,13 +16,13 @@
// independent from idl_parser, since this code is not needed for most clients // independent from idl_parser, since this code is not needed for most clients
#include <unordered_set>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include <unordered_set>
namespace flatbuffers { namespace flatbuffers {
// Pedantic warning free version of toupper(). // Pedantic warning free version of toupper().
@@ -208,9 +208,7 @@ class CppGenerator : public BaseGenerator {
for (std::size_t i = 0; i < parser_.opts.cpp_includes.size(); ++i) { for (std::size_t i = 0; i < parser_.opts.cpp_includes.size(); ++i) {
code_ += "#include \"" + parser_.opts.cpp_includes[i] + "\""; code_ += "#include \"" + parser_.opts.cpp_includes[i] + "\"";
} }
if (!parser_.opts.cpp_includes.empty()) { if (!parser_.opts.cpp_includes.empty()) { code_ += ""; }
code_ += "";
}
} }
std::string EscapeKeyword(const std::string &name) const { std::string EscapeKeyword(const std::string &name) const {
@@ -577,7 +575,9 @@ class CppGenerator : public BaseGenerator {
} }
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
// fall through // fall through
default: { return "void"; } default: {
return "void";
}
} }
} }
@@ -696,7 +696,9 @@ class CppGenerator : public BaseGenerator {
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
return type.enum_def->name + "Union"; return type.enum_def->name + "Union";
} }
default: { return GenTypeBasic(type, true); } default: {
return GenTypeBasic(type, true);
}
} }
} }
@@ -1163,7 +1165,8 @@ class CppGenerator : public BaseGenerator {
code_ += " void Set(T&& val) {"; code_ += " void Set(T&& val) {";
code_ += " using RT = typename std::remove_reference<T>::type;"; code_ += " using RT = typename std::remove_reference<T>::type;";
code_ += " Reset();"; code_ += " Reset();";
code_ += " type = {{NAME}}Traits<typename RT::TableType>::enum_value;"; code_ +=
" type = {{NAME}}Traits<typename RT::TableType>::enum_value;";
code_ += " if (type != {{NONE}}) {"; code_ += " if (type != {{NONE}}) {";
code_ += " value = new RT(std::forward<T>(val));"; code_ += " value = new RT(std::forward<T>(val));";
code_ += " }"; code_ += " }";
@@ -1276,7 +1279,8 @@ class CppGenerator : public BaseGenerator {
" auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);"; " auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);";
if (ev.union_type.base_type == BASE_TYPE_STRUCT) { if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
if (ev.union_type.struct_def->fixed) { if (ev.union_type.struct_def->fixed) {
code_ += " return verifier.Verify<{{TYPE}}>(static_cast<const " code_ +=
" return verifier.Verify<{{TYPE}}>(static_cast<const "
"uint8_t *>(obj), 0);"; "uint8_t *>(obj), 0);";
} else { } else {
code_ += getptr; code_ += getptr;
@@ -1295,7 +1299,7 @@ class CppGenerator : public BaseGenerator {
code_ += " }"; code_ += " }";
} }
} }
code_ += " default: return true;"; // unknown values are OK. code_ += " default: return true;"; // unknown values are OK.
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
@@ -1763,7 +1767,9 @@ class CppGenerator : public BaseGenerator {
} }
break; break;
} }
default: { break; } default: {
break;
}
} }
} }
@@ -1925,7 +1931,8 @@ class CppGenerator : public BaseGenerator {
} }
} }
if (parser_.opts.mutable_buffer && !(is_scalar && IsUnion(field.value.type))) { if (parser_.opts.mutable_buffer &&
!(is_scalar && IsUnion(field.value.type))) {
if (is_scalar) { if (is_scalar) {
const auto type = GenTypeWire(field.value.type, "", false); const auto type = GenTypeWire(field.value.type, "", false);
code_.SetValue("SET_FN", "SetField<" + type + ">"); code_.SetValue("SET_FN", "SetField<" + type + ">");
@@ -2901,8 +2908,8 @@ class CppGenerator : public BaseGenerator {
} else if (IsArray(field.value.type)) { } else if (IsArray(field.value.type)) {
auto underlying = GenTypeGet(field.value.type, "", "", "", false); auto underlying = GenTypeGet(field.value.type, "", "", "", false);
code_ += " flatbuffers::Array<" + mut_field_type + ", " + code_ += " flatbuffers::Array<" + mut_field_type + ", " +
NumToString(field.value.type.fixed_length) + NumToString(field.value.type.fixed_length) + "> *" +
"> *" + "mutable_{{FIELD_NAME}}() {"; "mutable_{{FIELD_NAME}}() {";
code_ += " return reinterpret_cast<flatbuffers::Array<" + code_ += " return reinterpret_cast<flatbuffers::Array<" +
mut_field_type + ", " + mut_field_type + ", " +
NumToString(field.value.type.fixed_length) + NumToString(field.value.type.fixed_length) +

View File

@@ -71,9 +71,7 @@ class DartGenerator : public BaseGenerator {
"// ignore_for_file: unused_import, unused_field, " "// ignore_for_file: unused_import, unused_field, "
"unused_local_variable\n\n"; "unused_local_variable\n\n";
if (!kv->first.empty()) { if (!kv->first.empty()) { code += "library " + kv->first + ";\n\n"; }
code += "library " + kv->first + ";\n\n";
}
code += "import 'dart:typed_data' show Uint8List;\n"; code += "import 'dart:typed_data' show Uint8List;\n";
code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb + code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb +
@@ -87,16 +85,20 @@ class DartGenerator : public BaseGenerator {
++kv2) { ++kv2) {
if (kv2->first != kv->first) { if (kv2->first != kv->first) {
code += "import '" + code += "import '" +
GeneratedFileName("./", file_name_ + (!kv2->first.empty() ? "_" + kv2->first : "")) + GeneratedFileName(
"./", file_name_ +
(!kv2->first.empty() ? "_" + kv2->first : "")) +
"' as " + ImportAliasName(kv2->first) + ";\n"; "' as " + ImportAliasName(kv2->first) + ";\n";
} }
} }
code += "\n"; code += "\n";
code += kv->second; code += kv->second;
if (!SaveFile( if (!SaveFile(GeneratedFileName(
GeneratedFileName(path_, file_name_ + (!kv->first.empty() ? "_" + kv->first : "")).c_str(), path_, file_name_ +
code, false)) { (!kv->first.empty() ? "_" + kv->first : ""))
.c_str(),
code, false)) {
return false; return false;
} }
} }
@@ -117,9 +119,7 @@ class DartGenerator : public BaseGenerator {
} }
static std::string BuildNamespaceName(const Namespace &ns) { static std::string BuildNamespaceName(const Namespace &ns) {
if (ns.components.empty()) { if (ns.components.empty()) { return ""; }
return "";
}
std::stringstream sstream; std::stringstream sstream;
std::copy(ns.components.begin(), ns.components.end() - 1, std::copy(ns.components.begin(), ns.components.end() - 1,
std::ostream_iterator<std::string>(sstream, ".")); std::ostream_iterator<std::string>(sstream, "."));
@@ -139,7 +139,8 @@ class DartGenerator : public BaseGenerator {
return ret; return ret;
} }
void GenIncludeDependencies(std::string* code, const std::string& the_namespace) { void GenIncludeDependencies(std::string *code,
const std::string &the_namespace) {
for (auto it = parser_.included_files_.begin(); for (auto it = parser_.included_files_.begin();
it != parser_.included_files_.end(); ++it) { it != parser_.included_files_.end(); ++it) {
if (it->second.empty()) continue; if (it->second.empty()) continue;
@@ -147,7 +148,11 @@ class DartGenerator : public BaseGenerator {
auto noext = flatbuffers::StripExtension(it->second); auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext); auto basename = flatbuffers::StripPath(noext);
*code += "import '" + GeneratedFileName("", basename + (the_namespace == "" ? "" : "_" + the_namespace)) + "';\n"; *code +=
"import '" +
GeneratedFileName(
"", basename + (the_namespace == "" ? "" : "_" + the_namespace)) +
"';\n";
} }
} }
@@ -798,7 +803,8 @@ class DartGenerator : public BaseGenerator {
} }
code += "\n : null;\n"; code += "\n : null;\n";
} else if (field.value.type.base_type == BASE_TYPE_STRING) { } else if (field.value.type.base_type == BASE_TYPE_STRING) {
code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) + ");\n"; code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) +
");\n";
} else { } else {
code += " = _" + MakeCamel(field.name, false) + code += " = _" + MakeCamel(field.name, false) +
"?.getOrCreateOffset(fbBuilder);\n"; "?.getOrCreateOffset(fbBuilder);\n";

View File

@@ -69,75 +69,71 @@ const LanguageParameters &GetLangParams(IDLOptions::Language lang) {
"Double.", "Float.", "NaN", "POSITIVE_INFINITY", "NEGATIVE_INFINITY"); "Double.", "Float.", "NaN", "POSITIVE_INFINITY", "NEGATIVE_INFINITY");
static const LanguageParameters language_parameters[] = { static const LanguageParameters language_parameters[] = {
{ { IDLOptions::kJava,
IDLOptions::kJava, false,
false, ".java",
".java", "String",
"String", "boolean ",
"boolean ", " {\n",
" {\n", "class ",
"class ", " final ",
" final ", "final ",
"final ", "final class ",
"final class ", ";\n",
";\n", "()",
"()", "",
"", " extends ",
" extends ", "package ",
"package ", ";",
";", "",
"", "_bb.order(ByteOrder.LITTLE_ENDIAN); ",
"_bb.order(ByteOrder.LITTLE_ENDIAN); ", "position()",
"position()", "offset()",
"offset()", "",
"", "",
"", "",
"", "import java.nio.*;\nimport java.lang.*;\nimport "
"import java.nio.*;\nimport java.lang.*;\nimport " "java.util.*;\nimport com.google.flatbuffers.*;\n",
"java.util.*;\nimport com.google.flatbuffers.*;\n", "\n@SuppressWarnings(\"unused\")\n",
"\n@SuppressWarnings(\"unused\")\n", "\n@javax.annotation.Generated(value=\"flatc\")\n",
"\n@javax.annotation.Generated(value=\"flatc\")\n", {
{ "/**",
"/**", " *",
" *", " */",
" */", },
}, &JavaFloatGen },
&JavaFloatGen { IDLOptions::kCSharp,
}, true,
{ ".cs",
IDLOptions::kCSharp, "string",
true, "bool ",
".cs", "\n{\n",
"string", "struct ",
"bool ", " readonly ",
"\n{\n", "",
"struct ", "enum ",
" readonly ", ",\n",
"", " { get",
"enum ", "} ",
",\n", " : ",
" { get", "namespace ",
"} ", "\n{",
" : ", "\n}\n",
"namespace ", "",
"\n{", "Position",
"\n}\n", "Offset",
"", "__p.",
"Position", "Table.",
"Offset", "?",
"__p.", "using global::System;\nusing global::FlatBuffers;\n\n",
"Table.", "",
"?", "",
"using global::System;\nusing global::FlatBuffers;\n\n", {
"", nullptr,
"", "///",
{ nullptr,
nullptr, },
"///", &CSharpFloatGen },
nullptr,
},
&CSharpFloatGen
},
}; };
if (lang == IDLOptions::kJava) { if (lang == IDLOptions::kJava) {
@@ -233,9 +229,7 @@ class GeneralGenerator : public BaseGenerator {
} }
code += lang_.class_annotation; code += lang_.class_annotation;
} }
if (parser_.opts.gen_generated) { if (parser_.opts.gen_generated) { code += lang_.generated_type_annotation; }
code += lang_.generated_type_annotation;
}
code += classcode; code += classcode;
if (!namespace_name.empty()) code += lang_.namespace_end; if (!namespace_name.empty()) code += lang_.namespace_end;
auto filename = NamespaceDir(ns) + defname + lang_.file_extension; auto filename = NamespaceDir(ns) + defname + lang_.file_extension;
@@ -339,7 +333,7 @@ class GeneralGenerator : public BaseGenerator {
case BASE_TYPE_ARRAY: case BASE_TYPE_ARRAY:
case BASE_TYPE_VECTOR: case BASE_TYPE_VECTOR:
if (vectorelem) return DestinationType(type.VectorType(), vectorelem); if (vectorelem) return DestinationType(type.VectorType(), vectorelem);
FLATBUFFERS_FALLTHROUGH(); // else fall thru FLATBUFFERS_FALLTHROUGH(); // else fall thru
default: return type; default: return type;
} }
} }
@@ -383,7 +377,7 @@ class GeneralGenerator : public BaseGenerator {
case BASE_TYPE_UINT: return " & 0xFFFFFFFFL"; case BASE_TYPE_UINT: return " & 0xFFFFFFFFL";
case BASE_TYPE_VECTOR: case BASE_TYPE_VECTOR:
if (vectorelem) return DestinationMask(type.VectorType(), vectorelem); if (vectorelem) return DestinationMask(type.VectorType(), vectorelem);
FLATBUFFERS_FALLTHROUGH(); // else fall thru FLATBUFFERS_FALLTHROUGH(); // else fall thru
default: return ""; default: return "";
} }
} }
@@ -440,7 +434,9 @@ class GeneralGenerator : public BaseGenerator {
return ""; return "";
} }
std::string SourceCast(const Type &type) const { return SourceCast(type, true); } std::string SourceCast(const Type &type) const {
return SourceCast(type, true);
}
std::string SourceCastBasic(const Type &type, bool castFromDest) const { std::string SourceCastBasic(const Type &type, bool castFromDest) const {
return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : ""; return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : "";
@@ -459,8 +455,9 @@ class GeneralGenerator : public BaseGenerator {
: value.constant; : value.constant;
} }
std::string GenDefaultValue(const FieldDef &field, bool enableLangOverrides) const { std::string GenDefaultValue(const FieldDef &field,
auto& value = field.value; bool enableLangOverrides) const {
auto &value = field.value;
if (enableLangOverrides) { if (enableLangOverrides) {
// handles both enum case and vector of enum case // handles both enum case and vector of enum case
if (lang_.language == IDLOptions::kCSharp && if (lang_.language == IDLOptions::kCSharp &&
@@ -482,7 +479,7 @@ class GeneralGenerator : public BaseGenerator {
case BASE_TYPE_UINT: case BASE_TYPE_UINT:
case BASE_TYPE_LONG: return value.constant + longSuffix; case BASE_TYPE_LONG: return value.constant + longSuffix;
default: default:
if(IsFloat(value.type.base_type)) if (IsFloat(value.type.base_type))
return lang_.float_gen->GenFloatConstant(field); return lang_.float_gen->GenFloatConstant(field);
else else
return value.constant; return value.constant;
@@ -495,7 +492,7 @@ class GeneralGenerator : public BaseGenerator {
std::string GenDefaultValueBasic(const FieldDef &field, std::string GenDefaultValueBasic(const FieldDef &field,
bool enableLangOverrides) const { bool enableLangOverrides) const {
auto& value = field.value; auto &value = field.value;
if (!IsScalar(value.type.base_type)) { if (!IsScalar(value.type.base_type)) {
if (enableLangOverrides) { if (enableLangOverrides) {
if (lang_.language == IDLOptions::kCSharp) { if (lang_.language == IDLOptions::kCSharp) {
@@ -530,15 +527,14 @@ class GeneralGenerator : public BaseGenerator {
GenComment(enum_def.doc_comment, code_ptr, &lang_.comment_config); GenComment(enum_def.doc_comment, code_ptr, &lang_.comment_config);
// In C# this indicates enumeration values can be treated as bit flags. // In C# this indicates enumeration values can be treated as bit flags.
if (lang_.language == IDLOptions::kCSharp && enum_def.attributes.Lookup("bit_flags")) { if (lang_.language == IDLOptions::kCSharp &&
enum_def.attributes.Lookup("bit_flags")) {
code += "[System.FlagsAttribute]\n"; code += "[System.FlagsAttribute]\n";
} }
if (enum_def.attributes.Lookup("private")) { if (enum_def.attributes.Lookup("private")) {
// For Java, we leave the enum unmarked to indicate package-private // For Java, we leave the enum unmarked to indicate package-private
// For C# we mark the enum as internal // For C# we mark the enum as internal
if (lang_.language == IDLOptions::kCSharp) { if (lang_.language == IDLOptions::kCSharp) { code += "internal "; }
code += "internal ";
}
} else { } else {
code += "public "; code += "public ";
} }
@@ -870,9 +866,7 @@ class GeneralGenerator : public BaseGenerator {
if (struct_def.attributes.Lookup("private")) { if (struct_def.attributes.Lookup("private")) {
// For Java, we leave the struct unmarked to indicate package-private // For Java, we leave the struct unmarked to indicate package-private
// For C# we mark the struct as internal // For C# we mark the struct as internal
if (lang_.language == IDLOptions::kCSharp) { if (lang_.language == IDLOptions::kCSharp) { code += "internal "; }
code += "internal ";
}
} else { } else {
code += "public "; code += "public ";
} }
@@ -1016,8 +1010,8 @@ class GeneralGenerator : public BaseGenerator {
code += "(new " + type_name + "(), j); }\n"; code += "(new " + type_name + "(), j); }\n";
} }
} else if (field.value.type.base_type == BASE_TYPE_UNION || } else if (field.value.type.base_type == BASE_TYPE_UNION ||
(field.value.type.base_type == BASE_TYPE_VECTOR && (field.value.type.base_type == BASE_TYPE_VECTOR &&
field.value.type.VectorType().base_type == BASE_TYPE_UNION)) { field.value.type.VectorType().base_type == BASE_TYPE_UNION)) {
if (lang_.language == IDLOptions::kCSharp) { if (lang_.language == IDLOptions::kCSharp) {
// Union types in C# use generic Table-derived type for better type // Union types in C# use generic Table-derived type for better type
// safety. // safety.
@@ -1092,8 +1086,8 @@ class GeneralGenerator : public BaseGenerator {
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_UNION && if (vectortype.base_type == BASE_TYPE_UNION &&
lang_.language == IDLOptions::kCSharp) { lang_.language == IDLOptions::kCSharp) {
conditional_cast = "(TTable?)"; conditional_cast = "(TTable?)";
getter += "<TTable>"; getter += "<TTable>";
} }
code += "("; code += "(";
if (vectortype.base_type == BASE_TYPE_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -1145,7 +1139,8 @@ class GeneralGenerator : public BaseGenerator {
if (lang_.language == IDLOptions::kCSharp) { if (lang_.language == IDLOptions::kCSharp) {
code += "() where TTable : struct, IFlatbufferObject"; code += "() where TTable : struct, IFlatbufferObject";
code += offset_prefix + "(TTable?)" + getter; code += offset_prefix + "(TTable?)" + getter;
code += "<TTable>(o + " + lang_.accessor_prefix + "bb_pos) : null"; code +=
"<TTable>(o + " + lang_.accessor_prefix + "bb_pos) : null";
} else { } else {
code += "(" + type_name + " obj)" + offset_prefix + getter; code += "(" + type_name + " obj)" + offset_prefix + getter;
code += "(obj, o + " + lang_.accessor_prefix + "bb_pos) : null"; code += "(obj, o + " + lang_.accessor_prefix + "bb_pos) : null";
@@ -1174,19 +1169,21 @@ class GeneralGenerator : public BaseGenerator {
auto &key_field = **kit; auto &key_field = **kit;
if (key_field.key) { if (key_field.key) {
auto qualified_name = WrapInNameSpace(sd); auto qualified_name = WrapInNameSpace(sd);
code += " public " + qualified_name + lang_.optional_suffix + " "; code +=
" public " + qualified_name + lang_.optional_suffix + " ";
code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey("; code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey(";
code += GenTypeNameDest(key_field.value.type) + " key)"; code += GenTypeNameDest(key_field.value.type) + " key)";
code += offset_prefix; code += offset_prefix;
code += qualified_name + ".__lookup_by_key("; code += qualified_name + ".__lookup_by_key(";
if (lang_.language == IDLOptions::kJava) if (lang_.language == IDLOptions::kJava) code += "null, ";
code += "null, ";
code += lang_.accessor_prefix + "__vector(o), key, "; code += lang_.accessor_prefix + "__vector(o), key, ";
code += lang_.accessor_prefix + "bb) : null; "; code += lang_.accessor_prefix + "bb) : null; ";
code += "}\n"; code += "}\n";
if (lang_.language == IDLOptions::kJava) { if (lang_.language == IDLOptions::kJava) {
code += " public " + qualified_name + lang_.optional_suffix + " "; code +=
code += MakeCamel(field.name, lang_.first_camel_upper) + "ByKey("; " public " + qualified_name + lang_.optional_suffix + " ";
code +=
MakeCamel(field.name, lang_.first_camel_upper) + "ByKey(";
code += qualified_name + lang_.optional_suffix + " obj, "; code += qualified_name + lang_.optional_suffix + " obj, ";
code += GenTypeNameDest(key_field.value.type) + " key)"; code += GenTypeNameDest(key_field.value.type) + " key)";
code += offset_prefix; code += offset_prefix;
@@ -1259,12 +1256,15 @@ class GeneralGenerator : public BaseGenerator {
break; break;
case IDLOptions::kCSharp: case IDLOptions::kCSharp:
code += "#if ENABLE_SPAN_T\n"; code += "#if ENABLE_SPAN_T\n";
code += " public Span<" + GenTypeBasic(field.value.type.VectorType()) + "> Get"; code += " public Span<" +
GenTypeBasic(field.value.type.VectorType()) + "> Get";
code += MakeCamel(field.name, lang_.first_camel_upper); code += MakeCamel(field.name, lang_.first_camel_upper);
code += "Bytes() { return "; code += "Bytes() { return ";
code += lang_.accessor_prefix + "__vector_as_span<"+ GenTypeBasic(field.value.type.VectorType()) +">("; code += lang_.accessor_prefix + "__vector_as_span<" +
GenTypeBasic(field.value.type.VectorType()) + ">(";
code += NumToString(field.value.offset); code += NumToString(field.value.offset);
code += ", " + NumToString(SizeOf(field.value.type.VectorType().base_type)); code += ", " + NumToString(
SizeOf(field.value.type.VectorType().base_type));
code += "); }\n"; code += "); }\n";
code += "#else\n"; code += "#else\n";
code += " public ArraySegment<byte>? Get"; code += " public ArraySegment<byte>? Get";
@@ -1596,10 +1596,10 @@ class GeneralGenerator : public BaseGenerator {
std::string size_prefix[] = { "", "SizePrefixed" }; std::string size_prefix[] = { "", "SizePrefixed" };
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 2; ++i) {
code += " public static void "; code += " public static void ";
code += FunctionStart('F') + "inish" + size_prefix[i] + code +=
struct_def.name; FunctionStart('F') + "inish" + size_prefix[i] + struct_def.name;
code += "Buffer(FlatBufferBuilder builder, " + code +=
GenOffsetType(struct_def); "Buffer(FlatBufferBuilder builder, " + GenOffsetType(struct_def);
code += " offset) {"; code += " offset) {";
code += " builder." + FunctionStart('F') + "inish" + size_prefix[i] + code += " builder." + FunctionStart('F') + "inish" + size_prefix[i] +
"(offset"; "(offset";
@@ -1636,7 +1636,7 @@ class GeneralGenerator : public BaseGenerator {
code += "\n public static " + struct_def.name + lang_.optional_suffix; code += "\n public static " + struct_def.name + lang_.optional_suffix;
code += " __lookup_by_key("; code += " __lookup_by_key(";
if (lang_.language == IDLOptions::kJava) if (lang_.language == IDLOptions::kJava)
code += struct_def.name + " obj, "; code += struct_def.name + " obj, ";
code += "int vectorLocation, "; code += "int vectorLocation, ";
code += GenTypeNameDest(key_field->value.type); code += GenTypeNameDest(key_field->value.type);
code += " key, ByteBuffer bb) {\n"; code += " key, ByteBuffer bb) {\n";
@@ -1684,8 +1684,7 @@ class GeneralGenerator : public BaseGenerator {
// Generate a vector of structs accessor class. // Generate a vector of structs accessor class.
code += "\n"; code += "\n";
code += " "; code += " ";
if (!struct_def.attributes.Lookup("private")) if (!struct_def.attributes.Lookup("private")) code += "public ";
code += "public ";
code += "static "; code += "static ";
code += lang_.unsubclassable_decl; code += lang_.unsubclassable_decl;
code += lang_.accessor_type + "Vector" + lang_.inheritance_marker; code += lang_.accessor_type + "Vector" + lang_.inheritance_marker;

View File

@@ -43,7 +43,7 @@ static std::string GeneratedFileName(const std::string &path,
namespace go { namespace go {
// see https://golang.org/ref/spec#Keywords // see https://golang.org/ref/spec#Keywords
static const char * const g_golang_keywords[] = { static const char *const g_golang_keywords[] = {
"break", "default", "func", "interface", "select", "case", "defer", "break", "default", "func", "interface", "select", "case", "defer",
"go", "map", "struct", "chan", "else", "goto", "package", "go", "map", "struct", "chan", "else", "goto", "package",
"switch", "const", "fallthrough", "if", "range", "type", "continue", "switch", "const", "fallthrough", "if", "range", "type", "continue",
@@ -151,7 +151,8 @@ class GoGenerator : public BaseGenerator {
// Construct the name of the type for this enum. // Construct the name of the type for this enum.
std::string GetEnumTypeName(const EnumDef &enum_def) { std::string GetEnumTypeName(const EnumDef &enum_def) {
return WrapInNameSpaceAndTrack(enum_def.defined_namespace, GoIdentity(enum_def.name)); return WrapInNameSpaceAndTrack(enum_def.defined_namespace,
GoIdentity(enum_def.name));
} }
// Create a type for the enum values. // Create a type for the enum values.
@@ -222,7 +223,7 @@ class GoGenerator : public BaseGenerator {
code += "\tif s, ok := EnumNames" + enum_def.name + "[v]; ok {\n"; code += "\tif s, ok := EnumNames" + enum_def.name + "[v]; ok {\n";
code += "\t\treturn s\n"; code += "\t\treturn s\n";
code += "\t}\n"; code += "\t}\n";
code += "\treturn \""+ enum_def.name; code += "\treturn \"" + enum_def.name;
code += "(\" + strconv.FormatInt(int64(v), 10) + \")\"\n"; code += "(\" + strconv.FormatInt(int64(v), 10) + \")\"\n";
code += "}\n\n"; code += "}\n\n";
} }
@@ -325,23 +326,21 @@ class GoGenerator : public BaseGenerator {
// Get the value of a struct's scalar. // Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def, void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name); code += " " + MakeCamel(field.name);
code += "() " + TypeName(field) + " {\n"; code += "() " + TypeName(field) + " {\n";
code += "\treturn " + CastToEnum( code += "\treturn " +
field.value.type, CastToEnum(field.value.type,
getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" + getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" +
NumToString(field.value.offset) + "))"); NumToString(field.value.offset) + "))");
code += "\n}\n"; code += "\n}\n";
} }
// Get the value of a table's scalar. // Get the value of a table's scalar.
void GetScalarFieldOfTable(const StructDef &struct_def, void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
@@ -358,8 +357,7 @@ class GoGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Struct. // Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def, void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name); code += " " + MakeCamel(field.name);
@@ -377,8 +375,7 @@ class GoGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Table. // Specific to Table.
void GetStructFieldOfTable(const StructDef &struct_def, void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -400,8 +397,7 @@ class GoGenerator : public BaseGenerator {
} }
// Get the value of a string. // Get the value of a string.
void GetStringField(const StructDef &struct_def, void GetStringField(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -428,8 +424,7 @@ class GoGenerator : public BaseGenerator {
// Get the value of a vector's struct member. // Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def, void GetMemberOfVectorOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
@@ -461,10 +456,11 @@ class GoGenerator : public BaseGenerator {
code += "(j int) " + TypeName(field) + " "; code += "(j int) " + TypeName(field) + " ";
code += OffsetPrefix(field); code += OffsetPrefix(field);
code += "\t\ta := rcv._tab.Vector(o)\n"; code += "\t\ta := rcv._tab.Vector(o)\n";
code += "\t\treturn " + CastToEnum( code += "\t\treturn " +
field.value.type, CastToEnum(field.value.type,
GenGetter(field.value.type) + "(a + flatbuffers.UOffsetT(j*" + GenGetter(field.value.type) +
NumToString(InlineSize(vectortype)) + "))"); "(a + flatbuffers.UOffsetT(j*" +
NumToString(InlineSize(vectortype)) + "))");
code += "\n\t}\n"; code += "\n\t}\n";
if (vectortype.base_type == BASE_TYPE_STRING) { if (vectortype.base_type == BASE_TYPE_STRING) {
code += "\treturn nil\n"; code += "\treturn nil\n";
@@ -518,8 +514,8 @@ class GoGenerator : public BaseGenerator {
// Recursively generate struct construction statements and instert manual // Recursively generate struct construction statements and instert manual
// padding. // padding.
void StructBuilderBody(const StructDef &struct_def, void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", "; code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", ";
code += NumToString(struct_def.bytesize) + ")\n"; code += NumToString(struct_def.bytesize) + ")\n";
@@ -533,7 +529,9 @@ class GoGenerator : public BaseGenerator {
(nameprefix + (field.name + "_")).c_str(), code_ptr); (nameprefix + (field.name + "_")).c_str(), code_ptr);
} else { } else {
code += "\tbuilder.Prepend" + GenMethod(field) + "("; code += "\tbuilder.Prepend" + GenMethod(field) + "(";
code += CastToBaseType(field.value.type, nameprefix + GoIdentity(field.name)) + ")\n"; code += CastToBaseType(field.value.type,
nameprefix + GoIdentity(field.name)) +
")\n";
} }
} }
} }
@@ -582,8 +580,8 @@ class GoGenerator : public BaseGenerator {
} }
// Set the value of one of the members of a table's vector. // Set the value of one of the members of a table's vector.
void BuildVectorOfTable(const StructDef &struct_def, void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "func " + struct_def.name + "Start"; code += "func " + struct_def.name + "Start";
code += MakeCamel(field.name); code += MakeCamel(field.name);
@@ -612,8 +610,8 @@ class GoGenerator : public BaseGenerator {
} }
// Generate a struct field getter, conditioned on its child type(s). // Generate a struct field getter, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, nullptr, ""); GenComment(field.doc_comment, code_ptr, nullptr, "");
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -630,7 +628,9 @@ class GoGenerator : public BaseGenerator {
GetStructFieldOfTable(struct_def, field, code_ptr); GetStructFieldOfTable(struct_def, field, code_ptr);
} }
break; break;
case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break; case BASE_TYPE_STRING:
GetStringField(struct_def, field, code_ptr);
break;
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -652,10 +652,9 @@ class GoGenerator : public BaseGenerator {
} }
} }
// Mutate the value of a struct's scalar. // Mutate the value of a struct's scalar.
void MutateScalarFieldOfStruct(const StructDef &struct_def, void MutateScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string type = MakeCamel(GenTypeBasic(field.value.type)); std::string type = MakeCamel(GenTypeBasic(field.value.type));
std::string setter = "rcv._tab.Mutate" + type; std::string setter = "rcv._tab.Mutate" + type;
@@ -669,8 +668,7 @@ class GoGenerator : public BaseGenerator {
// Mutate the value of a table's scalar. // Mutate the value of a table's scalar.
void MutateScalarFieldOfTable(const StructDef &struct_def, void MutateScalarFieldOfTable(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string type = MakeCamel(GenTypeBasic(field.value.type)); std::string type = MakeCamel(GenTypeBasic(field.value.type));
std::string setter = "rcv._tab.Mutate" + type + "Slot"; std::string setter = "rcv._tab.Mutate" + type + "Slot";
@@ -916,9 +914,9 @@ class GoGenerator : public BaseGenerator {
if (IsScalar(field.value.type.element)) { if (IsScalar(field.value.type.element)) {
code += "\t\t\tbuilder.Prepend" + code += "\t\t\tbuilder.Prepend" +
MakeCamel(GenTypeBasic(field.value.type.VectorType())) + "(" + MakeCamel(GenTypeBasic(field.value.type.VectorType())) + "(" +
CastToBaseType( CastToBaseType(field.value.type.VectorType(),
field.value.type.VectorType(), "t." + MakeCamel(field.name) + "[j]") +
"t." + MakeCamel(field.name) + "[j]") + ")\n"; ")\n";
} else if (field.value.type.element == BASE_TYPE_STRUCT && } else if (field.value.type.element == BASE_TYPE_STRUCT &&
field.value.type.struct_def->fixed) { field.value.type.struct_def->fixed) {
code += "\t\t\t" + code += "\t\t\t" +
@@ -979,8 +977,8 @@ class GoGenerator : public BaseGenerator {
code += "}\n\n"; code += "}\n\n";
} }
void GenNativeTableUnPack( void GenNativeTableUnPack(const StructDef &struct_def,
const StructDef &struct_def, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" + code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" +
@@ -995,8 +993,8 @@ class GoGenerator : public BaseGenerator {
if (field.value.type.enum_def != nullptr && if (field.value.type.enum_def != nullptr &&
field.value.type.enum_def->is_union) field.value.type.enum_def->is_union)
continue; continue;
code += "\tt." + field_name_camel + " = rcv." + field_name_camel + code +=
"()\n"; "\tt." + field_name_camel + " = rcv." + field_name_camel + "()\n";
} else if (field.value.type.base_type == BASE_TYPE_STRING) { } else if (field.value.type.base_type == BASE_TYPE_STRING) {
code += "\tt." + field_name_camel + " = string(rcv." + code += "\tt." + field_name_camel + " = string(rcv." +
field_name_camel + "())\n"; field_name_camel + "())\n";
@@ -1084,8 +1082,8 @@ class GoGenerator : public BaseGenerator {
} }
} }
void GenNativeStructUnPack( void GenNativeStructUnPack(const StructDef &struct_def,
const StructDef &struct_def, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" + code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" +
@@ -1137,8 +1135,7 @@ class GoGenerator : public BaseGenerator {
EndEnumNames(code_ptr); EndEnumNames(code_ptr);
BeginEnumValues(enum_def, code_ptr); BeginEnumValues(enum_def, code_ptr);
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
++it) {
auto &ev = **it; auto &ev = **it;
EnumValueMember(enum_def, ev, max_name_length, code_ptr); EnumValueMember(enum_def, ev, max_name_length, code_ptr);
} }
@@ -1189,9 +1186,7 @@ class GoGenerator : public BaseGenerator {
} }
std::string GenTypeGet(const Type &type) { std::string GenTypeGet(const Type &type) {
if (type.enum_def != nullptr) { if (type.enum_def != nullptr) { return GetEnumTypeName(*type.enum_def); }
return GetEnumTypeName(*type.enum_def);
}
return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type); return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
} }
@@ -1221,7 +1216,8 @@ class GoGenerator : public BaseGenerator {
std::string GenConstant(const FieldDef &field) { std::string GenConstant(const FieldDef &field) {
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
case BASE_TYPE_BOOL: return field.value.constant == "0" ? "false" : "true"; case BASE_TYPE_BOOL:
return field.value.constant == "0" ? "false" : "true";
default: return field.value.constant; default: return field.value.constant;
} }
} }
@@ -1248,11 +1244,11 @@ class GoGenerator : public BaseGenerator {
} else if (type.base_type == BASE_TYPE_VECTOR) { } else if (type.base_type == BASE_TYPE_VECTOR) {
return "[]" + NativeType(type.VectorType()); return "[]" + NativeType(type.VectorType());
} else if (type.base_type == BASE_TYPE_STRUCT) { } else if (type.base_type == BASE_TYPE_STRUCT) {
return "*" + WrapInNameSpaceAndTrack( return "*" + WrapInNameSpaceAndTrack(type.struct_def->defined_namespace,
type.struct_def->defined_namespace, NativeName(*type.struct_def)); NativeName(*type.struct_def));
} else if (type.base_type == BASE_TYPE_UNION) { } else if (type.base_type == BASE_TYPE_UNION) {
return "*" + WrapInNameSpaceAndTrack( return "*" + WrapInNameSpaceAndTrack(type.enum_def->defined_namespace,
type.enum_def->defined_namespace, NativeName(*type.enum_def)); NativeName(*type.enum_def));
} }
FLATBUFFERS_ASSERT(0); FLATBUFFERS_ASSERT(0);
return std::string(); return std::string();
@@ -1271,13 +1267,12 @@ class GoGenerator : public BaseGenerator {
void BeginFile(const std::string &name_space_name, const bool needs_imports, void BeginFile(const std::string &name_space_name, const bool needs_imports,
const bool is_enum, std::string *code_ptr) { const bool is_enum, std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code = code + "// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n"; code = code +
"// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n";
code += "package " + name_space_name + "\n\n"; code += "package " + name_space_name + "\n\n";
if (needs_imports) { if (needs_imports) {
code += "import (\n"; code += "import (\n";
if (is_enum) { if (is_enum) { code += "\t\"strconv\"\n\n"; }
code += "\t\"strconv\"\n\n";
}
if (!parser_.opts.go_import.empty()) { if (!parser_.opts.go_import.empty()) {
code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n"; code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n";
} else { } else {
@@ -1286,17 +1281,14 @@ class GoGenerator : public BaseGenerator {
if (tracked_imported_namespaces_.size() > 0) { if (tracked_imported_namespaces_.size() > 0) {
code += "\n"; code += "\n";
for (auto it = tracked_imported_namespaces_.begin(); for (auto it = tracked_imported_namespaces_.begin();
it != tracked_imported_namespaces_.end(); it != tracked_imported_namespaces_.end(); ++it) {
++it) { code += "\t" + NamespaceImportName(*it) + " \"" +
code += "\t" + NamespaceImportName(*it) + " \"" + \ NamespaceImportPath(*it) + "\"\n";
NamespaceImportPath(*it) + "\"\n";
} }
} }
code += ")\n\n"; code += ")\n\n";
} else { } else {
if (is_enum) { if (is_enum) { code += "import \"strconv\"\n\n"; }
code += "import \"strconv\"\n\n";
}
} }
} }
@@ -1364,8 +1356,7 @@ class GoGenerator : public BaseGenerator {
static size_t MaxNameLength(const EnumDef &enum_def) { static size_t MaxNameLength(const EnumDef &enum_def) {
size_t max = 0; size_t max = 0;
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
++it) {
max = std::max((*it)->name.length(), max); max = std::max((*it)->name.length(), max);
} }
return max; return max;

View File

@@ -20,7 +20,6 @@
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include "src/compiler/cpp_generator.h" #include "src/compiler/cpp_generator.h"
#include "src/compiler/go_generator.h" #include "src/compiler/go_generator.h"
#include "src/compiler/java_generator.h" #include "src/compiler/java_generator.h"
@@ -35,9 +34,7 @@ namespace flatbuffers {
class FlatBufMethod : public grpc_generator::Method { class FlatBufMethod : public grpc_generator::Method {
public: public:
enum Streaming { enum Streaming { kNone, kClient, kServer, kBiDi };
kNone, kClient, kServer, kBiDi
};
FlatBufMethod(const RPCCall *method) : method_(method) { FlatBufMethod(const RPCCall *method) : method_(method) {
streaming_ = kNone; streaming_ = kNone;
@@ -171,7 +168,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
void Outdent() { void Outdent() {
indent_--; indent_--;
FLATBUFFERS_ASSERT(indent_ >= 0); FLATBUFFERS_ASSERT(indent_ >= 0);
} }
private: private:
@@ -182,9 +179,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
class FlatBufFile : public grpc_generator::File { class FlatBufFile : public grpc_generator::File {
public: public:
enum Language { enum Language { kLanguageGo, kLanguageCpp, kLanguageJava };
kLanguageGo, kLanguageCpp, kLanguageJava
};
FlatBufFile(const Parser &parser, const std::string &file_name, FlatBufFile(const Parser &parser, const std::string &file_name,
Language language) Language language)
@@ -270,7 +265,8 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
auto service = file.service(i); auto service = file.service(i);
const Definition *def = parser_.services_.vec[i]; const Definition *def = parser_.services_.vec[i];
p.package_name = LastNamespacePart(*(def->defined_namespace)); p.package_name = LastNamespacePart(*(def->defined_namespace));
p.service_prefix = def->defined_namespace->GetFullyQualifiedName(""); // file.package(); p.service_prefix =
def->defined_namespace->GetFullyQualifiedName(""); // file.package();
std::string output = std::string output =
grpc_go_generator::GenerateServiceSource(&file, service.get(), &p); grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
std::string filename = std::string filename =
@@ -313,20 +309,20 @@ bool GenerateCppGRPC(const Parser &parser, const std::string &path,
std::string header_code = std::string header_code =
grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) + grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) + grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) + grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters); grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters);
std::string source_code = std::string source_code =
grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) + grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) +
grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) + grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) +
grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) + grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) +
grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters); grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters);
return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(), return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(),
header_code, false) && header_code, false) &&
flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(), flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(),
source_code, false); source_code, false);
} }
class JavaGRPCGenerator : public flatbuffers::BaseGenerator { class JavaGRPCGenerator : public flatbuffers::BaseGenerator {

View File

@@ -127,9 +127,7 @@ class JsTsGenerator : public BaseGenerator {
const auto &file = *it; const auto &file = *it;
const auto basename = const auto basename =
flatbuffers::StripPath(flatbuffers::StripExtension(file)); flatbuffers::StripPath(flatbuffers::StripExtension(file));
if (basename != file_name_) { if (basename != file_name_) { code += GenPrefixedImport(file, basename); }
code += GenPrefixedImport(file, basename);
}
} }
} }
@@ -309,14 +307,12 @@ class JsTsGenerator : public BaseGenerator {
result += " " + type_name; result += " " + type_name;
break; break;
} }
default: { result += " {" + type_name + "}"; } default: {
} result += " {" + type_name + "}";
if (!arg_name.empty()) { }
result += " " + arg_name;
}
if (include_newline) {
result += "\n";
} }
if (!arg_name.empty()) { result += " " + arg_name; }
if (include_newline) { result += "\n"; }
return result; return result;
} }
@@ -605,7 +601,8 @@ class JsTsGenerator : public BaseGenerator {
} }
void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr, void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
std::string &code, std::string &object_name, bool size_prefixed) { std::string &code, std::string &object_name,
bool size_prefixed) {
if (!struct_def.fixed) { if (!struct_def.fixed) {
GenDocComment(code_ptr, GenDocComment(code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") + GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
@@ -613,11 +610,13 @@ class JsTsGenerator : public BaseGenerator {
GenTypeAnnotation(kReturns, object_name, "", false)); GenTypeAnnotation(kReturns, object_name, "", false));
std::string sizePrefixed("SizePrefixed"); std::string sizePrefixed("SizePrefixed");
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As"); code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" +
Verbose(struct_def, "As");
code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name + code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
"):" + object_name + " {\n"; "):" + object_name + " {\n";
} else { } else {
code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As"); code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") +
"Root" + Verbose(struct_def, "As");
code += " = function(bb, obj) {\n"; code += " = function(bb, obj) {\n";
} }
code += " return (obj || new " + object_name; code += " return (obj || new " + object_name;
@@ -627,21 +626,22 @@ class JsTsGenerator : public BaseGenerator {
} }
void GenerateFinisher(StructDef &struct_def, std::string *code_ptr, void GenerateFinisher(StructDef &struct_def, std::string *code_ptr,
std::string &code, std::string &object_name, bool size_prefixed) { std::string &code, std::string &object_name,
bool size_prefixed) {
if (parser_.root_struct_def_ == &struct_def) { if (parser_.root_struct_def_ == &struct_def) {
std::string sizePrefixed("SizePrefixed"); std::string sizePrefixed("SizePrefixed");
GenDocComment( GenDocComment(
code_ptr, code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") + GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset", GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset", false));
false));
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "static finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer"; code += "static finish" + (size_prefixed ? sizePrefixed : "") +
code += Verbose(struct_def) + "Buffer";
"(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n"; code += "(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
} else { } else {
code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer"; code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") +
Verbose(struct_def) + "Buffer";
code += " = function(builder, offset) {\n"; code += " = function(builder, offset) {\n";
} }
@@ -650,9 +650,7 @@ class JsTsGenerator : public BaseGenerator {
code += ", '" + parser_.file_identifier_ + "'"; code += ", '" + parser_.file_identifier_ + "'";
} }
if (size_prefixed) { if (size_prefixed) {
if (parser_.file_identifier_.empty()) { if (parser_.file_identifier_.empty()) { code += ", undefined"; }
code += ", undefined";
}
code += ", true"; code += ", true";
} }
code += ");\n"; code += ");\n";
@@ -682,7 +680,8 @@ class JsTsGenerator : public BaseGenerator {
code += " {\n"; code += " {\n";
if (lang_.language != IDLOptions::kTs) { if (lang_.language != IDLOptions::kTs) {
code += " /**\n"; code += " /**\n";
code += " * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", ""); code +=
" * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", "");
code += " */\n"; code += " */\n";
} }
code += " bb: flatbuffers.ByteBuffer|null = null;\n"; code += " bb: flatbuffers.ByteBuffer|null = null;\n";
@@ -752,10 +751,9 @@ class JsTsGenerator : public BaseGenerator {
// Generate the identifier check method // Generate the identifier check method
if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def && if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def &&
!parser_.file_identifier_.empty()) { !parser_.file_identifier_.empty()) {
GenDocComment( GenDocComment(code_ptr,
code_ptr, GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") + GenTypeAnnotation(kReturns, "boolean", "", false));
GenTypeAnnotation(kReturns, "boolean", "", false));
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += code +=
"static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean " "static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean "
@@ -872,7 +870,8 @@ class JsTsGenerator : public BaseGenerator {
code += ", " + GenBBAccess() + ") : null;\n"; code += ", " + GenBBAccess() + ") : null;\n";
} }
if (lang_.language == IDLOptions::kTs && !parser_.opts.generate_all) { if (lang_.language == IDLOptions::kTs &&
!parser_.opts.generate_all) {
imported_files.insert(field.value.type.struct_def->file); imported_files.insert(field.value.type.struct_def->file);
} }
@@ -1290,8 +1289,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
if (field.deprecated) if (field.deprecated) continue;
continue;
paramDoc += paramDoc +=
GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field)); GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field));
} }
@@ -1311,8 +1309,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
if (field.deprecated) if (field.deprecated) continue;
continue;
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += ", " + GetArgName(field) + ":" + GetArgType(field); code += ", " + GetArgName(field) + ":" + GetArgType(field);
@@ -1336,8 +1333,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
if (field.deprecated) if (field.deprecated) continue;
continue;
code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "("; code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "(";
code += "builder, " + GetArgName(field) + ");\n"; code += "builder, " + GetArgName(field) + ");\n";
@@ -1346,14 +1342,11 @@ class JsTsGenerator : public BaseGenerator {
code += " return " + methodPrefix + ".end" + Verbose(struct_def) + code += " return " + methodPrefix + ".end" + Verbose(struct_def) +
"(builder);\n"; "(builder);\n";
code += "}\n"; code += "}\n";
if (lang_.language == IDLOptions::kJs) if (lang_.language == IDLOptions::kJs) code += "\n";
code += "\n";
} }
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
if (!object_namespace.empty()) { if (!object_namespace.empty()) { code += "}\n"; }
code += "}\n";
}
code += "}\n"; code += "}\n";
} }
} }
@@ -1372,9 +1365,7 @@ class JsTsGenerator : public BaseGenerator {
return argname; return argname;
} }
std::string Verbose(const StructDef &struct_def, std::string Verbose(const StructDef &struct_def, const char *prefix = "") {
const char* prefix = "")
{
return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name; return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name;
} }
}; };

View File

@@ -15,6 +15,7 @@
*/ */
#include <iostream> #include <iostream>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"

File diff suppressed because it is too large Load Diff

View File

@@ -27,14 +27,16 @@ namespace lobster {
class LobsterGenerator : public BaseGenerator { class LobsterGenerator : public BaseGenerator {
public: public:
LobsterGenerator(const Parser &parser, const std::string &path, LobsterGenerator(const Parser &parser, const std::string &path,
const std::string &file_name) const std::string &file_name)
: BaseGenerator(parser, path, file_name, "" /* not used */, "_") { : BaseGenerator(parser, path, file_name, "" /* not used */, "_") {
static const char * const keywords[] = { static const char *const keywords[] = {
"nil", "true", "false", "return", "struct", "class", "import", "int", "nil", "true", "false", "return", "struct", "class",
"float", "string", "any", "def", "is", "from", "program", "private", "import", "int", "float", "string", "any", "def",
"coroutine", "resource", "enum", "typeof", "var", "let", "pakfile", "is", "from", "program", "private", "coroutine", "resource",
"switch", "case", "default", "namespace", "not", "and", "or", "bool", "enum", "typeof", "var", "let", "pakfile", "switch",
"case", "default", "namespace", "not", "and", "or",
"bool",
}; };
keywords_.insert(std::begin(keywords), std::end(keywords)); keywords_.insert(std::begin(keywords), std::end(keywords));
} }
@@ -66,7 +68,8 @@ class LobsterGenerator : public BaseGenerator {
std::string LobsterType(const Type &type) { std::string LobsterType(const Type &type) {
if (IsFloat(type.base_type)) return "float"; if (IsFloat(type.base_type)) return "float";
if (IsScalar(type.base_type) && type.enum_def) return NormalizedName(*type.enum_def); if (IsScalar(type.base_type) && type.enum_def)
return NormalizedName(*type.enum_def);
if (!IsScalar(type.base_type)) return "flatbuffers_offset"; if (!IsScalar(type.base_type)) return "flatbuffers_offset";
return "int"; return "int";
} }
@@ -74,14 +77,14 @@ class LobsterGenerator : public BaseGenerator {
// Returns the method name for use with add/put calls. // Returns the method name for use with add/put calls.
std::string GenMethod(const Type &type) { std::string GenMethod(const Type &type) {
return IsScalar(type.base_type) return IsScalar(type.base_type)
? MakeCamel(GenTypeBasic(type)) ? MakeCamel(GenTypeBasic(type))
: (IsStruct(type) ? "Struct" : "UOffsetTRelative"); : (IsStruct(type) ? "Struct" : "UOffsetTRelative");
} }
// This uses Python names for now.. // This uses Python names for now..
std::string GenTypeBasic(const Type &type) { std::string GenTypeBasic(const Type &type) {
static const char *ctypename[] = { static const char *ctypename[] = {
// clang-format off // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
#PTYPE, #PTYPE,
@@ -93,8 +96,8 @@ class LobsterGenerator : public BaseGenerator {
} }
// Generate a struct field, conditioned on its child type(s). // Generate a struct field, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, nullptr, " "); GenComment(field.doc_comment, code_ptr, nullptr, " ");
std::string &code = *code_ptr; std::string &code = *code_ptr;
auto offsets = NumToString(field.value.offset); auto offsets = NumToString(field.value.offset);
@@ -102,13 +105,12 @@ class LobsterGenerator : public BaseGenerator {
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
std::string acc; std::string acc;
if (struct_def.fixed) { if (struct_def.fixed) {
acc = "buf_.read_" + GenTypeName(field.value.type) + acc = "buf_.read_" + GenTypeName(field.value.type) + "_le(pos_ + " +
"_le(pos_ + " + offsets + ")"; offsets + ")";
} else { } else {
acc = "buf_.flatbuffers_field_" + acc = "buf_.flatbuffers_field_" + GenTypeName(field.value.type) +
GenTypeName(field.value.type) + "(pos_, " + offsets + ", " + "(pos_, " + offsets + ", " + field.value.constant + ")";
field.value.constant + ")";
} }
if (field.value.type.enum_def) if (field.value.type.enum_def)
acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")"; acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")";
@@ -130,7 +132,8 @@ class LobsterGenerator : public BaseGenerator {
break; break;
} }
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
code += def + "():\n return buf_.flatbuffers_field_string(pos_, " + code += def +
"():\n return buf_.flatbuffers_field_string(pos_, " +
offsets + ")\n"; offsets + ")\n";
break; break;
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
@@ -171,19 +174,20 @@ class LobsterGenerator : public BaseGenerator {
} }
if (field.value.type.base_type == BASE_TYPE_VECTOR) { if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code += def + code += def +
"_length():\n return buf_.flatbuffers_field_vector_len(pos_, " + "_length():\n return "
"buf_.flatbuffers_field_vector_len(pos_, " +
offsets + ")\n"; offsets + ")\n";
} }
} }
// Generate table constructors, conditioned on its members' types. // Generate table constructors, conditioned on its members' types.
void GenTableBuilders(const StructDef &struct_def, void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "struct " + NormalizedName(struct_def) + code += "struct " + NormalizedName(struct_def) +
"Builder:\n b_:flatbuffers_builder\n"; "Builder:\n b_:flatbuffers_builder\n";
code += " def start():\n b_.StartObject(" + code += " def start():\n b_.StartObject(" +
NumToString(struct_def.fields.vec.size()) + ")\n return this\n"; NumToString(struct_def.fields.vec.size()) +
")\n return this\n";
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
auto &field = **it; auto &field = **it;
@@ -209,8 +213,8 @@ class LobsterGenerator : public BaseGenerator {
auto vector_type = field.value.type.VectorType(); auto vector_type = field.value.type.VectorType();
auto alignment = InlineAlignment(vector_type); auto alignment = InlineAlignment(vector_type);
auto elem_size = InlineSize(vector_type); auto elem_size = InlineSize(vector_type);
code += NumToString(elem_size) + ", n_, " + NumToString(alignment) + code +=
")\n"; NumToString(elem_size) + ", n_, " + NumToString(alignment) + ")\n";
if (vector_type.base_type != BASE_TYPE_STRUCT || if (vector_type.base_type != BASE_TYPE_STRUCT ||
!vector_type.struct_def->fixed) { !vector_type.struct_def->fixed) {
code += "def " + NormalizedName(struct_def) + "Create" + code += "def " + NormalizedName(struct_def) + "Create" +
@@ -218,8 +222,7 @@ class LobsterGenerator : public BaseGenerator {
"Vector(b_:flatbuffers_builder, v_:[" + "Vector(b_:flatbuffers_builder, v_:[" +
LobsterType(vector_type) + "]):\n b_.StartVector(" + LobsterType(vector_type) + "]):\n b_.StartVector(" +
NumToString(elem_size) + ", v_.length, " + NumToString(elem_size) + ", v_.length, " +
NumToString(alignment) + NumToString(alignment) + ")\n reverse(v_) e_: b_.Prepend" +
")\n reverse(v_) e_: b_.Prepend" +
GenMethod(vector_type) + GenMethod(vector_type) +
"(e_)\n return b_.EndVector(v_.length)\n"; "(e_)\n return b_.EndVector(v_.length)\n";
} }
@@ -243,7 +246,7 @@ class LobsterGenerator : public BaseGenerator {
GenComment(struct_def.doc_comment, code_ptr, nullptr, ""); GenComment(struct_def.doc_comment, code_ptr, nullptr, "");
code += "class " + NormalizedName(struct_def) + " : flatbuffers_handle\n"; code += "class " + NormalizedName(struct_def) + " : flatbuffers_handle\n";
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
auto &field = **it; auto &field = **it;
if (field.deprecated) continue; if (field.deprecated) continue;
GenStructAccessor(struct_def, field, code_ptr); GenStructAccessor(struct_def, field, code_ptr);
@@ -252,8 +255,8 @@ class LobsterGenerator : public BaseGenerator {
if (!struct_def.fixed) { if (!struct_def.fixed) {
// Generate a special accessor for the table that has been declared as // Generate a special accessor for the table that has been declared as
// the root type. // the root type.
code += "def GetRootAs" + NormalizedName(struct_def) + "(buf:string): return " + code += "def GetRootAs" + NormalizedName(struct_def) +
NormalizedName(struct_def) + "(buf:string): return " + NormalizedName(struct_def) +
" { buf, buf.flatbuffers_indirect(0) }\n\n"; " { buf, buf.flatbuffers_indirect(0) }\n\n";
} }
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -283,8 +286,8 @@ class LobsterGenerator : public BaseGenerator {
// Recursively generate arguments for a constructor, to deal with nested // Recursively generate arguments for a constructor, to deal with nested
// structs. // structs.
void StructBuilderArgs(const StructDef &struct_def, void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
auto &field = **it; auto &field = **it;
@@ -293,7 +296,8 @@ class LobsterGenerator : public BaseGenerator {
// don't clash, and to make it obvious these arguments are constructing // don't clash, and to make it obvious these arguments are constructing
// a nested struct, prefix the name with the field name. // a nested struct, prefix the name with the field name.
StructBuilderArgs(*field.value.type.struct_def, StructBuilderArgs(*field.value.type.struct_def,
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr); (nameprefix + (NormalizedName(field) + "_")).c_str(),
code_ptr);
} else { } else {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += ", " + (nameprefix + NormalizedName(field)) + ":" + code += ", " + (nameprefix + NormalizedName(field)) + ":" +
@@ -304,8 +308,8 @@ class LobsterGenerator : public BaseGenerator {
// Recursively generate struct construction statements and instert manual // Recursively generate struct construction statements and instert manual
// padding. // padding.
void StructBuilderBody(const StructDef &struct_def, void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " + code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " +
NumToString(struct_def.bytesize) + ")\n"; NumToString(struct_def.bytesize) + ")\n";
@@ -316,7 +320,8 @@ class LobsterGenerator : public BaseGenerator {
code += " b_.Pad(" + NumToString(field.padding) + ")\n"; code += " b_.Pad(" + NumToString(field.padding) + ")\n";
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
StructBuilderBody(*field.value.type.struct_def, StructBuilderBody(*field.value.type.struct_def,
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr); (nameprefix + (NormalizedName(field) + "_")).c_str(),
code_ptr);
} else { } else {
code += " b_.Prepend" + GenMethod(field.value.type) + "(" + code += " b_.Prepend" + GenMethod(field.value.type) + "(" +
nameprefix + NormalizedName(field) + ")\n"; nameprefix + NormalizedName(field) + ")\n";
@@ -325,11 +330,10 @@ class LobsterGenerator : public BaseGenerator {
} }
// Create a struct with a builder and the struct's arguments. // Create a struct with a builder and the struct's arguments.
void GenStructBuilder(const StructDef &struct_def, void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def Create" + NormalizedName(struct_def) + code +=
"(b_:flatbuffers_builder"; "def Create" + NormalizedName(struct_def) + "(b_:flatbuffers_builder";
StructBuilderArgs(struct_def, "", code_ptr); StructBuilderArgs(struct_def, "", code_ptr);
code += "):\n"; code += "):\n";
StructBuilderBody(struct_def, "", code_ptr); StructBuilderBody(struct_def, "", code_ptr);
@@ -363,8 +367,8 @@ class LobsterGenerator : public BaseGenerator {
auto &struct_def = **it; auto &struct_def = **it;
GenStruct(struct_def, &code); GenStruct(struct_def, &code);
} }
return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(), return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(), code,
code, false); false);
} }
private: private:
@@ -375,7 +379,7 @@ class LobsterGenerator : public BaseGenerator {
} // namespace lobster } // namespace lobster
bool GenerateLobster(const Parser &parser, const std::string &path, bool GenerateLobster(const Parser &parser, const std::string &path,
const std::string &file_name) { const std::string &file_name) {
lobster::LobsterGenerator generator(parser, path, file_name); lobster::LobsterGenerator generator(parser, path, file_name);
return generator.generate(); return generator.generate();
} }

File diff suppressed because it is too large Load Diff

View File

@@ -826,7 +826,8 @@ class PhpGenerator : public BaseGenerator {
code += Indent + "private static $names = array(\n"; code += Indent + "private static $names = array(\n";
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) { for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
auto &ev = **it; auto &ev = **it;
code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" + ev.name + "\",\n"; code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" +
ev.name + "\",\n";
} }
code += Indent + ");\n\n"; code += Indent + ");\n\n";

View File

@@ -17,14 +17,13 @@
// independent from idl_parser, since this code is not needed for most clients // independent from idl_parser, since this code is not needed for most clients
#include <string> #include <string>
#include <unordered_set>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include <unordered_set>
namespace flatbuffers { namespace flatbuffers {
namespace python { namespace python {
@@ -39,40 +38,12 @@ class PythonGenerator : public BaseGenerator {
: BaseGenerator(parser, path, file_name, "" /* not used */, : BaseGenerator(parser, path, file_name, "" /* not used */,
"" /* not used */), "" /* not used */),
float_const_gen_("float('nan')", "float('inf')", "float('-inf')") { float_const_gen_("float('nan')", "float('inf')", "float('-inf')") {
static const char * const keywords[] = { static const char *const keywords[] = {
"False", "False", "None", "True", "and", "as", "assert", "break",
"None", "class", "continue", "def", "del", "elif", "else", "except",
"True", "finally", "for", "from", "global", "if", "import", "in",
"and", "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
"as", "return", "try", "while", "with", "yield"
"assert",
"break",
"class",
"continue",
"def",
"del",
"elif",
"else",
"except",
"finally",
"for",
"from",
"global",
"if",
"import",
"in",
"is",
"lambda",
"nonlocal",
"not",
"or",
"pass",
"raise",
"return",
"try",
"while",
"with",
"yield"
}; };
keywords_.insert(std::begin(keywords), std::end(keywords)); keywords_.insert(std::begin(keywords), std::end(keywords));
} }
@@ -81,9 +52,9 @@ class PythonGenerator : public BaseGenerator {
// this is the prefix code for that. // this is the prefix code for that.
std::string OffsetPrefix(const FieldDef &field) { std::string OffsetPrefix(const FieldDef &field) {
return "\n" + Indent + Indent + return "\n" + Indent + Indent +
"o = flatbuffers.number_types.UOffsetTFlags.py_type" + "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
"(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" + "(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" +
Indent + Indent + "if o != 0:\n"; Indent + Indent + "if o != 0:\n";
} }
// Begin a class declaration. // Begin a class declaration.
@@ -148,8 +119,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Initialize an existing object with other data, to avoid an allocation. // Initialize an existing object with other data, to avoid an allocation.
void InitializeExisting(const StructDef &struct_def, void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -172,8 +142,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a struct's scalar. // Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def, void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -184,8 +153,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the value of a table's scalar. // Get the value of a table's scalar.
void GetScalarFieldOfTable(const StructDef &struct_def, void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string getter = GenGetter(field.value.type); std::string getter = GenGetter(field.value.type);
@@ -195,9 +163,7 @@ class PythonGenerator : public BaseGenerator {
code += OffsetPrefix(field); code += OffsetPrefix(field);
getter += "o + self._tab.Pos)"; getter += "o + self._tab.Pos)";
auto is_bool = IsBool(field.value.type.base_type); auto is_bool = IsBool(field.value.type.base_type);
if (is_bool) { if (is_bool) { getter = "bool(" + getter + ")"; }
getter = "bool(" + getter + ")";
}
code += Indent + Indent + Indent + "return " + getter + "\n"; code += Indent + Indent + Indent + "return " + getter + "\n";
std::string default_value; std::string default_value;
if (is_bool) { if (is_bool) {
@@ -213,8 +179,7 @@ class PythonGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Struct. // Specific to Struct.
void GetStructFieldOfStruct(const StructDef &struct_def, void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -250,8 +215,7 @@ class PythonGenerator : public BaseGenerator {
// Get a struct by initializing an existing struct. // Get a struct by initializing an existing struct.
// Specific to Table. // Specific to Table.
void GetStructFieldOfTable(const StructDef &struct_def, void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -296,7 +260,8 @@ class PythonGenerator : public BaseGenerator {
// TODO(rw): this works and is not the good way to it: // TODO(rw): this works and is not the good way to it:
bool is_native_table = TypeName(field) == "*flatbuffers.Table"; bool is_native_table = TypeName(field) == "*flatbuffers.Table";
if (is_native_table) { if (is_native_table) {
code += Indent + Indent + Indent + "from flatbuffers.table import Table\n"; code +=
Indent + Indent + Indent + "from flatbuffers.table import Table\n";
} else { } else {
code += Indent + Indent + Indent; code += Indent + Indent + Indent;
code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n"; code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
@@ -309,8 +274,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a vector's struct member. // Get the value of a vector's struct member.
void GetMemberOfVectorOfStruct(const StructDef &struct_def, void GetMemberOfVectorOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
@@ -388,8 +352,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Begin the creator function signature. // Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def, void BeginBuilderArgs(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "\n"; code += "\n";
@@ -399,10 +362,10 @@ class PythonGenerator : public BaseGenerator {
// Recursively generate arguments for a constructor, to deal with nested // Recursively generate arguments for a constructor, to deal with nested
// structs. // structs.
void StructBuilderArgs(const StructDef &struct_def, void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
auto &field = **it; auto &field = **it;
const auto &field_type = field.value.type; const auto &field_type = field.value.type;
const auto &type = const auto &type =
@@ -439,7 +402,7 @@ class PythonGenerator : public BaseGenerator {
indent + " builder.Prep(" + NumToString(struct_def.minalign) + ", "; indent + " builder.Prep(" + NumToString(struct_def.minalign) + ", ";
code += NumToString(struct_def.bytesize) + ")\n"; code += NumToString(struct_def.bytesize) + ")\n";
for (auto it = struct_def.fields.vec.rbegin(); for (auto it = struct_def.fields.vec.rbegin();
it != struct_def.fields.vec.rend(); ++it) { it != struct_def.fields.vec.rend(); ++it) {
auto &field = **it; auto &field = **it;
const auto &field_type = field.value.type; const auto &field_type = field.value.type;
const auto &type = const auto &type =
@@ -484,8 +447,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the value of a table's starting offset. // Get the value of a table's starting offset.
void GetStartOfTable(const StructDef &struct_def, void GetStartOfTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start"; code += "def " + NormalizedName(struct_def) + "Start";
code += "(builder): "; code += "(builder): ";
@@ -495,11 +457,11 @@ class PythonGenerator : public BaseGenerator {
} }
// Set the value of a table's field. // Set the value of a table's field.
void BuildFieldOfTable(const StructDef &struct_def, void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, const size_t offset, const size_t offset, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field)); code += "def " + NormalizedName(struct_def) + "Add" +
MakeCamel(NormalizedName(field));
code += "(builder, "; code += "(builder, ";
code += MakeCamel(NormalizedName(field), false); code += MakeCamel(NormalizedName(field), false);
code += "): "; code += "): ";
@@ -521,8 +483,8 @@ class PythonGenerator : public BaseGenerator {
} }
// Set the value of one of the members of a table's vector. // Set the value of one of the members of a table's vector.
void BuildVectorOfTable(const StructDef &struct_def, void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start"; code += "def " + NormalizedName(struct_def) + "Start";
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -536,8 +498,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the offset of the end of a table. // Get the offset of the end of a table.
void GetEndOffsetOnTable(const StructDef &struct_def, void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "End"; code += "def " + NormalizedName(struct_def) + "End";
code += "(builder): "; code += "(builder): ";
@@ -552,8 +513,8 @@ class PythonGenerator : public BaseGenerator {
} }
// Generate a struct field, conditioned on its child type(s). // Generate a struct field, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str()); GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str());
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -572,7 +533,9 @@ class PythonGenerator : public BaseGenerator {
GetStructFieldOfTable(struct_def, field, code_ptr); GetStructFieldOfTable(struct_def, field, code_ptr);
} }
break; break;
case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break; case BASE_TYPE_STRING:
GetStringField(struct_def, field, code_ptr);
break;
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
auto vectortype = field.value.type.VectorType(); auto vectortype = field.value.type.VectorType();
if (vectortype.base_type == BASE_TYPE_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -593,12 +556,11 @@ class PythonGenerator : public BaseGenerator {
} }
// Generate table constructors, conditioned on its members' types. // Generate table constructors, conditioned on its members' types.
void GenTableBuilders(const StructDef &struct_def, void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
GetStartOfTable(struct_def, code_ptr); GetStartOfTable(struct_def, code_ptr);
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
auto &field = **it; auto &field = **it;
if (field.deprecated) continue; if (field.deprecated) continue;
@@ -635,7 +597,7 @@ class PythonGenerator : public BaseGenerator {
code += "\", size_prefixed=size_prefixed)\n"; code += "\", size_prefixed=size_prefixed)\n";
code += "\n"; code += "\n";
} }
// Generate struct or table methods. // Generate struct or table methods.
void GenStruct(const StructDef &struct_def, std::string *code_ptr) { void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
if (struct_def.generated) return; if (struct_def.generated) return;
@@ -646,7 +608,7 @@ class PythonGenerator : public BaseGenerator {
// Generate a special accessor for the table that has been declared as // Generate a special accessor for the table that has been declared as
// the root type. // the root type.
NewRootTypeFromBuffer(struct_def, code_ptr); NewRootTypeFromBuffer(struct_def, code_ptr);
if (parser_.file_identifier_.length()){ if (parser_.file_identifier_.length()) {
// Generate a special function to test file_identifier // Generate a special function to test file_identifier
GenHasFileIdentifier(struct_def, code_ptr); GenHasFileIdentifier(struct_def, code_ptr);
} }
@@ -655,7 +617,7 @@ class PythonGenerator : public BaseGenerator {
// accessor object. This is to allow object reuse. // accessor object. This is to allow object reuse.
InitializeExisting(struct_def, code_ptr); InitializeExisting(struct_def, code_ptr);
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
auto &field = **it; auto &field = **it;
if (field.deprecated) continue; if (field.deprecated) continue;
@@ -693,7 +655,7 @@ class PythonGenerator : public BaseGenerator {
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
default: default:
return "self._tab.Get(flatbuffers.number_types." + return "self._tab.Get(flatbuffers.number_types." +
MakeCamel(GenTypeGet(type)) + "Flags, "; MakeCamel(GenTypeGet(type)) + "Flags, ";
} }
} }
@@ -738,8 +700,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Create a struct with a builder and the struct's arguments. // Create a struct with a builder and the struct's arguments.
void GenStructBuilder(const StructDef &struct_def, void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
BeginBuilderArgs(struct_def, code_ptr); BeginBuilderArgs(struct_def, code_ptr);
StructBuilderArgs(struct_def, "", code_ptr); StructBuilderArgs(struct_def, "", code_ptr);
EndBuilderArgs(code_ptr); EndBuilderArgs(code_ptr);
@@ -807,6 +768,7 @@ class PythonGenerator : public BaseGenerator {
NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py"; NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py";
return SaveFile(filename.c_str(), code, false); return SaveFile(filename.c_str(), code, false);
} }
private: private:
std::unordered_set<std::string> keywords_; std::unordered_set<std::string> keywords_;
const SimpleFloatConstantGenerator float_const_gen_; const SimpleFloatConstantGenerator float_const_gen_;

File diff suppressed because it is too large Load Diff

View File

@@ -142,8 +142,8 @@ bool Print<const void *>(const void *val, Type type, int indent,
FLATBUFFERS_ASSERT(prev_val); FLATBUFFERS_ASSERT(prev_val);
auto union_type_byte = *prev_val; // Always a uint8_t. auto union_type_byte = *prev_val; // Always a uint8_t.
if (vector_index >= 0) { if (vector_index >= 0) {
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val + auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(
ReadScalar<uoffset_t>(prev_val)); prev_val + ReadScalar<uoffset_t>(prev_val));
union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index)); union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index));
} }
auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true); auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true);
@@ -205,9 +205,7 @@ bool Print<const void *>(const void *val, Type type, int indent,
// clang-format on // clang-format on
return true; return true;
} }
default: default: FLATBUFFERS_ASSERT(0); return false;
FLATBUFFERS_ASSERT(0);
return false;
} }
} }
@@ -287,7 +285,7 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
text += ":"; text += ":";
text += " "; text += " ";
switch (fd.value.type.base_type) { switch (fd.value.type.base_type) {
// clang-format off // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_ ## ENUM: \
@@ -310,7 +308,7 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
return false; return false;
} }
break; break;
// clang-format on // clang-format on
} }
// Track prev val for use with union types. // Track prev val for use with union types.
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -330,15 +328,11 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
bool GenerateTextFromTable(const Parser &parser, const void *table, bool GenerateTextFromTable(const Parser &parser, const void *table,
const std::string &table_name, std::string *_text) { const std::string &table_name, std::string *_text) {
auto struct_def = parser.LookupStruct(table_name); auto struct_def = parser.LookupStruct(table_name);
if (struct_def == nullptr) { if (struct_def == nullptr) { return false; }
return false;
}
auto &text = *_text; auto &text = *_text;
text.reserve(1024); // Reduce amount of inevitable reallocs. text.reserve(1024); // Reduce amount of inevitable reallocs.
auto root = static_cast<const Table *>(table); auto root = static_cast<const Table *>(table);
if (!GenStruct(*struct_def, root, 0, parser.opts, &text)) { if (!GenStruct(*struct_def, root, 0, parser.opts, &text)) { return false; }
return false;
}
text += NewLine(parser.opts); text += NewLine(parser.opts);
return true; return true;
} }
@@ -348,9 +342,9 @@ bool GenerateText(const Parser &parser, const void *flatbuffer,
std::string *_text) { std::string *_text) {
std::string &text = *_text; std::string &text = *_text;
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType() FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
text.reserve(1024); // Reduce amount of inevitable reallocs. text.reserve(1024); // Reduce amount of inevitable reallocs.
auto root = parser.opts.size_prefixed ? auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
GetSizePrefixedRoot<Table>(flatbuffer) : GetRoot<Table>(flatbuffer); : GetRoot<Table>(flatbuffer);
if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) { if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) {
return false; return false;
} }

View File

@@ -15,12 +15,11 @@
*/ */
#include <algorithm> #include <algorithm>
#include <cmath>
#include <list> #include <list>
#include <string> #include <string>
#include <utility> #include <utility>
#include <cmath>
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
@@ -114,8 +113,8 @@ std::string MakeScreamingCamel(const std::string &in) {
return s; return s;
} }
void DeserializeDoc( std::vector<std::string> &doc, void DeserializeDoc(std::vector<std::string> &doc,
const Vector<Offset<String>> *documentation) { const Vector<Offset<String>> *documentation) {
if (documentation == nullptr) return; if (documentation == nullptr) return;
for (uoffset_t index = 0; index < documentation->size(); index++) for (uoffset_t index = 0; index < documentation->size(); index++)
doc.push_back(documentation->Get(index)->str()); doc.push_back(documentation->Get(index)->str());
@@ -399,7 +398,8 @@ CheckedError Parser::Next() {
"illegal Unicode sequence (unpaired high surrogate)"); "illegal Unicode sequence (unpaired high surrogate)");
} }
// reset if non-printable // reset if non-printable
attr_is_trivial_ascii_string_ &= check_ascii_range(*cursor_, ' ', '~'); attr_is_trivial_ascii_string_ &=
check_ascii_range(*cursor_, ' ', '~');
attribute_ += *cursor_++; attribute_ += *cursor_++;
} }
@@ -437,7 +437,7 @@ CheckedError Parser::Next() {
cursor_ += 2; cursor_ += 2;
break; break;
} }
FLATBUFFERS_FALLTHROUGH(); // else fall thru FLATBUFFERS_FALLTHROUGH(); // else fall thru
default: default:
const auto has_sign = (c == '+') || (c == '-'); const auto has_sign = (c == '+') || (c == '-');
// '-'/'+' and following identifier - can be a predefined constant like: // '-'/'+' and following identifier - can be a predefined constant like:
@@ -451,14 +451,15 @@ CheckedError Parser::Next() {
return NoError(); return NoError();
} }
auto dot_lvl = (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen auto dot_lvl =
if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum? (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen
if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum?
// Parser accepts hexadecimal-floating-literal (see C++ 5.13.4). // Parser accepts hexadecimal-floating-literal (see C++ 5.13.4).
if (is_digit(c) || has_sign || !dot_lvl) { if (is_digit(c) || has_sign || !dot_lvl) {
const auto start = cursor_ - 1; const auto start = cursor_ - 1;
auto start_digits = !is_digit(c) ? cursor_ : cursor_ - 1; auto start_digits = !is_digit(c) ? cursor_ : cursor_ - 1;
if (!is_digit(c) && is_digit(*cursor_)){ if (!is_digit(c) && is_digit(*cursor_)) {
start_digits = cursor_; // see digit in cursor_ position start_digits = cursor_; // see digit in cursor_ position
c = *cursor_++; c = *cursor_++;
} }
// hex-float can't begind with '.' // hex-float can't begind with '.'
@@ -501,7 +502,8 @@ CheckedError Parser::Next() {
} }
std::string ch; std::string ch;
ch = c; ch = c;
if (false == check_ascii_range(c, ' ', '~')) ch = "code: " + NumToString(c); if (false == check_ascii_range(c, ' ', '~'))
ch = "code: " + NumToString(c);
return Error("illegal character: " + ch); return Error("illegal character: " + ch);
} }
} }
@@ -730,7 +732,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (!IsScalar(type.base_type) || if (!IsScalar(type.base_type) ||
(struct_def.fixed && field->value.constant != "0")) (struct_def.fixed && field->value.constant != "0"))
return Error( return Error(
"default values currently only supported for scalars in tables"); "default values currently only supported for scalars in tables");
} }
// Append .0 if the value has not it (skip hex and scientific floats). // Append .0 if the value has not it (skip hex and scientific floats).
// This suffix needed for generated C++ code. // This suffix needed for generated C++ code.
@@ -738,7 +740,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
auto &text = field->value.constant; auto &text = field->value.constant;
FLATBUFFERS_ASSERT(false == text.empty()); FLATBUFFERS_ASSERT(false == text.empty());
auto s = text.c_str(); auto s = text.c_str();
while(*s == ' ') s++; while (*s == ' ') s++;
if (*s == '-' || *s == '+') s++; if (*s == '-' || *s == '+') s++;
// 1) A float constants (nan, inf, pi, etc) is a kind of identifier. // 1) A float constants (nan, inf, pi, etc) is a kind of identifier.
// 2) A float number needn't ".0" at the end if it has exponent. // 2) A float number needn't ".0" at the end if it has exponent.
@@ -774,7 +776,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
field->deprecated = field->attributes.Lookup("deprecated") != nullptr; field->deprecated = field->attributes.Lookup("deprecated") != nullptr;
auto hash_name = field->attributes.Lookup("hash"); auto hash_name = field->attributes.Lookup("hash");
if (hash_name) { if (hash_name) {
switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element : type.base_type) { switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element
: type.base_type) {
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: { case BASE_TYPE_USHORT: {
if (FindHashFunction16(hash_name->constant.c_str()) == nullptr) if (FindHashFunction16(hash_name->constant.c_str()) == nullptr)
@@ -798,7 +801,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
} }
default: default:
return Error( return Error(
"only short, ushort, int, uint, long and ulong data types support hashing."); "only short, ushort, int, uint, long and ulong data types support "
"hashing.");
} }
} }
auto cpp_type = field->attributes.Lookup("cpp_type"); auto cpp_type = field->attributes.Lookup("cpp_type");
@@ -817,8 +821,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (field->deprecated && struct_def.fixed) if (field->deprecated && struct_def.fixed)
return Error("can't deprecate fields in a struct"); return Error("can't deprecate fields in a struct");
field->required = field->attributes.Lookup("required") != nullptr; field->required = field->attributes.Lookup("required") != nullptr;
if (field->required && if (field->required && (struct_def.fixed || IsScalar(type.base_type)))
(struct_def.fixed || IsScalar(type.base_type)))
return Error("only non-scalar fields in tables may be 'required'"); return Error("only non-scalar fields in tables may be 'required'");
field->key = field->attributes.Lookup("key") != nullptr; field->key = field->attributes.Lookup("key") != nullptr;
if (field->key) { if (field->key) {
@@ -861,8 +864,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (field->attributes.Lookup("flexbuffer")) { if (field->attributes.Lookup("flexbuffer")) {
field->flexbuffer = true; field->flexbuffer = true;
uses_flexbuffers_ = true; uses_flexbuffers_ = true;
if (type.base_type != BASE_TYPE_VECTOR || if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR)
type.element != BASE_TYPE_UCHAR)
return Error("flexbuffer attribute may only apply to a vector of ubyte"); return Error("flexbuffer attribute may only apply to a vector of ubyte");
} }
@@ -902,8 +904,7 @@ CheckedError Parser::ParseComma() {
CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field, CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
size_t parent_fieldn, size_t parent_fieldn,
const StructDef *parent_struct_def, const StructDef *parent_struct_def,
uoffset_t count, uoffset_t count, bool inside_vector) {
bool inside_vector) {
switch (val.type.base_type) { switch (val.type.base_type) {
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
FLATBUFFERS_ASSERT(field); FLATBUFFERS_ASSERT(field);
@@ -921,8 +922,8 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
uoffset_t offset; uoffset_t offset;
ECHECK(atot(elem->first.constant.c_str(), *this, &offset)); ECHECK(atot(elem->first.constant.c_str(), *this, &offset));
vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>( vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>(
builder_.GetCurrentBufferPointer() + builder_.GetCurrentBufferPointer() + builder_.GetSize() -
builder_.GetSize() - offset); offset);
break; break;
} }
} else { } else {
@@ -964,8 +965,7 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
} }
} }
if (constant.empty() && !vector_of_union_types) { if (constant.empty() && !vector_of_union_types) {
return Error("missing type field for this union value: " + return Error("missing type field for this union value: " + field->name);
field->name);
} }
uint8_t enum_idx; uint8_t enum_idx;
if (vector_of_union_types) { if (vector_of_union_types) {
@@ -1040,10 +1040,9 @@ void Parser::SerializeStruct(FlatBufferBuilder &builder,
builder.AddStructOffset(val.offset, builder.GetSize()); builder.AddStructOffset(val.offset, builder.GetSize());
} }
template <typename F> template<typename F>
CheckedError Parser::ParseTableDelimiters(size_t &fieldn, CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
const StructDef *struct_def, const StructDef *struct_def, F body) {
F body) {
// We allow tables both as JSON object{ .. } with field names // We allow tables both as JSON object{ .. } with field names
// or vector[..] with all fields in order // or vector[..] with all fields in order
char terminator = '}'; char terminator = '}';
@@ -1217,7 +1216,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
reinterpret_cast<const uint8_t*>(field_value.constant.c_str()), reinterpret_cast<const uint8_t*>(field_value.constant.c_str()),
InlineSize(field_value.type)); InlineSize(field_value.type));
break; break;
// clang-format on // clang-format on
} }
} }
} }
@@ -1243,7 +1242,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
return NoError(); return NoError();
} }
template <typename F> template<typename F>
CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) { CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) {
EXPECT('['); EXPECT('[');
for (;;) { for (;;) {
@@ -1259,12 +1258,11 @@ CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) {
static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) { static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) {
switch (ftype) { switch (ftype) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
PTYPE, RTYPE, KTYPE) \ RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_##ENUM: return ReadScalar<CTYPE>(a) < ReadScalar<CTYPE>(b);
return ReadScalar<CTYPE>(a) < ReadScalar<CTYPE>(b);
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
// Indirect offset pointer to string pointer. // Indirect offset pointer to string pointer.
a += ReadScalar<uoffset_t>(a); a += ReadScalar<uoffset_t>(a);
@@ -1278,21 +1276,21 @@ static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) {
// See below for why we need our own sort :( // See below for why we need our own sort :(
template<typename T, typename F, typename S> template<typename T, typename F, typename S>
void SimpleQsort(T *begin, T *end, size_t width, F comparator, S swapper) { void SimpleQsort(T *begin, T *end, size_t width, F comparator, S swapper) {
if (end - begin <= static_cast<ptrdiff_t>(width)) return; if (end - begin <= static_cast<ptrdiff_t>(width)) return;
auto l = begin + width; auto l = begin + width;
auto r = end; auto r = end;
while (l < r) { while (l < r) {
if (comparator(begin, l)) { if (comparator(begin, l)) {
r -= width; r -= width;
swapper(l, r); swapper(l, r);
} else { } else {
l++; l++;
}
} }
l -= width; }
swapper(begin, l); l -= width;
SimpleQsort(begin, l, width, comparator, swapper); swapper(begin, l);
SimpleQsort(r, end, width, comparator, swapper); SimpleQsort(begin, l, width, comparator, swapper);
SimpleQsort(r, end, width, comparator, swapper);
} }
CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue, CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
@@ -1359,46 +1357,49 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
static BaseType ftype = key->value.type.base_type; static BaseType ftype = key->value.type.base_type;
if (type.struct_def->fixed) { if (type.struct_def->fixed) {
auto v = reinterpret_cast<VectorOfAny *>( auto v =
builder_.GetCurrentBufferPointer()); reinterpret_cast<VectorOfAny *>(builder_.GetCurrentBufferPointer());
SimpleQsort<uint8_t>(v->Data(), SimpleQsort<uint8_t>(
v->Data() + v->size() * type.struct_def->bytesize, v->Data(), v->Data() + v->size() * type.struct_def->bytesize,
type.struct_def->bytesize, type.struct_def->bytesize,
[](const uint8_t *a, const uint8_t *b) -> bool { [](const uint8_t *a, const uint8_t *b) -> bool {
return CompareType(a + offset, b + offset, ftype); return CompareType(a + offset, b + offset, ftype);
}, [&](uint8_t *a, uint8_t *b) { },
// FIXME: faster? [&](uint8_t *a, uint8_t *b) {
for (size_t i = 0; i < type.struct_def->bytesize; i++) { // FIXME: faster?
std::swap(a[i], b[i]); for (size_t i = 0; i < type.struct_def->bytesize; i++) {
} std::swap(a[i], b[i]);
}); }
});
} else { } else {
auto v = reinterpret_cast<Vector<Offset<Table>> *>( auto v = reinterpret_cast<Vector<Offset<Table>> *>(
builder_.GetCurrentBufferPointer()); builder_.GetCurrentBufferPointer());
// Here also can't use std::sort. We do have an iterator type for it, // Here also can't use std::sort. We do have an iterator type for it,
// but it is non-standard as it will dereference the offsets, and thus // but it is non-standard as it will dereference the offsets, and thus
// can't be used to swap elements. // can't be used to swap elements.
SimpleQsort<Offset<Table>>(v->data(), v->data() + v->size(), 1, SimpleQsort<Offset<Table>>(
[](const Offset<Table> *_a, const Offset<Table> *_b) -> bool { v->data(), v->data() + v->size(), 1,
// Indirect offset pointer to table pointer. [](const Offset<Table> *_a, const Offset<Table> *_b) -> bool {
auto a = reinterpret_cast<const uint8_t *>(_a) + // Indirect offset pointer to table pointer.
ReadScalar<uoffset_t>(_a); auto a = reinterpret_cast<const uint8_t *>(_a) +
auto b = reinterpret_cast<const uint8_t *>(_b) + ReadScalar<uoffset_t>(_a);
ReadScalar<uoffset_t>(_b); auto b = reinterpret_cast<const uint8_t *>(_b) +
// Fetch field address from table. ReadScalar<uoffset_t>(_b);
a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset); // Fetch field address from table.
b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset); a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset);
return CompareType(a, b, ftype); b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset);
}, [&](Offset<Table> *a, Offset<Table> *b) { return CompareType(a, b, ftype);
// These are serialized offsets, so are relative where they are },
// stored in memory, so compute the distance between these pointers: [&](Offset<Table> *a, Offset<Table> *b) {
ptrdiff_t diff = (b - a) * sizeof(Offset<Table>); // These are serialized offsets, so are relative where they are
assert(diff >= 0); // Guaranteed by SimpleQsort. // stored in memory, so compute the distance between these pointers:
auto udiff = static_cast<uoffset_t>(diff); ptrdiff_t diff = (b - a) * sizeof(Offset<Table>);
a->o = EndianScalar(ReadScalar<uoffset_t>(a) - udiff); assert(diff >= 0); // Guaranteed by SimpleQsort.
b->o = EndianScalar(ReadScalar<uoffset_t>(b) + udiff); auto udiff = static_cast<uoffset_t>(diff);
std::swap(*a, *b); a->o = EndianScalar(ReadScalar<uoffset_t>(a) - udiff);
}); b->o = EndianScalar(ReadScalar<uoffset_t>(b) + udiff);
std::swap(*a, *b);
});
} }
} }
return NoError(); return NoError();
@@ -1478,12 +1479,11 @@ CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field,
nested_parser.enums_.dict.clear(); nested_parser.enums_.dict.clear();
nested_parser.enums_.vec.clear(); nested_parser.enums_.vec.clear();
if (!ok) { if (!ok) { ECHECK(Error(nested_parser.error_)); }
ECHECK(Error(nested_parser.error_));
}
// Force alignment for nested flatbuffer // Force alignment for nested flatbuffer
builder_.ForceVectorAlignment(nested_parser.builder_.GetSize(), sizeof(uint8_t), builder_.ForceVectorAlignment(
nested_parser.builder_.GetBufferMinAlignment()); nested_parser.builder_.GetSize(), sizeof(uint8_t),
nested_parser.builder_.GetBufferMinAlignment());
auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(), auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(),
nested_parser.builder_.GetSize()); nested_parser.builder_.GetSize());
@@ -1499,7 +1499,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
auto name = attribute_; auto name = attribute_;
if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant))) if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant)))
return Error("attribute name must be either identifier or string: " + return Error("attribute name must be either identifier or string: " +
name); name);
if (known_attributes_.find(name) == known_attributes_.end()) if (known_attributes_.find(name) == known_attributes_.end())
return Error("user define attributes must be declared before use: " + return Error("user define attributes must be declared before use: " +
name); name);
@@ -1648,10 +1648,10 @@ template<typename T> inline void SingleValueRepack(Value &e, T val) {
} }
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Normilaze defaults NaN to unsigned quiet-NaN(0). // Normilaze defaults NaN to unsigned quiet-NaN(0).
static inline void SingleValueRepack(Value& e, float val) { static inline void SingleValueRepack(Value &e, float val) {
if (val != val) e.constant = "nan"; if (val != val) e.constant = "nan";
} }
static inline void SingleValueRepack(Value& e, double val) { static inline void SingleValueRepack(Value &e, double val) {
if (val != val) e.constant = "nan"; if (val != val) e.constant = "nan";
} }
#endif #endif
@@ -1774,7 +1774,7 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
"' to value of <" + std::string(kTypeNames[in_type]) + "> type."; "' to value of <" + std::string(kTypeNames[in_type]) + "> type.";
return Error(msg); return Error(msg);
} }
const auto match_type = e.type.base_type; // may differ from in_type const auto match_type = e.type.base_type; // may differ from in_type
// The check_now flag must be true when parse a fbs-schema. // The check_now flag must be true when parse a fbs-schema.
// This flag forces to check default scalar values or metadata of field. // This flag forces to check default scalar values or metadata of field.
// For JSON parser the flag should be false. // For JSON parser the flag should be false.
@@ -2210,11 +2210,10 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
bool Parser::SupportsAdvancedUnionFeatures() const { bool Parser::SupportsAdvancedUnionFeatures() const {
return opts.lang_to_generate != 0 && return opts.lang_to_generate != 0 &&
(opts.lang_to_generate & ~(IDLOptions::kCpp | IDLOptions::kJs | (opts.lang_to_generate &
IDLOptions::kTs | IDLOptions::kPhp | ~(IDLOptions::kCpp | IDLOptions::kJs | IDLOptions::kTs |
IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kPhp | IDLOptions::kJava | IDLOptions::kCSharp |
IDLOptions::kKotlin | IDLOptions::kKotlin | IDLOptions::kBinary)) == 0;
IDLOptions::kBinary)) == 0;
} }
bool Parser::SupportsAdvancedArrayFeatures() const { bool Parser::SupportsAdvancedArrayFeatures() const {
@@ -2486,8 +2485,8 @@ CheckedError Parser::StartEnum(const std::string &enum_name, bool is_union,
if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name), if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name),
&enum_def)) &enum_def))
return Error("enum already exists: " + enum_name); return Error("enum already exists: " + enum_name);
enum_def.underlying_type.base_type = is_union ? BASE_TYPE_UTYPE enum_def.underlying_type.base_type =
: BASE_TYPE_INT; is_union ? BASE_TYPE_UTYPE : BASE_TYPE_INT;
enum_def.underlying_type.enum_def = &enum_def; enum_def.underlying_type.enum_def = &enum_def;
if (dest) *dest = &enum_def; if (dest) *dest = &enum_def;
return NoError(); return NoError();
@@ -2623,8 +2622,8 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
if (oneof_type.base_type != BASE_TYPE_STRUCT || if (oneof_type.base_type != BASE_TYPE_STRUCT ||
!oneof_type.struct_def || oneof_type.struct_def->fixed) !oneof_type.struct_def || oneof_type.struct_def->fixed)
return Error("oneof '" + name + return Error("oneof '" + name +
"' cannot be mapped to a union because member '" + "' cannot be mapped to a union because member '" +
oneof_field.name + "' is not a table type."); oneof_field.name + "' is not a table type.");
EnumValBuilder evb(*this, *oneof_union); EnumValBuilder evb(*this, *oneof_union);
auto ev = evb.CreateEnumerator(oneof_type.struct_def->name); auto ev = evb.CreateEnumerator(oneof_type.struct_def->name);
ev->union_type = oneof_type; ev->union_type = oneof_type;
@@ -2989,9 +2988,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
// entered into included_files_. // entered into included_files_.
// This is recursive, but only go as deep as the number of include // This is recursive, but only go as deep as the number of include
// statements. // statements.
if (source_filename) { if (source_filename) { included_files_.erase(source_filename); }
included_files_.erase(source_filename);
}
return DoParse(source, include_paths, source_filename, return DoParse(source, include_paths, source_filename,
include_filename); include_filename);
} }
@@ -3015,9 +3012,9 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
uoffset_t toff; uoffset_t toff;
ECHECK(ParseTable(*root_struct_def_, nullptr, &toff)); ECHECK(ParseTable(*root_struct_def_, nullptr, &toff));
if (opts.size_prefixed) { if (opts.size_prefixed) {
builder_.FinishSizePrefixed(Offset<Table>(toff), file_identifier_.length() builder_.FinishSizePrefixed(
? file_identifier_.c_str() Offset<Table>(toff),
: nullptr); file_identifier_.length() ? file_identifier_.c_str() : nullptr);
} else { } else {
builder_.Finish(Offset<Table>(toff), file_identifier_.length() builder_.Finish(Offset<Table>(toff), file_identifier_.length()
? file_identifier_.c_str() ? file_identifier_.c_str()
@@ -3038,8 +3035,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
if (opts.root_type.empty()) { if (opts.root_type.empty()) {
if (!SetRootType(root_type.c_str())) if (!SetRootType(root_type.c_str()))
return Error("unknown root type: " + root_type); return Error("unknown root type: " + root_type);
if (root_struct_def_->fixed) if (root_struct_def_->fixed) return Error("root type must be a table");
return Error("root type must be a table");
} }
EXPECT(';'); EXPECT(';');
} else if (IsIdent("file_identifier")) { } else if (IsIdent("file_identifier")) {
@@ -3144,10 +3140,9 @@ void Parser::Serialize() {
auto fiid__ = builder_.CreateString(file_identifier_); auto fiid__ = builder_.CreateString(file_identifier_);
auto fext__ = builder_.CreateString(file_extension_); auto fext__ = builder_.CreateString(file_extension_);
auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets); auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets);
auto schema_offset = auto schema_offset = reflection::CreateSchema(
reflection::CreateSchema(builder_, objs__, enum__, fiid__, fext__, builder_, objs__, enum__, fiid__, fext__,
(root_struct_def_ ? root_struct_def_->serialized_location : 0), (root_struct_def_ ? root_struct_def_->serialized_location : 0), serv__);
serv__);
if (opts.size_prefixed) { if (opts.size_prefixed) {
builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier()); builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier());
} else { } else {
@@ -3193,22 +3188,20 @@ Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder,
auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets); auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateObject(*builder, name__, flds__, fixed, return reflection::CreateObject(*builder, name__, flds__, fixed,
static_cast<int>(minalign), static_cast<int>(minalign),
static_cast<int>(bytesize), static_cast<int>(bytesize), attr__, docs__);
attr__, docs__);
} }
bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
if (!DeserializeAttributes(parser, object->attributes())) if (!DeserializeAttributes(parser, object->attributes())) return false;
return false;
DeserializeDoc(doc_comment, object->documentation()); DeserializeDoc(doc_comment, object->documentation());
name = parser.UnqualifiedName(object->name()->str()); name = parser.UnqualifiedName(object->name()->str());
predecl = false; predecl = false;
sortbysize = attributes.Lookup("original_order") == nullptr && !fixed; sortbysize = attributes.Lookup("original_order") == nullptr && !fixed;
const auto& of = *(object->fields()); const auto &of = *(object->fields());
auto indexes = std::vector<uoffset_t>(of.size()); auto indexes = std::vector<uoffset_t>(of.size());
for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i; for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i;
size_t tmp_struct_size = 0; size_t tmp_struct_size = 0;
@@ -3224,9 +3217,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
// Recompute padding since that's currently not serialized. // Recompute padding since that's currently not serialized.
auto size = InlineSize(field_def->value.type); auto size = InlineSize(field_def->value.type);
auto next_field = auto next_field =
i + 1 < indexes.size() i + 1 < indexes.size() ? of.Get(indexes[i + 1]) : nullptr;
? of.Get(indexes[i+1])
: nullptr;
tmp_struct_size += size; tmp_struct_size += size;
field_def->padding = field_def->padding =
next_field ? (next_field->offset() - field_def->value.offset) - size next_field ? (next_field->offset() - field_def->value.offset) - size
@@ -3245,9 +3236,10 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
auto type__ = value.type.Serialize(builder); auto type__ = value.type.Serialize(builder);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateField(*builder, name__, type__, id, value.offset, return reflection::CreateField(
*builder, name__, type__, id, value.offset,
// Is uint64>max(int64) tested? // Is uint64>max(int64) tested?
IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0, IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
// result may be platform-dependent if underlying is float (not double) // result may be platform-dependent if underlying is float (not double)
@@ -3261,8 +3253,7 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) { bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
name = field->name()->str(); name = field->name()->str();
defined_namespace = parser.current_namespace_; defined_namespace = parser.current_namespace_;
if (!value.type.Deserialize(parser, field->type())) if (!value.type.Deserialize(parser, field->type())) return false;
return false;
value.offset = field->offset(); value.offset = field->offset();
if (IsInteger(value.type.base_type)) { if (IsInteger(value.type.base_type)) {
value.constant = NumToString(field->default_integer()); value.constant = NumToString(field->default_integer());
@@ -3276,8 +3267,7 @@ bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
deprecated = field->deprecated(); deprecated = field->deprecated();
required = field->required(); required = field->required();
key = field->key(); key = field->key();
if (!DeserializeAttributes(parser, field->attributes())) if (!DeserializeAttributes(parser, field->attributes())) return false;
return false;
// TODO: this should probably be handled by a separate attribute // TODO: this should probably be handled by a separate attribute
if (attributes.Lookup("flexbuffer")) { if (attributes.Lookup("flexbuffer")) {
flexbuffer = true; flexbuffer = true;
@@ -3301,18 +3291,16 @@ Offset<reflection::RPCCall> RPCCall::Serialize(FlatBufferBuilder *builder,
auto name__ = builder->CreateString(name); auto name__ = builder->CreateString(name);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateRPCCall(*builder, name__, return reflection::CreateRPCCall(
request->serialized_location, *builder, name__, request->serialized_location,
response->serialized_location, response->serialized_location, attr__, docs__);
attr__, docs__);
} }
bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) { bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) {
name = call->name()->str(); name = call->name()->str();
if (!DeserializeAttributes(parser, call->attributes())) if (!DeserializeAttributes(parser, call->attributes())) return false;
return false;
DeserializeDoc(doc_comment, call->documentation()); DeserializeDoc(doc_comment, call->documentation());
request = parser.structs_.Lookup(call->request()->name()->str()); request = parser.structs_.Lookup(call->request()->name()->str());
response = parser.structs_.Lookup(call->response()->name()->str()); response = parser.structs_.Lookup(call->response()->name()->str());
@@ -3331,8 +3319,8 @@ Offset<reflection::Service> ServiceDef::Serialize(FlatBufferBuilder *builder,
auto call__ = builder->CreateVector(servicecall_offsets); auto call__ = builder->CreateVector(servicecall_offsets);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateService(*builder, name__, call__, attr__, docs__); return reflection::CreateService(*builder, name__, call__, attr__, docs__);
} }
@@ -3349,8 +3337,7 @@ bool ServiceDef::Deserialize(Parser &parser,
} }
} }
} }
if (!DeserializeAttributes(parser, service->attributes())) if (!DeserializeAttributes(parser, service->attributes())) return false;
return false;
DeserializeDoc(doc_comment, service->documentation()); DeserializeDoc(doc_comment, service->documentation());
return true; return true;
} }
@@ -3367,8 +3354,8 @@ Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder,
auto type__ = underlying_type.Serialize(builder); auto type__ = underlying_type.Serialize(builder);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateEnum(*builder, name__, vals__, is_union, type__, return reflection::CreateEnum(*builder, name__, vals__, is_union, type__,
attr__, docs__); attr__, docs__);
} }
@@ -3387,8 +3374,7 @@ bool EnumDef::Deserialize(Parser &parser, const reflection::Enum *_enum) {
if (!underlying_type.Deserialize(parser, _enum->underlying_type())) { if (!underlying_type.Deserialize(parser, _enum->underlying_type())) {
return false; return false;
} }
if (!DeserializeAttributes(parser, _enum->attributes())) if (!DeserializeAttributes(parser, _enum->attributes())) return false;
return false;
DeserializeDoc(doc_comment, _enum->documentation()); DeserializeDoc(doc_comment, _enum->documentation());
return true; return true;
} }
@@ -3398,9 +3384,10 @@ Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder,
auto name__ = builder->CreateString(name); auto name__ = builder->CreateString(name);
auto type__ = union_type.Serialize(builder); auto type__ = union_type.Serialize(builder);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateEnumVal(*builder, name__, value, return reflection::CreateEnumVal(
*builder, name__, value,
union_type.struct_def ? union_type.struct_def->serialized_location : 0, union_type.struct_def ? union_type.struct_def->serialized_location : 0,
type__, docs__); type__, docs__);
} }
@@ -3409,8 +3396,7 @@ bool EnumVal::Deserialize(const Parser &parser,
const reflection::EnumVal *val) { const reflection::EnumVal *val) {
name = val->name()->str(); name = val->name()->str();
value = val->value(); value = val->value();
if (!union_type.Deserialize(parser, val->union_type())) if (!union_type.Deserialize(parser, val->union_type())) return false;
return false;
DeserializeDoc(doc_comment, val->documentation()); DeserializeDoc(doc_comment, val->documentation());
return true; return true;
} }
@@ -3432,8 +3418,7 @@ bool Type::Deserialize(const Parser &parser, const reflection::Type *type) {
bool is_series = type->base_type() == reflection::Vector || bool is_series = type->base_type() == reflection::Vector ||
type->base_type() == reflection::Array; type->base_type() == reflection::Array;
if (type->base_type() == reflection::Obj || if (type->base_type() == reflection::Obj ||
(is_series && (is_series && type->element() == reflection::Obj)) {
type->element() == reflection::Obj)) {
if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) { if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) {
struct_def = parser.structs_.vec[type->index()]; struct_def = parser.structs_.vec[type->index()];
struct_def->refcount++; struct_def->refcount++;
@@ -3474,8 +3459,7 @@ Definition::SerializeAttributes(FlatBufferBuilder *builder,
bool Definition::DeserializeAttributes( bool Definition::DeserializeAttributes(
Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) { Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) {
if (attrs == nullptr) if (attrs == nullptr) return true;
return true;
for (uoffset_t i = 0; i < attrs->size(); ++i) { for (uoffset_t i = 0; i < attrs->size(); ++i) {
auto kv = attrs->Get(i); auto kv = attrs->Get(i);
auto value = new Value(); auto value = new Value();
@@ -3495,7 +3479,7 @@ bool Definition::DeserializeAttributes(
bool Parser::Deserialize(const uint8_t *buf, const size_t size) { bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t *>(buf), size); flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t *>(buf), size);
bool size_prefixed = false; bool size_prefixed = false;
if(!reflection::SchemaBufferHasIdentifier(buf)) { if (!reflection::SchemaBufferHasIdentifier(buf)) {
if (!flatbuffers::BufferHasIdentifier(buf, reflection::SchemaIdentifier(), if (!flatbuffers::BufferHasIdentifier(buf, reflection::SchemaIdentifier(),
true)) true))
return false; return false;
@@ -3504,9 +3488,7 @@ bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
} }
auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer
: &reflection::VerifySchemaBuffer; : &reflection::VerifySchemaBuffer;
if (!verify_fn(verifier)) { if (!verify_fn(verifier)) { return false; }
return false;
}
auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf) auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf)
: reflection::GetSchema(buf); : reflection::GetSchema(buf);
return Deserialize(schema); return Deserialize(schema);
@@ -3555,7 +3537,7 @@ bool Parser::Deserialize(const reflection::Schema *schema) {
auto struct_def = structs_.Lookup(qualified_name); auto struct_def = structs_.Lookup(qualified_name);
struct_def->defined_namespace = struct_def->defined_namespace =
GetNamespace(qualified_name, namespaces_, namespaces_index); GetNamespace(qualified_name, namespaces_, namespaces_index);
if (!struct_def->Deserialize(*this, * it)) { return false; } if (!struct_def->Deserialize(*this, *it)) { return false; }
if (schema->root_table() == *it) { root_struct_def_ = struct_def; } if (schema->root_table() == *it) { root_struct_def_ = struct_def; }
} }
for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) { for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) {

View File

@@ -15,6 +15,7 @@
*/ */
#include "flatbuffers/reflection.h" #include "flatbuffers/reflection.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
// Helper functionality for reflection. // Helper functionality for reflection.
@@ -431,8 +432,8 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
break; break;
} }
} }
FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
default: { // Scalars and structs. default: { // Scalars and structs.
auto element_size = GetTypeSize(element_base_type); auto element_size = GetTypeSize(element_base_type);
if (elemobjectdef && elemobjectdef->is_struct()) if (elemobjectdef && elemobjectdef->is_struct())
element_size = elemobjectdef->bytesize(); element_size = elemobjectdef->bytesize();
@@ -466,7 +467,7 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
break; break;
} }
} }
FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case reflection::Union: case reflection::Union:
case reflection::String: case reflection::String:
case reflection::Vector: case reflection::Vector:
@@ -495,9 +496,8 @@ bool VerifyStruct(flatbuffers::Verifier &v,
auto offset = parent_table.GetOptionalFieldOffset(field_offset); auto offset = parent_table.GetOptionalFieldOffset(field_offset);
if (required && !offset) { return false; } if (required && !offset) { return false; }
return !offset || return !offset || v.Verify(reinterpret_cast<const uint8_t *>(&parent_table),
v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), offset, offset, obj.bytesize());
obj.bytesize());
} }
bool VerifyVectorOfStructs(flatbuffers::Verifier &v, bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
@@ -535,9 +535,8 @@ bool VerifyUnion(flatbuffers::Verifier &v, const reflection::Schema &schema,
} }
case reflection::String: case reflection::String:
return v.VerifyString( return v.VerifyString(
reinterpret_cast<const flatbuffers::String *>(elem)); reinterpret_cast<const flatbuffers::String *>(elem));
default: default: return false;
return false;
} }
} }
@@ -597,27 +596,24 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
} }
} }
case reflection::Union: { case reflection::Union: {
auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(table, auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(
vec_field); table, vec_field);
if (!v.VerifyVector(vec)) return false; if (!v.VerifyVector(vec)) return false;
if (!vec) return true; if (!vec) return true;
auto type_vec = table.GetPointer<Vector<uint8_t> *> auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() -
(vec_field.offset() - sizeof(voffset_t)); sizeof(voffset_t));
if (!v.VerifyVector(type_vec)) return false; if (!v.VerifyVector(type_vec)) return false;
for (uoffset_t j = 0; j < vec->size(); j++) { for (uoffset_t j = 0; j < vec->size(); j++) {
// get union type from the prev field // get union type from the prev field
auto utype = type_vec->Get(j); auto utype = type_vec->Get(j);
auto elem = vec->Get(j); auto elem = vec->Get(j);
if (!VerifyUnion(v, schema, utype, elem, vec_field)) if (!VerifyUnion(v, schema, utype, elem, vec_field)) return false;
return false;
} }
return true; return true;
} }
case reflection::Vector: case reflection::Vector:
case reflection::None: case reflection::None:
default: default: FLATBUFFERS_ASSERT(false); return false;
FLATBUFFERS_ASSERT(false);
return false;
} }
} }
@@ -663,8 +659,7 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
} }
break; break;
case reflection::Vector: case reflection::Vector:
if (!VerifyVector(v, schema, *table, *field_def)) if (!VerifyVector(v, schema, *table, *field_def)) return false;
return false;
break; break;
case reflection::Obj: { case reflection::Obj: {
auto child_obj = schema.objects()->Get(field_def->type()->index()); auto child_obj = schema.objects()->Get(field_def->type()->index());
@@ -687,15 +682,11 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
voffset_t utype_offset = field_def->offset() - sizeof(voffset_t); voffset_t utype_offset = field_def->offset() - sizeof(voffset_t);
auto utype = table->GetField<uint8_t>(utype_offset, 0); auto utype = table->GetField<uint8_t>(utype_offset, 0);
auto uval = reinterpret_cast<const uint8_t *>( auto uval = reinterpret_cast<const uint8_t *>(
flatbuffers::GetFieldT(*table, *field_def)); flatbuffers::GetFieldT(*table, *field_def));
if (!VerifyUnion(v, schema, utype, uval, *field_def)) { if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; }
return false;
}
break; break;
} }
default: default: FLATBUFFERS_ASSERT(false); break;
FLATBUFFERS_ASSERT(false);
break;
} }
} }

View File

@@ -242,9 +242,9 @@ bool SetGlobalTestLocale(const char *locale_name, std::string *_value) {
} }
bool ReadEnvironmentVariable(const char *var_name, std::string *_value) { bool ReadEnvironmentVariable(const char *var_name, std::string *_value) {
#ifdef _MSC_VER #ifdef _MSC_VER
__pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS __pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS
#endif #endif
auto env_str = std::getenv(var_name); auto env_str = std::getenv(var_name);
if (!env_str) return false; if (!env_str) return false;
if (_value) *_value = std::string(env_str); if (_value) *_value = std::string(env_str);

View File

@@ -1,13 +1,13 @@
#include "native_type_test_impl.h" #include "native_type_test_impl.h"
#include "native_type_test_generated.h" #include "native_type_test_generated.h"
namespace flatbuffers { namespace flatbuffers {
Geometry::Vector3D Pack(const Native::Vector3D &obj) { Geometry::Vector3D Pack(const Native::Vector3D &obj) {
return Geometry::Vector3D(obj.x, obj.y, obj.z); return Geometry::Vector3D(obj.x, obj.y, obj.z);
}
const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
return Native::Vector3D(obj.x(), obj.y(), obj.z());
}
} }
const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
return Native::Vector3D(obj.x(), obj.y(), obj.z());
}
} // namespace flatbuffers

View File

@@ -2,23 +2,31 @@
#define NATIVE_TYPE_TEST_IMPL_H #define NATIVE_TYPE_TEST_IMPL_H
namespace Native { namespace Native {
struct Vector3D { struct Vector3D {
float x; float x;
float y; float y;
float z; float z;
Vector3D() { x = 0; y = 0; z = 0; }; Vector3D() {
Vector3D(float _x, float _y, float _z) { this->x = _x; this->y = _y; this->z = _z; } x = 0;
y = 0;
z = 0;
}; };
} Vector3D(float _x, float _y, float _z) {
this->x = _x;
this->y = _y;
this->z = _z;
}
};
} // namespace Native
namespace Geometry { namespace Geometry {
struct Vector3D; struct Vector3D;
} }
namespace flatbuffers { namespace flatbuffers {
Geometry::Vector3D Pack(const Native::Vector3D &obj); Geometry::Vector3D Pack(const Native::Vector3D &obj);
const Native::Vector3D UnPack(const Geometry::Vector3D &obj); const Native::Vector3D UnPack(const Geometry::Vector3D &obj);
} } // namespace flatbuffers
#endif // VECTOR3D_PACK_H #endif // VECTOR3D_PACK_H

View File

@@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include <cmath> #include <cmath>
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/minireflect.h" #include "flatbuffers/minireflect.h"
@@ -35,7 +36,7 @@
#include "union_vector/union_vector_generated.h" #include "union_vector/union_vector_generated.h"
#include "monster_extra_generated.h" #include "monster_extra_generated.h"
#if !defined(_MSC_VER) || _MSC_VER >= 1700 #if !defined(_MSC_VER) || _MSC_VER >= 1700
#include "arrays_test_generated.h" # include "arrays_test_generated.h"
#endif #endif
#include "native_type_test_generated.h" #include "native_type_test_generated.h"
@@ -43,7 +44,6 @@
#include "flatbuffers/flexbuffers.h" #include "flatbuffers/flexbuffers.h"
// clang-format off // clang-format off
// Check that char* and uint8_t* are interoperable types. // Check that char* and uint8_t* are interoperable types.
// The reinterpret_cast<> between the pointers are used to simplify data loading. // The reinterpret_cast<> between the pointers are used to simplify data loading.
@@ -72,7 +72,8 @@ void FlatBufferBuilderTest();
// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator // http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
uint32_t lcg_seed = 48271; uint32_t lcg_seed = 48271;
uint32_t lcg_rand() { uint32_t lcg_rand() {
return lcg_seed = (static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL; return lcg_seed =
(static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL;
} }
void lcg_reset() { lcg_seed = 48271; } void lcg_reset() { lcg_seed = 48271; }
@@ -200,14 +201,13 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2); auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2);
// shortcut for creating monster with all fields set: // shortcut for creating monster with all fields set:
auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue, auto mloc = CreateMonster(
Any_Monster, mlocs[1].Union(), // Store a union. builder, &vec, 150, 80, name, inventory, Color_Blue, Any_Monster,
testv, vecofstrings, vecoftables, 0, mlocs[1].Union(), // Store a union.
nested_flatbuffer_vector, 0, false, 0, 0, 0, 0, 0, testv, vecofstrings, vecoftables, 0, nested_flatbuffer_vector, 0, false,
0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2,
vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0, vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, AnyUniqueAliases_NONE, 0, AnyUniqueAliases_NONE, 0, AnyAmbiguousAliases_NONE, 0, vecofcolors);
AnyAmbiguousAliases_NONE, 0, vecofcolors);
FinishMonsterBuffer(builder, mloc); FinishMonsterBuffer(builder, mloc);
@@ -567,8 +567,7 @@ void SizePrefixedTest() {
// Create size prefixed buffer. // Create size prefixed buffer.
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
FinishSizePrefixedMonsterBuffer( FinishSizePrefixedMonsterBuffer(
fbb, fbb, CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
// Verify it. // Verify it.
flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize()); flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
@@ -598,7 +597,8 @@ void JsonDefaultTest() {
// load FlatBuffer schema (.fbs) from disk // load FlatBuffer schema (.fbs) from disk
std::string schemafile; std::string schemafile;
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(), TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
false, &schemafile), true); false, &schemafile),
true);
// parse schema first, so we can use it to parse the data after // parse schema first, so we can use it to parse the data after
flatbuffers::Parser parser; flatbuffers::Parser parser;
auto include_test_path = auto include_test_path =
@@ -771,7 +771,7 @@ void ParseAndGenerateTextTest(bool binary) {
true); true);
auto include_test_path = auto include_test_path =
flatbuffers::ConCatPathFileName(test_data_path, "include_test"); flatbuffers::ConCatPathFileName(test_data_path, "include_test");
const char *include_directories[] = { test_data_path.c_str(), const char *include_directories[] = { test_data_path.c_str(),
include_test_path.c_str(), nullptr }; include_test_path.c_str(), nullptr };
@@ -782,8 +782,10 @@ void ParseAndGenerateTextTest(bool binary) {
reinterpret_cast<const uint8_t *>(schemafile.c_str()), reinterpret_cast<const uint8_t *>(schemafile.c_str()),
schemafile.size()); schemafile.size());
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true); TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
//auto schema = reflection::GetSchema(schemafile.c_str()); // auto schema = reflection::GetSchema(schemafile.c_str());
TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(), schemafile.size()), true); TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(),
schemafile.size()),
true);
} else { } else {
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true); TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
} }
@@ -1029,7 +1031,8 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
} }
void MiniReflectFlatBuffersTest(uint8_t *flatbuf) { void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
auto s = flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable()); auto s =
flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
TEST_EQ_STR( TEST_EQ_STR(
s.c_str(), s.c_str(),
"{ " "{ "
@@ -1060,15 +1063,15 @@ void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
"}"); "}");
Test test(16, 32); Test test(16, 32);
Vec3 vec(1,2,3, 1.5, Color_Red, test); Vec3 vec(1, 2, 3, 1.5, Color_Red, test);
flatbuffers::FlatBufferBuilder vec_builder; flatbuffers::FlatBufferBuilder vec_builder;
vec_builder.Finish(vec_builder.CreateStruct(vec)); vec_builder.Finish(vec_builder.CreateStruct(vec));
auto vec_buffer = vec_builder.Release(); auto vec_buffer = vec_builder.Release();
auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(), auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(),
Vec3::MiniReflectTypeTable()); Vec3::MiniReflectTypeTable());
TEST_EQ_STR( TEST_EQ_STR(vec_str.c_str(),
vec_str.c_str(), "{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: "
"{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: 16, b: 32 } }"); "16, b: 32 } }");
} }
// Parse a .proto schema, output as .fbs // Parse a .proto schema, output as .fbs
@@ -1085,11 +1088,10 @@ void ParseProtoTest() {
flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(), flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(),
false, &goldenfile), false, &goldenfile),
true); true);
TEST_EQ( TEST_EQ(flatbuffers::LoadFile(
flatbuffers::LoadFile((test_data_path + (test_data_path + "prototest/test_union.golden").c_str(), false,
"prototest/test_union.golden").c_str(), &goldenunionfile),
false, &goldenunionfile), true);
true);
flatbuffers::IDLOptions opts; flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false; opts.include_dependence_headers = false;
@@ -1526,9 +1528,9 @@ bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
// Additional parser testing not covered elsewhere. // Additional parser testing not covered elsewhere.
void ValueTest() { void ValueTest() {
// Test scientific notation numbers. // Test scientific notation numbers.
TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), TEST_EQ(
3.14159f), FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), 3.14159f),
true); true);
// number in string // number in string
TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"), TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"),
3.14159f), 3.14159f),
@@ -1566,7 +1568,6 @@ void ValueTest() {
// check comments before and after json object // check comments before and after json object
TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1); TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1);
TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1); TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1);
} }
void NestedListTest() { void NestedListTest() {
@@ -1608,8 +1609,8 @@ void EnumNamesTest() {
// For details see C++17 standard or explanation on the SO: // For details see C++17 standard or explanation on the SO:
// stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class // stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(0))); TEST_EQ_STR("", EnumNameColor(static_cast<Color>(0)));
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY-1))); TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY - 1)));
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY+1))); TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY + 1)));
} }
void EnumOutOfRangeTest() { void EnumOutOfRangeTest() {
@@ -1629,12 +1630,14 @@ void EnumOutOfRangeTest() {
TestError("enum X:uint { Y = -1 }", "enum value does not fit"); TestError("enum X:uint { Y = -1 }", "enum value does not fit");
TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit"); TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit");
TestError("enum X:long { Y = 9223372036854775808 }", "does not fit"); TestError("enum X:long { Y = 9223372036854775808 }", "does not fit");
TestError("enum X:long { Y = 9223372036854775807, Z }", "enum value does not fit"); TestError("enum X:long { Y = 9223372036854775807, Z }",
"enum value does not fit");
TestError("enum X:ulong { Y = -1 }", "does not fit"); TestError("enum X:ulong { Y = -1 }", "does not fit");
TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out"); TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out");
TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128 TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128
// bit_flgs out of range // bit_flgs out of range
TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }", "out of range"); TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }",
"out of range");
} }
void EnumValueTest() { void EnumValueTest() {
@@ -1734,11 +1737,12 @@ void IntegerOutOfRangeTest() {
void IntegerBoundaryTest() { void IntegerBoundaryTest() {
// Check numerical compatibility with non-C++ languages. // Check numerical compatibility with non-C++ languages.
// By the C++ standard, std::numerical_limits<int64_t>::min() == -9223372036854775807 (-2^63+1) or less* // By the C++ standard, std::numerical_limits<int64_t>::min() ==
// The Flatbuffers grammar and most of the languages (C#, Java, Rust) expect // -9223372036854775807 (-2^63+1) or less* The Flatbuffers grammar and most of
// that minimum values are: -128, -32768,.., -9223372036854775808. // the languages (C#, Java, Rust) expect that minimum values are: -128,
// Since C++20, static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement cast. // -32768,.., -9223372036854775808. Since C++20,
// Therefore -9223372036854775808 should be valid negative value. // static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement
// cast. Therefore -9223372036854775808 should be valid negative value.
TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128); TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128);
TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127); TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127);
TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768); TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768);
@@ -1810,11 +1814,11 @@ void ValidFloatTest() {
TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f); TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f);
TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f); TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f);
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Old MSVC versions may have problem with this check. // Old MSVC versions may have problem with this check.
// https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/ // https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"), TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"),
6929495644600920.0); 6929495644600920.0);
// check nan's // check nan's
TEST_EQ(std::isnan(TestValue<double>("{ Y:nan }", "double")), true); TEST_EQ(std::isnan(TestValue<double>("{ Y:nan }", "double")), true);
TEST_EQ(std::isnan(TestValue<float>("{ Y:nan }", "float")), true); TEST_EQ(std::isnan(TestValue<float>("{ Y:nan }", "float")), true);
@@ -1936,8 +1940,8 @@ void GenerateTableTextTest() {
TEST_EQ(ok, true); TEST_EQ(ok, true);
auto include_test_path = auto include_test_path =
flatbuffers::ConCatPathFileName(test_data_path, "include_test"); flatbuffers::ConCatPathFileName(test_data_path, "include_test");
const char *include_directories[] = {test_data_path.c_str(), const char *include_directories[] = { test_data_path.c_str(),
include_test_path.c_str(), nullptr}; include_test_path.c_str(), nullptr };
flatbuffers::IDLOptions opt; flatbuffers::IDLOptions opt;
opt.indent_step = -1; opt.indent_step = -1;
flatbuffers::Parser parser(opt); flatbuffers::Parser parser(opt);
@@ -2237,7 +2241,7 @@ void InvalidUTF8Test() {
// Check independence of identifier from locale. // Check independence of identifier from locale.
std::string locale_ident; std::string locale_ident;
locale_ident += "table T { F"; locale_ident += "table T { F";
locale_ident += static_cast<char>(-32); // unsigned 0xE0 locale_ident += static_cast<char>(-32); // unsigned 0xE0
locale_ident += " :string; }"; locale_ident += " :string; }";
locale_ident += "root_type T;"; locale_ident += "root_type T;";
locale_ident += "{}"; locale_ident += "{}";
@@ -2311,8 +2315,8 @@ void UnionVectorTest() {
// load FlatBuffer fbs schema and json. // load FlatBuffer fbs schema and json.
std::string schemafile, jsonfile; std::string schemafile, jsonfile;
TEST_EQ(flatbuffers::LoadFile( TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "union_vector/union_vector.fbs").c_str(), (test_data_path + "union_vector/union_vector.fbs").c_str(), false,
false, &schemafile), &schemafile),
true); true);
TEST_EQ(flatbuffers::LoadFile( TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "union_vector/union_vector.json").c_str(), (test_data_path + "union_vector/union_vector.json").c_str(),
@@ -2420,70 +2424,67 @@ void UnionVectorTest() {
"characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, " "characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, "
"{ books_read: 2 }, \"Other\", \"Unused\" ] }"); "{ books_read: 2 }, \"Other\", \"Unused\" ] }");
flatbuffers::ToStringVisitor visitor("\n", true, " "); flatbuffers::ToStringVisitor visitor("\n", true, " ");
IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor); IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor);
TEST_EQ_STR( TEST_EQ_STR(visitor.s.c_str(),
visitor.s.c_str(), "{\n"
"{\n" " \"main_character_type\": \"Rapunzel\",\n"
" \"main_character_type\": \"Rapunzel\",\n" " \"main_character\": {\n"
" \"main_character\": {\n" " \"hair_length\": 6\n"
" \"hair_length\": 6\n" " },\n"
" },\n" " \"characters_type\": [\n"
" \"characters_type\": [\n" " \"Belle\",\n"
" \"Belle\",\n" " \"MuLan\",\n"
" \"MuLan\",\n" " \"BookFan\",\n"
" \"BookFan\",\n" " \"Other\",\n"
" \"Other\",\n" " \"Unused\"\n"
" \"Unused\"\n" " ],\n"
" ],\n" " \"characters\": [\n"
" \"characters\": [\n" " {\n"
" {\n" " \"books_read\": 7\n"
" \"books_read\": 7\n" " },\n"
" },\n" " {\n"
" {\n" " \"sword_attack_damage\": 5\n"
" \"sword_attack_damage\": 5\n" " },\n"
" },\n" " {\n"
" {\n" " \"books_read\": 2\n"
" \"books_read\": 2\n" " },\n"
" },\n" " \"Other\",\n"
" \"Other\",\n" " \"Unused\"\n"
" \"Unused\"\n" " ]\n"
" ]\n" "}");
"}");
// Generate text using parsed schema. // Generate text using parsed schema.
std::string jsongen; std::string jsongen;
auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen); auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen);
TEST_EQ(result, true); TEST_EQ(result, true);
TEST_EQ_STR( TEST_EQ_STR(jsongen.c_str(),
jsongen.c_str(), "{\n"
"{\n" " main_character_type: \"Rapunzel\",\n"
" main_character_type: \"Rapunzel\",\n" " main_character: {\n"
" main_character: {\n" " hair_length: 6\n"
" hair_length: 6\n" " },\n"
" },\n" " characters_type: [\n"
" characters_type: [\n" " \"Belle\",\n"
" \"Belle\",\n" " \"MuLan\",\n"
" \"MuLan\",\n" " \"BookFan\",\n"
" \"BookFan\",\n" " \"Other\",\n"
" \"Other\",\n" " \"Unused\"\n"
" \"Unused\"\n" " ],\n"
" ],\n" " characters: [\n"
" characters: [\n" " {\n"
" {\n" " books_read: 7\n"
" books_read: 7\n" " },\n"
" },\n" " {\n"
" {\n" " sword_attack_damage: 5\n"
" sword_attack_damage: 5\n" " },\n"
" },\n" " {\n"
" {\n" " books_read: 2\n"
" books_read: 2\n" " },\n"
" },\n" " \"Other\",\n"
" \"Other\",\n" " \"Unused\"\n"
" \"Unused\"\n" " ]\n"
" ]\n" "}\n");
"}\n");
// Simple test with reflection. // Simple test with reflection.
parser.Serialize(); parser.Serialize();
@@ -2496,7 +2497,8 @@ void UnionVectorTest() {
TEST_EQ(parser2.Parse("struct Bool { b:bool; }" TEST_EQ(parser2.Parse("struct Bool { b:bool; }"
"union Any { Bool }" "union Any { Bool }"
"table Root { a:Any; }" "table Root { a:Any; }"
"root_type Root;"), true); "root_type Root;"),
true);
TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true); TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true);
} }
@@ -2703,7 +2705,7 @@ void TypeAliasesTest() {
TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max()); TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max());
TEST_EQ(ta->f32(), 2.3f); TEST_EQ(ta->f32(), 2.3f);
TEST_EQ(ta->f64(), 2.3); TEST_EQ(ta->f64(), 2.3);
using namespace flatbuffers; // is_same using namespace flatbuffers; // is_same
static_assert(is_same<decltype(ta->i8()), int8_t>::value, "invalid type"); static_assert(is_same<decltype(ta->i8()), int8_t>::value, "invalid type");
static_assert(is_same<decltype(ta->i16()), int16_t>::value, "invalid type"); static_assert(is_same<decltype(ta->i16()), int16_t>::value, "invalid type");
static_assert(is_same<decltype(ta->i32()), int32_t>::value, "invalid type"); static_assert(is_same<decltype(ta->i32()), int32_t>::value, "invalid type");
@@ -2729,14 +2731,16 @@ void UninitializedVectorTest() {
flatbuffers::FlatBufferBuilder builder; flatbuffers::FlatBufferBuilder builder;
Test *buf = nullptr; Test *buf = nullptr;
auto vector_offset = builder.CreateUninitializedVectorOfStructs<Test>(2, &buf); auto vector_offset =
builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
TEST_NOTNULL(buf); TEST_NOTNULL(buf);
buf[0] = Test(10, 20); buf[0] = Test(10, 20);
buf[1] = Test(30, 40); buf[1] = Test(30, 40);
auto required_name = builder.CreateString("myMonster"); auto required_name = builder.CreateString("myMonster");
auto monster_builder = MonsterBuilder(builder); auto monster_builder = MonsterBuilder(builder);
monster_builder.add_name(required_name); // required field mandated for monster. monster_builder.add_name(
required_name); // required field mandated for monster.
monster_builder.add_test4(vector_offset); monster_builder.add_test4(vector_offset);
builder.Finish(monster_builder.Finish()); builder.Finish(monster_builder.Finish());
@@ -2781,11 +2785,11 @@ void EqualOperatorTest() {
// For testing any binaries, e.g. from fuzzing. // For testing any binaries, e.g. from fuzzing.
void LoadVerifyBinaryTest() { void LoadVerifyBinaryTest() {
std::string binary; std::string binary;
if (flatbuffers::LoadFile((test_data_path + if (flatbuffers::LoadFile(
"fuzzer/your-filename-here").c_str(), (test_data_path + "fuzzer/your-filename-here").c_str(), true,
true, &binary)) { &binary)) {
flatbuffers::Verifier verifier( flatbuffers::Verifier verifier(
reinterpret_cast<const uint8_t *>(binary.data()), binary.size()); reinterpret_cast<const uint8_t *>(binary.data()), binary.size());
TEST_EQ(VerifyMonsterBuffer(verifier), true); TEST_EQ(VerifyMonsterBuffer(verifier), true);
} }
} }
@@ -2801,24 +2805,28 @@ void CreateSharedStringTest() {
TEST_EQ(onetwo.o != two.o, true); TEST_EQ(onetwo.o != two.o, true);
// Support for embedded nulls // Support for embedded nulls
const char chars_b[] = {'a', '\0', 'b'}; const char chars_b[] = { 'a', '\0', 'b' };
const char chars_c[] = {'a', '\0', 'c'}; const char chars_c[] = { 'a', '\0', 'c' };
const auto null_b1 = builder.CreateSharedString(chars_b, sizeof(chars_b)); const auto null_b1 = builder.CreateSharedString(chars_b, sizeof(chars_b));
const auto null_c = builder.CreateSharedString(chars_c, sizeof(chars_c)); const auto null_c = builder.CreateSharedString(chars_c, sizeof(chars_c));
const auto null_b2 = builder.CreateSharedString(chars_b, sizeof(chars_b)); const auto null_b2 = builder.CreateSharedString(chars_b, sizeof(chars_b));
TEST_EQ(null_b1.o != null_c.o, true); // Issue#5058 repro TEST_EQ(null_b1.o != null_c.o, true); // Issue#5058 repro
TEST_EQ(null_b1.o, null_b2.o); TEST_EQ(null_b1.o, null_b2.o);
// Put the strings into an array for round trip verification. // Put the strings into an array for round trip verification.
const flatbuffers::Offset<flatbuffers::String> array[7] = { one1, two, one2, onetwo, null_b1, null_c, null_b2 }; const flatbuffers::Offset<flatbuffers::String> array[7] = {
const auto vector_offset = builder.CreateVector(array, flatbuffers::uoffset_t(7)); one1, two, one2, onetwo, null_b1, null_c, null_b2
};
const auto vector_offset =
builder.CreateVector(array, flatbuffers::uoffset_t(7));
MonsterBuilder monster_builder(builder); MonsterBuilder monster_builder(builder);
monster_builder.add_name(two); monster_builder.add_name(two);
monster_builder.add_testarrayofstring(vector_offset); monster_builder.add_testarrayofstring(vector_offset);
builder.Finish(monster_builder.Finish()); builder.Finish(monster_builder.Finish());
// Read the Monster back. // Read the Monster back.
const auto *monster = flatbuffers::GetRoot<Monster>(builder.GetBufferPointer()); const auto *monster =
flatbuffers::GetRoot<Monster>(builder.GetBufferPointer());
TEST_EQ_STR(monster->name()->c_str(), "two"); TEST_EQ_STR(monster->name()->c_str(), "two");
const auto *testarrayofstring = monster->testarrayofstring(); const auto *testarrayofstring = monster->testarrayofstring();
TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7)); TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7));
@@ -2831,7 +2839,8 @@ void CreateSharedStringTest() {
TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c)))); TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c))));
TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b)))); TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b))));
// Make sure String::operator< works, too, since it is related to StringOffsetCompare. // Make sure String::operator< works, too, since it is related to
// StringOffsetCompare.
TEST_EQ((*a[0]) < (*a[1]), true); TEST_EQ((*a[0]) < (*a[1]), true);
TEST_EQ((*a[1]) < (*a[0]), false); TEST_EQ((*a[1]) < (*a[0]), false);
TEST_EQ((*a[1]) < (*a[2]), false); TEST_EQ((*a[1]) < (*a[2]), false);
@@ -2943,16 +2952,17 @@ void NativeTypeTest() {
src_data.vectors.reserve(N); src_data.vectors.reserve(N);
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
src_data.vectors.push_back (Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f)); src_data.vectors.push_back(
Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f));
} }
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data)); fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data));
auto dstDataT = Geometry::UnPackApplicationData(fbb.GetBufferPointer()); auto dstDataT = Geometry::UnPackApplicationData(fbb.GetBufferPointer());
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
Native::Vector3D& v = dstDataT->vectors[i]; Native::Vector3D &v = dstDataT->vectors[i];
TEST_EQ(v.x, 10 * i + 0.1f); TEST_EQ(v.x, 10 * i + 0.1f);
TEST_EQ(v.y, 10 * i + 0.2f); TEST_EQ(v.y, 10 * i + 0.2f);
TEST_EQ(v.z, 10 * i + 0.3f); TEST_EQ(v.z, 10 * i + 0.3f);
@@ -3107,7 +3117,7 @@ int FlatBufferTests() {
return 0; return 0;
} }
int main(int /*argc*/, const char * /*argv*/ []) { int main(int /*argc*/, const char * /*argv*/[]) {
InitTestEngine(); InitTestEngine();
std::string req_locale; std::string req_locale;

View File

@@ -31,7 +31,7 @@ void TestEqStr(const char *expval, const char *val, const char *exp,
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \ #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \
defined(_DEBUG) defined(_DEBUG)
#define FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC # define FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC
#endif #endif
void InitTestEngine(TestFailEventListener listener) { void InitTestEngine(TestFailEventListener listener) {
@@ -58,12 +58,12 @@ void InitTestEngine(TestFailEventListener listener) {
int CloseTestEngine(bool force_report) { int CloseTestEngine(bool force_report) {
if (!testing_fails || force_report) { if (!testing_fails || force_report) {
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC) #if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC)
auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
flags &= ~_CRTDBG_DELAY_FREE_MEM_DF; flags &= ~_CRTDBG_DELAY_FREE_MEM_DF;
flags |= _CRTDBG_LEAK_CHECK_DF; flags |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetDbgFlag(flags); _CrtSetDbgFlag(flags);
#endif #endif
} }
return (0 != testing_fails); return (0 != testing_fails);
} }

View File

@@ -1,8 +1,8 @@
#include "flatbuffers/stl_emulation.h"
#include "monster_test_generated.h"
#include "test_builder.h" #include "test_builder.h"
#include "flatbuffers/stl_emulation.h"
#include "monster_test_generated.h"
using namespace MyGame::Example; using namespace MyGame::Example;
const std::string m1_name = "Cyberdemon"; const std::string m1_name = "Cyberdemon";
@@ -13,7 +13,7 @@ const Color m2_color = Color_Green;
struct OwnedAllocator : public flatbuffers::DefaultAllocator {}; struct OwnedAllocator : public flatbuffers::DefaultAllocator {};
class TestHeapBuilder : public flatbuffers::FlatBufferBuilder { class TestHeapBuilder : public flatbuffers::FlatBufferBuilder {
private: private:
// clang-format off // clang-format off
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
TestHeapBuilder(const TestHeapBuilder &); TestHeapBuilder(const TestHeapBuilder &);
@@ -21,15 +21,15 @@ private:
#endif // !defined(FLATBUFFERS_CPP98_STL) #endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
public: public:
TestHeapBuilder() TestHeapBuilder()
: flatbuffers::FlatBufferBuilder(2048, new OwnedAllocator(), true) {} : flatbuffers::FlatBufferBuilder(2048, new OwnedAllocator(), true) {}
// clang-format off // clang-format off
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
TestHeapBuilder(TestHeapBuilder &&other) TestHeapBuilder(TestHeapBuilder &&other)
: FlatBufferBuilder(std::move(other)) { } : FlatBufferBuilder(std::move(other)) {}
TestHeapBuilder &operator=(TestHeapBuilder &&other) { TestHeapBuilder &operator=(TestHeapBuilder &&other) {
FlatBufferBuilder::operator=(std::move(other)); FlatBufferBuilder::operator=(std::move(other));
@@ -47,16 +47,16 @@ struct AllocatorMember {
struct GrpcLikeMessageBuilder : private AllocatorMember, struct GrpcLikeMessageBuilder : private AllocatorMember,
public flatbuffers::FlatBufferBuilder { public flatbuffers::FlatBufferBuilder {
private: private:
GrpcLikeMessageBuilder(const GrpcLikeMessageBuilder &); GrpcLikeMessageBuilder(const GrpcLikeMessageBuilder &);
GrpcLikeMessageBuilder &operator=(const GrpcLikeMessageBuilder &); GrpcLikeMessageBuilder &operator=(const GrpcLikeMessageBuilder &);
public: public:
GrpcLikeMessageBuilder() GrpcLikeMessageBuilder()
: flatbuffers::FlatBufferBuilder(1024, &member_allocator_, false) {} : flatbuffers::FlatBufferBuilder(1024, &member_allocator_, false) {}
GrpcLikeMessageBuilder(GrpcLikeMessageBuilder &&other) GrpcLikeMessageBuilder(GrpcLikeMessageBuilder &&other)
: FlatBufferBuilder(1024, &member_allocator_, false) { : FlatBufferBuilder(1024, &member_allocator_, false) {
// Default construct and swap idiom. // Default construct and swap idiom.
Swap(other); Swap(other);
} }
@@ -77,53 +77,63 @@ public:
void Swap(GrpcLikeMessageBuilder &other) { void Swap(GrpcLikeMessageBuilder &other) {
// No need to swap member_allocator_ because it's stateless. // No need to swap member_allocator_ because it's stateless.
FlatBufferBuilder::Swap(other); FlatBufferBuilder::Swap(other);
// After swapping the FlatBufferBuilder, we swap back the allocator, which restores // After swapping the FlatBufferBuilder, we swap back the allocator, which
// the original allocator back in place. This is necessary because MessageBuilder's // restores the original allocator back in place. This is necessary because
// allocator is its own member (SliceAllocatorMember). The allocator passed to // MessageBuilder's allocator is its own member (SliceAllocatorMember). The
// FlatBufferBuilder::vector_downward must point to this member. // allocator passed to FlatBufferBuilder::vector_downward must point to this
// member.
buf_.swap_allocator(other.buf_); buf_.swap_allocator(other.buf_);
} }
}; };
flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder) { flatbuffers::Offset<Monster> populate1(
flatbuffers::FlatBufferBuilder &builder) {
auto name_offset = builder.CreateString(m1_name); auto name_offset = builder.CreateString(m1_name);
return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color); return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color);
} }
flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder) { flatbuffers::Offset<Monster> populate2(
flatbuffers::FlatBufferBuilder &builder) {
auto name_offset = builder.CreateString(m2_name); auto name_offset = builder.CreateString(m2_name);
return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color); return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color);
} }
uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset) { uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
size_t &offset) {
return fbb.ReleaseRaw(size, offset); return fbb.ReleaseRaw(size, offset);
} }
void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) { void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) {
// release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument MessageBuilder. // release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument
// It's semantically wrong as MessageBuilder has its own ReleaseRaw member function that // MessageBuilder. It's semantically wrong as MessageBuilder has its own
// takes three arguments. In such cases though, ~MessageBuilder() invokes // ReleaseRaw member function that takes three arguments. In such cases
// ~SliceAllocator() that takes care of deleting memory as it calls grpc_slice_unref. // though, ~MessageBuilder() invokes ~SliceAllocator() that takes care of
// Obviously, this behavior is very surprising as the pointer returned by // deleting memory as it calls grpc_slice_unref. Obviously, this behavior is
// FlatBufferBuilder::ReleaseRaw is not valid as soon as MessageBuilder goes out of scope. // very surprising as the pointer returned by FlatBufferBuilder::ReleaseRaw is
// This problem does not occur with FlatBufferBuilder. // not valid as soon as MessageBuilder goes out of scope. This problem does
// not occur with FlatBufferBuilder.
} }
void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) { void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) {
flatbuffers::DefaultAllocator().deallocate(buf, 0); flatbuffers::DefaultAllocator().deallocate(buf, 0);
} }
bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color) { bool verify(const flatbuffers::DetachedBuffer &buf,
const std::string &expected_name, Color color) {
const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data()); const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data());
return (monster->name()->str() == expected_name) && (monster->color() == color); return (monster->name()->str() == expected_name) &&
(monster->color() == color);
} }
bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color) { bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
const Monster *monster = flatbuffers::GetRoot<Monster>(buf+offset); Color color) {
return (monster->name()->str() == expected_name) && (monster->color() == color); const Monster *monster = flatbuffers::GetRoot<Monster>(buf + offset);
return (monster->name()->str() == expected_name) &&
(monster->color() == color);
} }
bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color) { bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
const std::string &expected_name, Color color) {
flatbuffers::DetachedBuffer buf = fbb.Release(); flatbuffers::DetachedBuffer buf = fbb.Release();
return verify(buf, expected_name, color); return verify(buf, expected_name, color);
} }
@@ -136,13 +146,15 @@ void FlatBufferBuilderTest() {
BuilderTests<GrpcLikeMessageBuilder>::all_tests(); BuilderTests<GrpcLikeMessageBuilder>::all_tests();
BuilderReuseTestSelector tests[4] = { BuilderReuseTestSelector tests[4] = {
REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE_RAW,
REUSABLE_AFTER_RELEASE_RAW,
REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN,
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
}; };
BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+4)); BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(
BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(TestSelector(tests, tests+4)); TestSelector(tests, tests + 4));
BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(TestSelector(tests, tests+4)); BuilderReuseTests<TestHeapBuilder, TestHeapBuilder>::run_tests(
TestSelector(tests, tests + 4));
BuilderReuseTests<GrpcLikeMessageBuilder, GrpcLikeMessageBuilder>::run_tests(
TestSelector(tests, tests + 4));
} }

View File

@@ -3,8 +3,9 @@
#include <set> #include <set>
#include <type_traits> #include <type_traits>
#include "monster_test_generated.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "monster_test_generated.h"
#include "test_assert.h" #include "test_assert.h"
using MyGame::Example::Color; using MyGame::Example::Color;
@@ -14,17 +15,11 @@ namespace flatbuffers {
namespace grpc { namespace grpc {
class MessageBuilder; class MessageBuilder;
} }
} } // namespace flatbuffers
template <class T, class U> template<class T, class U> struct is_same { static const bool value = false; };
struct is_same {
static const bool value = false;
};
template <class T> template<class T> struct is_same<T, T> { static const bool value = true; };
struct is_same<T, T> {
static const bool value = true;
};
extern const std::string m1_name; extern const std::string m1_name;
extern const Color m1_color; extern const Color m1_color;
@@ -34,30 +29,36 @@ extern const Color m2_color;
flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder); flatbuffers::Offset<Monster> populate1(flatbuffers::FlatBufferBuilder &builder);
flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder); flatbuffers::Offset<Monster> populate2(flatbuffers::FlatBufferBuilder &builder);
uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size, size_t &offset); uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
size_t &offset);
void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf); void free_raw(flatbuffers::grpc::MessageBuilder &mbb, uint8_t *buf);
void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf); void free_raw(flatbuffers::FlatBufferBuilder &fbb, uint8_t *buf);
bool verify(const flatbuffers::DetachedBuffer &buf, const std::string &expected_name, Color color); bool verify(const flatbuffers::DetachedBuffer &buf,
bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name, Color color); const std::string &expected_name, Color color);
bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
Color color);
bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb, const std::string &expected_name, Color color); bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color); const std::string &expected_name, Color color);
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
const std::string &expected_name, Color color);
// clang-format off // clang-format off
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
// Invokes this function when testing the following Builder types // Invokes this function when testing the following Builder types
// FlatBufferBuilder, TestHeapBuilder, and GrpcLikeMessageBuilder // FlatBufferBuilder, TestHeapBuilder, and GrpcLikeMessageBuilder
template <class Builder> template<class Builder>
void builder_move_assign_after_releaseraw_test(Builder b1) { void builder_move_assign_after_releaseraw_test(Builder b1) {
auto root_offset1 = populate1(b1); auto root_offset1 = populate1(b1);
b1.Finish(root_offset1); b1.Finish(root_offset1);
size_t size, offset; size_t size, offset;
std::shared_ptr<uint8_t> raw(b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) { std::shared_ptr<uint8_t> raw(
flatbuffers::DefaultAllocator::dealloc(ptr, size); b1.ReleaseRaw(size, offset), [size](uint8_t *ptr) {
}); flatbuffers::DefaultAllocator::dealloc(ptr, size);
});
Builder src; Builder src;
auto root_offset2 = populate2(src); auto root_offset2 = populate2(src);
src.Finish(root_offset2); src.Finish(root_offset2);
@@ -72,9 +73,10 @@ void builder_move_assign_after_releaseraw_test(Builder b1) {
#endif // !defined(FLATBUFFERS_CPP98_STL) #endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder b1); void builder_move_assign_after_releaseraw_test(
flatbuffers::grpc::MessageBuilder b1);
template <class DestBuilder, class SrcBuilder = DestBuilder> template<class DestBuilder, class SrcBuilder = DestBuilder>
struct BuilderTests { struct BuilderTests {
// clang-format off // clang-format off
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
@@ -164,9 +166,10 @@ struct BuilderTests {
#endif // !defined(FLATBUFFERS_CPP98_STL) #endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
static void builder_swap_before_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) { static void builder_swap_before_finish_test(
bool run = is_same<DestBuilder, SrcBuilder>::value) {
/// Swap is allowed only when lhs and rhs are the same concrete type. /// Swap is allowed only when lhs and rhs are the same concrete type.
if(run) { if (run) {
SrcBuilder src; SrcBuilder src;
auto root_offset1 = populate1(src); auto root_offset1 = populate1(src);
auto size1 = src.GetSize(); auto size1 = src.GetSize();
@@ -183,9 +186,10 @@ struct BuilderTests {
} }
} }
static void builder_swap_after_finish_test(bool run = is_same<DestBuilder, SrcBuilder>::value) { static void builder_swap_after_finish_test(
bool run = is_same<DestBuilder, SrcBuilder>::value) {
/// Swap is allowed only when lhs and rhs are the same concrete type. /// Swap is allowed only when lhs and rhs are the same concrete type.
if(run) { if (run) {
SrcBuilder src; SrcBuilder src;
auto root_offset1 = populate1(src); auto root_offset1 = populate1(src);
src.Finish(root_offset1); src.Finish(root_offset1);
@@ -233,12 +237,9 @@ enum BuilderReuseTestSelector {
typedef std::set<BuilderReuseTestSelector> TestSelector; typedef std::set<BuilderReuseTestSelector> TestSelector;
template <class DestBuilder, class SrcBuilder> template<class DestBuilder, class SrcBuilder> struct BuilderReuseTests {
struct BuilderReuseTests {
static void builder_reusable_after_release_test(TestSelector selector) { static void builder_reusable_after_release_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE)) { if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
return;
}
DestBuilder fbb; DestBuilder fbb;
std::vector<flatbuffers::DetachedBuffer> buffers; std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -251,9 +252,7 @@ struct BuilderReuseTests {
} }
static void builder_reusable_after_releaseraw_test(TestSelector selector) { static void builder_reusable_after_releaseraw_test(TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
return;
}
DestBuilder fbb; DestBuilder fbb;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
@@ -269,10 +268,9 @@ struct BuilderReuseTests {
// clang-format off // clang-format off
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) { static void builder_reusable_after_release_and_move_assign_test(
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { TestSelector selector) {
return; if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
}
DestBuilder dst; DestBuilder dst;
std::vector<flatbuffers::DetachedBuffer> buffers; std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -287,10 +285,9 @@ struct BuilderReuseTests {
} }
} }
static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) { static void builder_reusable_after_releaseraw_and_move_assign_test(
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { TestSelector selector) {
return; if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
}
DestBuilder dst; DestBuilder dst;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
@@ -323,4 +320,4 @@ struct BuilderReuseTests {
} }
}; };
#endif // TEST_BUILDER_H #endif // TEST_BUILDER_H