mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-08 14:15:17 +00:00
Made all C++ files clang-formatted.
Also added missing generated files. Change-Id: Ifd22a643a08e3f2edfce92812ed57b87fc0e1875
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#ifndef FLATBUFFERS_BASE_H_
|
||||
#define FLATBUFFERS_BASE_H_
|
||||
|
||||
// clang-format off
|
||||
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
|
||||
defined(_MSC_VER) && defined(_DEBUG)
|
||||
#define _CRTDBG_MAP_ALLOC
|
||||
|
||||
@@ -49,7 +49,7 @@ class CodeWriter {
|
||||
// Associates a key with a value. All subsequent calls to operator+=, where
|
||||
// the specified key is contained in {{ and }} delimiters will be replaced by
|
||||
// the given value.
|
||||
void SetValue(const std::string& key, const std::string& value) {
|
||||
void SetValue(const std::string &key, const std::string &value) {
|
||||
value_map_[key] = value;
|
||||
}
|
||||
|
||||
@@ -71,8 +71,7 @@ class BaseGenerator {
|
||||
public:
|
||||
virtual bool generate() = 0;
|
||||
|
||||
static std::string NamespaceDir(const Parser &parser,
|
||||
const std::string &path,
|
||||
static std::string NamespaceDir(const Parser &parser, const std::string &path,
|
||||
const Namespace &ns);
|
||||
|
||||
protected:
|
||||
@@ -128,8 +127,7 @@ struct CommentConfig {
|
||||
};
|
||||
|
||||
extern void GenComment(const std::vector<std::string> &dc,
|
||||
std::string *code_ptr,
|
||||
const CommentConfig *config,
|
||||
std::string *code_ptr, const CommentConfig *config,
|
||||
const char *prefix = "");
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,15 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
#ifndef FLATC_H_
|
||||
#define FLATC_H_
|
||||
# define FLATC_H_
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
@@ -49,12 +49,10 @@ class FlatCompiler {
|
||||
MakeRuleFn make_rule;
|
||||
};
|
||||
|
||||
typedef void (*WarnFn)(const FlatCompiler *flatc,
|
||||
const std::string &warn,
|
||||
typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn,
|
||||
bool show_exe_name);
|
||||
|
||||
typedef void (*ErrorFn)(const FlatCompiler *flatc,
|
||||
const std::string &err,
|
||||
typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err,
|
||||
bool usage, bool show_exe_name);
|
||||
|
||||
// Parameters required to initialize the FlatCompiler.
|
||||
@@ -65,21 +63,20 @@ class FlatCompiler {
|
||||
warn_fn(nullptr),
|
||||
error_fn(nullptr) {}
|
||||
|
||||
const Generator* generators;
|
||||
const Generator *generators;
|
||||
size_t num_generators;
|
||||
WarnFn warn_fn;
|
||||
ErrorFn error_fn;
|
||||
};
|
||||
|
||||
explicit FlatCompiler(const InitParams& params) : params_(params) {}
|
||||
explicit FlatCompiler(const InitParams ¶ms) : params_(params) {}
|
||||
|
||||
int Compile(int argc, const char** argv);
|
||||
int Compile(int argc, const char **argv);
|
||||
|
||||
std::string GetUsageString(const char* program_name) const;
|
||||
std::string GetUsageString(const char *program_name) const;
|
||||
|
||||
private:
|
||||
void ParseFile(flatbuffers::Parser &parser,
|
||||
const std::string &filename,
|
||||
void ParseFile(flatbuffers::Parser &parser, const std::string &filename,
|
||||
const std::string &contents,
|
||||
std::vector<const char *> &include_directories) const;
|
||||
|
||||
@@ -91,7 +88,6 @@ class FlatCompiler {
|
||||
InitParams params_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATC_H_
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
#include "flatbuffers/util.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4127) // C4127: conditional expression is constant
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable : 4127) // C4127: conditional expression is constant
|
||||
#endif
|
||||
|
||||
namespace flexbuffers {
|
||||
@@ -60,24 +60,25 @@ enum Type {
|
||||
TYPE_INDIRECT_UINT = 7,
|
||||
TYPE_INDIRECT_FLOAT = 8,
|
||||
TYPE_MAP = 9,
|
||||
TYPE_VECTOR = 10, // Untyped.
|
||||
TYPE_VECTOR_INT = 11, // Typed any size (stores no type table).
|
||||
TYPE_VECTOR = 10, // Untyped.
|
||||
TYPE_VECTOR_INT = 11, // Typed any size (stores no type table).
|
||||
TYPE_VECTOR_UINT = 12,
|
||||
TYPE_VECTOR_FLOAT = 13,
|
||||
TYPE_VECTOR_KEY = 14,
|
||||
TYPE_VECTOR_STRING = 15,
|
||||
TYPE_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field).
|
||||
TYPE_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field).
|
||||
TYPE_VECTOR_UINT2 = 17,
|
||||
TYPE_VECTOR_FLOAT2 = 18,
|
||||
TYPE_VECTOR_INT3 = 19, // Typed triple (no type table, no size field).
|
||||
TYPE_VECTOR_INT3 = 19, // Typed triple (no type table, no size field).
|
||||
TYPE_VECTOR_UINT3 = 20,
|
||||
TYPE_VECTOR_FLOAT3 = 21,
|
||||
TYPE_VECTOR_INT4 = 22, // Typed quad (no type table, no size field).
|
||||
TYPE_VECTOR_INT4 = 22, // Typed quad (no type table, no size field).
|
||||
TYPE_VECTOR_UINT4 = 23,
|
||||
TYPE_VECTOR_FLOAT4 = 24,
|
||||
TYPE_BLOB = 25,
|
||||
TYPE_BOOL = 26,
|
||||
TYPE_VECTOR_BOOL = 36, // To Allow the same type of conversion of type to vector type
|
||||
TYPE_VECTOR_BOOL =
|
||||
36, // To Allow the same type of conversion of type to vector type
|
||||
};
|
||||
|
||||
inline bool IsInline(Type t) { return t <= TYPE_FLOAT || t == TYPE_BOOL; }
|
||||
@@ -87,7 +88,8 @@ inline bool IsTypedVectorElementType(Type t) {
|
||||
}
|
||||
|
||||
inline bool IsTypedVector(Type t) {
|
||||
return (t >= TYPE_VECTOR_INT && t <= TYPE_VECTOR_STRING) || t == TYPE_VECTOR_BOOL;
|
||||
return (t >= TYPE_VECTOR_INT && t <= TYPE_VECTOR_STRING) ||
|
||||
t == TYPE_VECTOR_BOOL;
|
||||
}
|
||||
|
||||
inline bool IsFixedTypedVector(Type t) {
|
||||
@@ -113,7 +115,8 @@ inline Type ToTypedVectorElementType(Type t) {
|
||||
inline Type ToFixedTypedVectorElementType(Type t, uint8_t *len) {
|
||||
assert(IsFixedTypedVector(t));
|
||||
auto fixed_type = t - TYPE_VECTOR_INT2;
|
||||
*len = static_cast<uint8_t>(fixed_type / 3 + 2); // 3 types each, starting from length 2.
|
||||
*len = static_cast<uint8_t>(fixed_type / 3 +
|
||||
2); // 3 types each, starting from length 2.
|
||||
return static_cast<Type>(fixed_type % 3 + TYPE_INT);
|
||||
}
|
||||
|
||||
@@ -127,19 +130,20 @@ typedef int8_t quarter;
|
||||
// decently quick, but it is the most frequently executed function.
|
||||
// We could do an (unaligned) 64-bit read if we ifdef out the platforms for
|
||||
// which that doesn't work (or where we'd read into un-owned memory).
|
||||
template <typename R, typename T1, typename T2, typename T4, typename T8>
|
||||
template<typename R, typename T1, typename T2, typename T4, typename T8>
|
||||
R ReadSizedScalar(const uint8_t *data, uint8_t byte_width) {
|
||||
return byte_width < 4
|
||||
? (byte_width < 2 ? static_cast<R>(flatbuffers::ReadScalar<T1>(data))
|
||||
: static_cast<R>(flatbuffers::ReadScalar<T2>(data)))
|
||||
: (byte_width < 8 ? static_cast<R>(flatbuffers::ReadScalar<T4>(data))
|
||||
: static_cast<R>(flatbuffers::ReadScalar<T8>(data)));
|
||||
? (byte_width < 2
|
||||
? static_cast<R>(flatbuffers::ReadScalar<T1>(data))
|
||||
: static_cast<R>(flatbuffers::ReadScalar<T2>(data)))
|
||||
: (byte_width < 8
|
||||
? static_cast<R>(flatbuffers::ReadScalar<T4>(data))
|
||||
: static_cast<R>(flatbuffers::ReadScalar<T8>(data)));
|
||||
}
|
||||
|
||||
|
||||
inline int64_t ReadInt64(const uint8_t *data, uint8_t byte_width) {
|
||||
return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>(data,
|
||||
byte_width);
|
||||
return ReadSizedScalar<int64_t, int8_t, int16_t, int32_t, int64_t>(
|
||||
data, byte_width);
|
||||
}
|
||||
|
||||
inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) {
|
||||
@@ -148,6 +152,7 @@ inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) {
|
||||
// TODO: GCC apparently replaces memcpy by a rep movsb, but only if count is a
|
||||
// constant, which here it isn't. Test if memcpy is still faster than
|
||||
// the conditionals in ReadSizedScalar. Can also use inline asm.
|
||||
// clang-format off
|
||||
#ifdef _MSC_VER
|
||||
uint64_t u = 0;
|
||||
__movsb(reinterpret_cast<uint8_t *>(&u),
|
||||
@@ -157,11 +162,12 @@ inline uint64_t ReadUInt64(const uint8_t *data, uint8_t byte_width) {
|
||||
return ReadSizedScalar<uint64_t, uint8_t, uint16_t, uint32_t, uint64_t>(
|
||||
data, byte_width);
|
||||
#endif
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
inline double ReadDouble(const uint8_t *data, uint8_t byte_width) {
|
||||
return ReadSizedScalar<double, quarter, half, float, double>(data,
|
||||
byte_width);
|
||||
byte_width);
|
||||
}
|
||||
|
||||
inline const uint8_t *Indirect(const uint8_t *offset, uint8_t byte_width) {
|
||||
@@ -173,13 +179,14 @@ template<typename T> const uint8_t *Indirect(const uint8_t *offset) {
|
||||
}
|
||||
|
||||
inline BitWidth WidthU(uint64_t u) {
|
||||
#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) { \
|
||||
#define FLATBUFFERS_GET_FIELD_BIT_WIDTH(value, width) \
|
||||
{ \
|
||||
if (!((u) & ~((1ULL << (width)) - 1ULL))) return BIT_WIDTH_##width; \
|
||||
}
|
||||
FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 8);
|
||||
FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 16);
|
||||
FLATBUFFERS_GET_FIELD_BIT_WIDTH(u, 32);
|
||||
#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH
|
||||
#undef FLATBUFFERS_GET_FIELD_BIT_WIDTH
|
||||
return BIT_WIDTH_64;
|
||||
}
|
||||
|
||||
@@ -198,7 +205,7 @@ inline BitWidth WidthF(double f) {
|
||||
class Object {
|
||||
public:
|
||||
Object(const uint8_t *data, uint8_t byte_width)
|
||||
: data_(data), byte_width_(byte_width) {}
|
||||
: data_(data), byte_width_(byte_width) {}
|
||||
|
||||
protected:
|
||||
const uint8_t *data_;
|
||||
@@ -216,15 +223,14 @@ class Sized : public Object {
|
||||
|
||||
class String : public Sized {
|
||||
public:
|
||||
String(const uint8_t *data, uint8_t byte_width)
|
||||
: Sized(data, byte_width) {}
|
||||
String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
|
||||
|
||||
size_t length() const { return size(); }
|
||||
const char *c_str() const { return reinterpret_cast<const char *>(data_); }
|
||||
std::string str() const { return std::string(c_str(), length()); }
|
||||
|
||||
static String EmptyString() {
|
||||
static const uint8_t empty_string[] = { 0/*len*/, 0/*terminator*/ };
|
||||
static const uint8_t empty_string[] = { 0 /*len*/, 0 /*terminator*/ };
|
||||
return String(empty_string + 1, 1);
|
||||
}
|
||||
bool IsTheEmptyString() const { return data_ == EmptyString().data_; }
|
||||
@@ -233,10 +239,10 @@ class String : public Sized {
|
||||
class Blob : public Sized {
|
||||
public:
|
||||
Blob(const uint8_t *data_buf, uint8_t byte_width)
|
||||
: Sized(data_buf, byte_width) {}
|
||||
: Sized(data_buf, byte_width) {}
|
||||
|
||||
static Blob EmptyBlob() {
|
||||
static const uint8_t empty_blob[] = { 0/*len*/ };
|
||||
static const uint8_t empty_blob[] = { 0 /*len*/ };
|
||||
return Blob(empty_blob + 1, 1);
|
||||
}
|
||||
bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; }
|
||||
@@ -245,13 +251,12 @@ class Blob : public Sized {
|
||||
|
||||
class Vector : public Sized {
|
||||
public:
|
||||
Vector(const uint8_t *data, uint8_t byte_width)
|
||||
: Sized(data, byte_width) {}
|
||||
Vector(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
|
||||
|
||||
Reference operator[](size_t i) const;
|
||||
|
||||
static Vector EmptyVector() {
|
||||
static const uint8_t empty_vector[] = { 0/*len*/ };
|
||||
static const uint8_t empty_vector[] = { 0 /*len*/ };
|
||||
return Vector(empty_vector + 1, 1);
|
||||
}
|
||||
bool IsTheEmptyVector() const { return data_ == EmptyVector().data_; }
|
||||
@@ -260,12 +265,12 @@ class Vector : public Sized {
|
||||
class TypedVector : public Sized {
|
||||
public:
|
||||
TypedVector(const uint8_t *data, uint8_t byte_width, Type element_type)
|
||||
: Sized(data, byte_width), type_(element_type) {}
|
||||
: Sized(data, byte_width), type_(element_type) {}
|
||||
|
||||
Reference operator[](size_t i) const;
|
||||
|
||||
static TypedVector EmptyTypedVector() {
|
||||
static const uint8_t empty_typed_vector[] = { 0/*len*/ };
|
||||
static const uint8_t empty_typed_vector[] = { 0 /*len*/ };
|
||||
return TypedVector(empty_typed_vector + 1, 1, TYPE_INT);
|
||||
}
|
||||
bool IsTheEmptyVector() const {
|
||||
@@ -284,12 +289,12 @@ class FixedTypedVector : public Object {
|
||||
public:
|
||||
FixedTypedVector(const uint8_t *data, uint8_t byte_width, Type element_type,
|
||||
uint8_t len)
|
||||
: Object(data, byte_width), type_(element_type), len_(len) {}
|
||||
: Object(data, byte_width), type_(element_type), len_(len) {}
|
||||
|
||||
Reference operator[](size_t i) const;
|
||||
|
||||
static FixedTypedVector EmptyFixedTypedVector() {
|
||||
static const uint8_t fixed_empty_vector[] = { 0/* unused */ };
|
||||
static const uint8_t fixed_empty_vector[] = { 0 /* unused */ };
|
||||
return FixedTypedVector(fixed_empty_vector, 1, TYPE_INT, 0);
|
||||
}
|
||||
bool IsTheEmptyFixedTypedVector() const {
|
||||
@@ -306,8 +311,7 @@ class FixedTypedVector : public Object {
|
||||
|
||||
class Map : public Vector {
|
||||
public:
|
||||
Map(const uint8_t *data, uint8_t byte_width)
|
||||
: Vector(data, byte_width) {}
|
||||
Map(const uint8_t *data, uint8_t byte_width) : Vector(data, byte_width) {}
|
||||
|
||||
Reference operator[](const char *key) const;
|
||||
Reference operator[](const std::string &key) const;
|
||||
@@ -319,31 +323,31 @@ class Map : public Vector {
|
||||
auto keys_offset = data_ - byte_width_ * num_prefixed_fields;
|
||||
return TypedVector(Indirect(keys_offset, byte_width_),
|
||||
static_cast<uint8_t>(
|
||||
ReadUInt64(keys_offset + byte_width_, byte_width_)),
|
||||
ReadUInt64(keys_offset + byte_width_, byte_width_)),
|
||||
TYPE_KEY);
|
||||
}
|
||||
|
||||
static Map EmptyMap() {
|
||||
static const uint8_t empty_map[] = {
|
||||
0/*keys_len*/, 0/*keys_offset*/, 1/*keys_width*/, 0/*len*/
|
||||
0 /*keys_len*/, 0 /*keys_offset*/, 1 /*keys_width*/, 0 /*len*/
|
||||
};
|
||||
return Map(empty_map + 4, 1);
|
||||
}
|
||||
|
||||
bool IsTheEmptyMap() const {
|
||||
return data_ == EmptyMap().data_;
|
||||
}
|
||||
bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; }
|
||||
};
|
||||
|
||||
class Reference {
|
||||
public:
|
||||
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
|
||||
Type type)
|
||||
: data_(data), parent_width_(parent_width), byte_width_(byte_width),
|
||||
type_(type) {}
|
||||
: data_(data),
|
||||
parent_width_(parent_width),
|
||||
byte_width_(byte_width),
|
||||
type_(type) {}
|
||||
|
||||
Reference(const uint8_t *data, uint8_t parent_width, uint8_t packed_type)
|
||||
: data_(data), parent_width_(parent_width) {
|
||||
: data_(data), parent_width_(parent_width) {
|
||||
byte_width_ = 1U << static_cast<BitWidth>(packed_type & 3);
|
||||
type_ = static_cast<Type>(packed_type >> 2);
|
||||
}
|
||||
@@ -352,13 +356,14 @@ class Reference {
|
||||
|
||||
bool IsNull() const { return type_ == TYPE_NULL; }
|
||||
bool IsBool() const { return type_ == TYPE_BOOL; }
|
||||
bool IsInt() const { return type_ == TYPE_INT ||
|
||||
type_ == TYPE_INDIRECT_INT; }
|
||||
bool IsUInt() const { return type_ == TYPE_UINT||
|
||||
type_ == TYPE_INDIRECT_UINT;; }
|
||||
bool IsInt() const { return type_ == TYPE_INT || type_ == TYPE_INDIRECT_INT; }
|
||||
bool IsUInt() const {
|
||||
return type_ == TYPE_UINT || type_ == TYPE_INDIRECT_UINT;
|
||||
}
|
||||
bool IsIntOrUint() const { return IsInt() || IsUInt(); }
|
||||
bool IsFloat() const { return type_ == TYPE_FLOAT ||
|
||||
type_ == TYPE_INDIRECT_FLOAT; }
|
||||
bool IsFloat() const {
|
||||
return type_ == TYPE_FLOAT || type_ == TYPE_INDIRECT_FLOAT;
|
||||
}
|
||||
bool IsNumeric() const { return IsIntOrUint() || IsFloat(); }
|
||||
bool IsString() const { return type_ == TYPE_STRING; }
|
||||
bool IsKey() const { return type_ == TYPE_KEY; }
|
||||
@@ -367,7 +372,8 @@ class Reference {
|
||||
bool IsBlob() const { return type_ == TYPE_BLOB; }
|
||||
|
||||
bool AsBool() const {
|
||||
return (type_ == TYPE_BOOL ? ReadUInt64(data_, parent_width_) : AsUInt64()) != 0;
|
||||
return (type_ == TYPE_BOOL ? ReadUInt64(data_, parent_width_)
|
||||
: AsUInt64()) != 0;
|
||||
}
|
||||
|
||||
// Reads any type as a int64_t. Never fails, does most sensible conversion.
|
||||
@@ -377,79 +383,82 @@ class Reference {
|
||||
if (type_ == TYPE_INT) {
|
||||
// A fast path for the common case.
|
||||
return ReadInt64(data_, parent_width_);
|
||||
} else switch (type_) {
|
||||
case TYPE_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
|
||||
case TYPE_UINT: return ReadUInt64(data_, parent_width_);
|
||||
case TYPE_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
|
||||
case TYPE_FLOAT: return static_cast<int64_t>(
|
||||
ReadDouble(data_, parent_width_));
|
||||
case TYPE_INDIRECT_FLOAT: return static_cast<int64_t>(
|
||||
ReadDouble(Indirect(), byte_width_));
|
||||
case TYPE_NULL: return 0;
|
||||
case TYPE_STRING: return flatbuffers::StringToInt(AsString().c_str());
|
||||
case TYPE_VECTOR: return static_cast<int64_t>(AsVector().size());
|
||||
case TYPE_BOOL: return ReadInt64(data_, parent_width_);
|
||||
default:
|
||||
// Convert other things to int.
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
switch (type_) {
|
||||
case TYPE_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
|
||||
case TYPE_UINT: return ReadUInt64(data_, parent_width_);
|
||||
case TYPE_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
|
||||
case TYPE_FLOAT:
|
||||
return static_cast<int64_t>(ReadDouble(data_, parent_width_));
|
||||
case TYPE_INDIRECT_FLOAT:
|
||||
return static_cast<int64_t>(ReadDouble(Indirect(), byte_width_));
|
||||
case TYPE_NULL: return 0;
|
||||
case TYPE_STRING: return flatbuffers::StringToInt(AsString().c_str());
|
||||
case TYPE_VECTOR: return static_cast<int64_t>(AsVector().size());
|
||||
case TYPE_BOOL: return ReadInt64(data_, parent_width_);
|
||||
default:
|
||||
// Convert other things to int.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: could specialize these to not use AsInt64() if that saves
|
||||
// extension ops in generated code, and use a faster op than ReadInt64.
|
||||
int32_t AsInt32() const { return static_cast<int32_t>(AsInt64()); }
|
||||
int16_t AsInt16() const { return static_cast<int16_t>(AsInt64()); }
|
||||
int8_t AsInt8() const { return static_cast<int8_t> (AsInt64()); }
|
||||
int8_t AsInt8() const { return static_cast<int8_t>(AsInt64()); }
|
||||
|
||||
uint64_t AsUInt64() const {
|
||||
if (type_ == TYPE_UINT) {
|
||||
// A fast path for the common case.
|
||||
return ReadUInt64(data_, parent_width_);
|
||||
} else switch (type_) {
|
||||
case TYPE_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
|
||||
case TYPE_INT: return ReadInt64(data_, parent_width_);
|
||||
case TYPE_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
|
||||
case TYPE_FLOAT: return static_cast<uint64_t>(
|
||||
ReadDouble(data_, parent_width_));
|
||||
case TYPE_INDIRECT_FLOAT: return static_cast<uint64_t>(
|
||||
ReadDouble(Indirect(), byte_width_));
|
||||
case TYPE_NULL: return 0;
|
||||
case TYPE_STRING: return flatbuffers::StringToUInt(AsString().c_str());
|
||||
case TYPE_VECTOR: return static_cast<uint64_t>(AsVector().size());
|
||||
case TYPE_BOOL: return ReadUInt64(data_, parent_width_);
|
||||
default:
|
||||
// Convert other things to uint.
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
switch (type_) {
|
||||
case TYPE_INDIRECT_UINT: return ReadUInt64(Indirect(), byte_width_);
|
||||
case TYPE_INT: return ReadInt64(data_, parent_width_);
|
||||
case TYPE_INDIRECT_INT: return ReadInt64(Indirect(), byte_width_);
|
||||
case TYPE_FLOAT:
|
||||
return static_cast<uint64_t>(ReadDouble(data_, parent_width_));
|
||||
case TYPE_INDIRECT_FLOAT:
|
||||
return static_cast<uint64_t>(ReadDouble(Indirect(), byte_width_));
|
||||
case TYPE_NULL: return 0;
|
||||
case TYPE_STRING: return flatbuffers::StringToUInt(AsString().c_str());
|
||||
case TYPE_VECTOR: return static_cast<uint64_t>(AsVector().size());
|
||||
case TYPE_BOOL: return ReadUInt64(data_, parent_width_);
|
||||
default:
|
||||
// Convert other things to uint.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t AsUInt32() const { return static_cast<uint32_t>(AsUInt64()); }
|
||||
uint16_t AsUInt16() const { return static_cast<uint16_t>(AsUInt64()); }
|
||||
uint8_t AsUInt8() const { return static_cast<uint8_t> (AsUInt64()); }
|
||||
uint8_t AsUInt8() const { return static_cast<uint8_t>(AsUInt64()); }
|
||||
|
||||
double AsDouble() const {
|
||||
if (type_ == TYPE_FLOAT) {
|
||||
// A fast path for the common case.
|
||||
return ReadDouble(data_, parent_width_);
|
||||
} else switch (type_) {
|
||||
case TYPE_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_);
|
||||
case TYPE_INT: return static_cast<double>(
|
||||
ReadInt64(data_, parent_width_));
|
||||
case TYPE_UINT: return static_cast<double>(
|
||||
ReadUInt64(data_, parent_width_));
|
||||
case TYPE_INDIRECT_INT: return static_cast<double>(
|
||||
ReadInt64(Indirect(), byte_width_));
|
||||
case TYPE_INDIRECT_UINT: return static_cast<double>(
|
||||
ReadUInt64(Indirect(), byte_width_));
|
||||
case TYPE_NULL: return 0.0;
|
||||
case TYPE_STRING: return strtod(AsString().c_str(), nullptr);
|
||||
case TYPE_VECTOR: return static_cast<double>(AsVector().size());
|
||||
case TYPE_BOOL: return static_cast<double>(
|
||||
ReadUInt64(data_, parent_width_));
|
||||
default:
|
||||
// Convert strings and other things to float.
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
switch (type_) {
|
||||
case TYPE_INDIRECT_FLOAT: return ReadDouble(Indirect(), byte_width_);
|
||||
case TYPE_INT:
|
||||
return static_cast<double>(ReadInt64(data_, parent_width_));
|
||||
case TYPE_UINT:
|
||||
return static_cast<double>(ReadUInt64(data_, parent_width_));
|
||||
case TYPE_INDIRECT_INT:
|
||||
return static_cast<double>(ReadInt64(Indirect(), byte_width_));
|
||||
case TYPE_INDIRECT_UINT:
|
||||
return static_cast<double>(ReadUInt64(Indirect(), byte_width_));
|
||||
case TYPE_NULL: return 0.0;
|
||||
case TYPE_STRING: return strtod(AsString().c_str(), nullptr);
|
||||
case TYPE_VECTOR: return static_cast<double>(AsVector().size());
|
||||
case TYPE_BOOL:
|
||||
return static_cast<double>(ReadUInt64(data_, parent_width_));
|
||||
default:
|
||||
// Convert strings and other things to float.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
float AsFloat() const { return static_cast<float>(AsDouble()); }
|
||||
@@ -652,9 +661,7 @@ class Reference {
|
||||
memcpy(const_cast<char *>(s.c_str()), str, len);
|
||||
return true;
|
||||
}
|
||||
bool MutateString(const char *str) {
|
||||
return MutateString(str, strlen(str));
|
||||
}
|
||||
bool MutateString(const char *str) { return MutateString(str, strlen(str)); }
|
||||
bool MutateString(const std::string &str) {
|
||||
return MutateString(str.data(), str.length());
|
||||
}
|
||||
@@ -664,9 +671,11 @@ class Reference {
|
||||
return flexbuffers::Indirect(data_, parent_width_);
|
||||
}
|
||||
|
||||
template<typename T> bool Mutate(const uint8_t *dest, T t, size_t byte_width,
|
||||
BitWidth value_width) {
|
||||
auto fits = static_cast<size_t>(static_cast<size_t>(1U) << value_width) <= byte_width;
|
||||
template<typename T>
|
||||
bool Mutate(const uint8_t *dest, T t, size_t byte_width,
|
||||
BitWidth value_width) {
|
||||
auto fits = static_cast<size_t>(static_cast<size_t>(1U) << value_width) <=
|
||||
byte_width;
|
||||
if (fits) {
|
||||
t = flatbuffers::EndianScalar(t);
|
||||
memcpy(const_cast<uint8_t *>(dest), &t, byte_width);
|
||||
@@ -674,8 +683,9 @@ class Reference {
|
||||
return fits;
|
||||
}
|
||||
|
||||
template<typename T> bool MutateF(const uint8_t *dest, T t, size_t byte_width,
|
||||
BitWidth value_width) {
|
||||
template<typename T>
|
||||
bool MutateF(const uint8_t *dest, T t, size_t byte_width,
|
||||
BitWidth value_width) {
|
||||
if (byte_width == sizeof(double))
|
||||
return Mutate(dest, static_cast<double>(t), byte_width, value_width);
|
||||
if (byte_width == sizeof(float))
|
||||
@@ -707,21 +717,25 @@ template<> inline double Reference::As<double>() { return AsDouble(); }
|
||||
template<> inline float Reference::As<float>() { return AsFloat(); }
|
||||
|
||||
template<> inline String Reference::As<String>() { return AsString(); }
|
||||
template<> inline std::string Reference::As<std::string>() { return AsString().str(); }
|
||||
template<> inline std::string Reference::As<std::string>() {
|
||||
return AsString().str();
|
||||
}
|
||||
|
||||
template<> inline Blob Reference::As<Blob>() { return AsBlob(); }
|
||||
template<> inline Vector Reference::As<Vector>() { return AsVector(); }
|
||||
template<> inline TypedVector Reference::As<TypedVector>() { return AsTypedVector(); }
|
||||
template<> inline FixedTypedVector Reference::As<FixedTypedVector>() { return AsFixedTypedVector(); }
|
||||
template<> inline TypedVector Reference::As<TypedVector>() {
|
||||
return AsTypedVector();
|
||||
}
|
||||
template<> inline FixedTypedVector Reference::As<FixedTypedVector>() {
|
||||
return AsFixedTypedVector();
|
||||
}
|
||||
template<> inline Map Reference::As<Map>() { return AsMap(); }
|
||||
|
||||
inline uint8_t PackedType(BitWidth bit_width, Type type) {
|
||||
return static_cast<uint8_t>(bit_width | (type << 2));
|
||||
}
|
||||
|
||||
inline uint8_t NullPackedType() {
|
||||
return PackedType(BIT_WIDTH_8, TYPE_NULL);
|
||||
}
|
||||
inline uint8_t NullPackedType() { return PackedType(BIT_WIDTH_8, TYPE_NULL); }
|
||||
|
||||
// Vector accessors.
|
||||
// Note: if you try to access outside of bounds, you get a Null value back
|
||||
@@ -730,7 +744,7 @@ inline uint8_t NullPackedType() {
|
||||
// wanted 3d).
|
||||
// The Null converts seamlessly into a default value for any other type.
|
||||
// TODO(wvo): Could introduce an #ifdef that makes this into an assert?
|
||||
inline Reference Vector::operator[](size_t i) const {
|
||||
inline Reference Vector::operator[](size_t i) const {
|
||||
auto len = size();
|
||||
if (i >= len) return Reference(nullptr, 1, NullPackedType());
|
||||
auto packed_type = (data_ + len * byte_width_)[i];
|
||||
@@ -738,14 +752,14 @@ inline Reference Vector::operator[](size_t i) const {
|
||||
return Reference(elem, byte_width_, packed_type);
|
||||
}
|
||||
|
||||
inline Reference TypedVector::operator[](size_t i) const {
|
||||
inline Reference TypedVector::operator[](size_t i) const {
|
||||
auto len = size();
|
||||
if (i >= len) return Reference(nullptr, 1, NullPackedType());
|
||||
auto elem = data_ + i * byte_width_;
|
||||
return Reference(elem, byte_width_, 1, type_);
|
||||
}
|
||||
|
||||
inline Reference FixedTypedVector::operator[](size_t i) const {
|
||||
inline Reference FixedTypedVector::operator[](size_t i) const {
|
||||
if (i >= len_) return Reference(nullptr, 1, NullPackedType());
|
||||
auto elem = data_ + i * byte_width_;
|
||||
return Reference(elem, byte_width_, 1, type_);
|
||||
@@ -753,7 +767,7 @@ inline Reference FixedTypedVector::operator[](size_t i) const {
|
||||
|
||||
template<typename T> int KeyCompare(const void *key, const void *elem) {
|
||||
auto str_elem = reinterpret_cast<const char *>(
|
||||
Indirect<T>(reinterpret_cast<const uint8_t *>(elem)));
|
||||
Indirect<T>(reinterpret_cast<const uint8_t *>(elem)));
|
||||
auto skey = reinterpret_cast<const char *>(key);
|
||||
return strcmp(skey, str_elem);
|
||||
}
|
||||
@@ -770,8 +784,7 @@ inline Reference Map::operator[](const char *key) const {
|
||||
case 8: comp = KeyCompare<uint64_t>; break;
|
||||
}
|
||||
auto res = std::bsearch(key, keys.data_, keys.size(), keys.byte_width_, comp);
|
||||
if (!res)
|
||||
return Reference(nullptr, 1, NullPackedType());
|
||||
if (!res) return Reference(nullptr, 1, NullPackedType());
|
||||
auto i = (reinterpret_cast<uint8_t *>(res) - keys.data_) / keys.byte_width_;
|
||||
return (*static_cast<const Vector *>(this))[i];
|
||||
}
|
||||
@@ -817,8 +830,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
public:
|
||||
Builder(size_t initial_size = 256,
|
||||
BuilderFlag flags = BUILDER_FLAG_SHARE_KEYS)
|
||||
: buf_(initial_size), finished_(false), flags_(flags),
|
||||
force_min_bit_width_(BIT_WIDTH_8), key_pool(KeyOffsetCompare(buf_)),
|
||||
: buf_(initial_size),
|
||||
finished_(false),
|
||||
flags_(flags),
|
||||
force_min_bit_width_(BIT_WIDTH_8),
|
||||
key_pool(KeyOffsetCompare(buf_)),
|
||||
string_pool(StringOffsetCompare(buf_)) {
|
||||
buf_.clear();
|
||||
}
|
||||
@@ -831,9 +847,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
}
|
||||
|
||||
// Size of the buffer. Does not include unfinished values.
|
||||
size_t GetSize() const {
|
||||
return buf_.size();
|
||||
}
|
||||
size_t GetSize() const { return buf_.size(); }
|
||||
|
||||
// Reset all state so we can re-use the buffer.
|
||||
void Clear() {
|
||||
@@ -851,26 +865,42 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
// vectors and elsewhere).
|
||||
|
||||
void Null() { stack_.push_back(Value()); }
|
||||
void Null(const char *key) { Key(key); Null(); }
|
||||
void Null(const char *key) {
|
||||
Key(key);
|
||||
Null();
|
||||
}
|
||||
|
||||
void Int(int64_t i) { stack_.push_back(Value(i, TYPE_INT, WidthI(i))); }
|
||||
void Int(const char *key, int64_t i) { Key(key); Int(i); }
|
||||
void Int(const char *key, int64_t i) {
|
||||
Key(key);
|
||||
Int(i);
|
||||
}
|
||||
|
||||
void UInt(uint64_t u) { stack_.push_back(Value(u, TYPE_UINT, WidthU(u))); }
|
||||
void UInt(const char *key, uint64_t u) { Key(key); Int(u); }
|
||||
void UInt(const char *key, uint64_t u) {
|
||||
Key(key);
|
||||
Int(u);
|
||||
}
|
||||
|
||||
void Float(float f) { stack_.push_back(Value(f)); }
|
||||
void Float(const char *key, float f) { Key(key); Float(f); }
|
||||
void Float(const char *key, float f) {
|
||||
Key(key);
|
||||
Float(f);
|
||||
}
|
||||
|
||||
void Double(double f) { stack_.push_back(Value(f)); }
|
||||
void Double(const char *key, double d) { Key(key); Double(d); }
|
||||
void Double(const char *key, double d) {
|
||||
Key(key);
|
||||
Double(d);
|
||||
}
|
||||
|
||||
void Bool(bool b) { stack_.push_back(Value(b)); }
|
||||
void Bool(const char *key, bool b) { Key(key); Bool(b); }
|
||||
|
||||
void IndirectInt(int64_t i) {
|
||||
PushIndirect(i, TYPE_INDIRECT_INT, WidthI(i));
|
||||
void Bool(const char *key, bool b) {
|
||||
Key(key);
|
||||
Bool(b);
|
||||
}
|
||||
|
||||
void IndirectInt(int64_t i) { PushIndirect(i, TYPE_INDIRECT_INT, WidthI(i)); }
|
||||
void IndirectInt(const char *key, int64_t i) {
|
||||
Key(key);
|
||||
IndirectInt(i);
|
||||
@@ -939,9 +969,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
}
|
||||
return sloc;
|
||||
}
|
||||
size_t String(const char *str) {
|
||||
return String(str, strlen(str));
|
||||
}
|
||||
size_t String(const char *str) { return String(str, strlen(str)); }
|
||||
size_t String(const std::string &str) {
|
||||
return String(str.c_str(), str.size());
|
||||
}
|
||||
@@ -974,9 +1002,15 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
// Also some FlatBuffers types?
|
||||
|
||||
size_t StartVector() { return stack_.size(); }
|
||||
size_t StartVector(const char *key) { Key(key); return stack_.size(); }
|
||||
size_t StartVector(const char *key) {
|
||||
Key(key);
|
||||
return stack_.size();
|
||||
}
|
||||
size_t StartMap() { return stack_.size(); }
|
||||
size_t StartMap(const char *key) { Key(key); return stack_.size(); }
|
||||
size_t StartMap(const char *key) {
|
||||
Key(key);
|
||||
return stack_.size();
|
||||
}
|
||||
|
||||
// TODO(wvo): allow this to specify an aligment greater than the natural
|
||||
// alignment.
|
||||
@@ -1000,7 +1034,10 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
}
|
||||
// Now sort values, so later we can do a binary seach lookup.
|
||||
// We want to sort 2 array elements at a time.
|
||||
struct TwoValue { Value key; Value val; };
|
||||
struct TwoValue {
|
||||
Value key;
|
||||
Value val;
|
||||
};
|
||||
// TODO(wvo): strict aliasing?
|
||||
// TODO(wvo): allow the caller to indicate the data is already sorted
|
||||
// for maximum efficiency? With an assert to check sortedness to make sure
|
||||
@@ -1011,22 +1048,22 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
// sorted fashion.
|
||||
// std::sort is typically already a lot faster on sorted data though.
|
||||
auto dict =
|
||||
reinterpret_cast<TwoValue *>(flatbuffers::vector_data(stack_) +
|
||||
start);
|
||||
reinterpret_cast<TwoValue *>(flatbuffers::vector_data(stack_) + start);
|
||||
std::sort(dict, dict + len,
|
||||
[&](const TwoValue &a, const TwoValue &b) -> bool {
|
||||
auto as = reinterpret_cast<const char *>(
|
||||
flatbuffers::vector_data(buf_) + a.key.u_);
|
||||
auto bs = reinterpret_cast<const char *>(
|
||||
flatbuffers::vector_data(buf_) + b.key.u_);
|
||||
auto comp = strcmp(as, bs);
|
||||
// If this assertion hits, you've added two keys with the same value to
|
||||
// this map.
|
||||
// TODO: Have to check for pointer equality, as some sort implementation
|
||||
// apparently call this function with the same element?? Why?
|
||||
assert(comp || &a == &b);
|
||||
return comp < 0;
|
||||
});
|
||||
auto as = reinterpret_cast<const char *>(
|
||||
flatbuffers::vector_data(buf_) + a.key.u_);
|
||||
auto bs = reinterpret_cast<const char *>(
|
||||
flatbuffers::vector_data(buf_) + b.key.u_);
|
||||
auto comp = strcmp(as, bs);
|
||||
// If this assertion hits, you've added two keys with the same
|
||||
// value to this map.
|
||||
// TODO: Have to check for pointer equality, as some sort
|
||||
// implementation apparently call this function with the same
|
||||
// element?? Why?
|
||||
assert(comp || &a == &b);
|
||||
return comp < 0;
|
||||
});
|
||||
// First create a vector out of all keys.
|
||||
// TODO(wvo): if kBuilderFlagShareKeyVectors is true, see if we can share
|
||||
// the first vector.
|
||||
@@ -1043,7 +1080,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
f();
|
||||
return EndVector(start, false, false);
|
||||
}
|
||||
template <typename F, typename T> size_t Vector(F f, T &state) {
|
||||
template<typename F, typename T> size_t Vector(F f, T &state) {
|
||||
auto start = StartVector();
|
||||
f(state);
|
||||
return EndVector(start, false, false);
|
||||
@@ -1053,8 +1090,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
f();
|
||||
return EndVector(start, false, false);
|
||||
}
|
||||
template <typename F, typename T> size_t Vector(const char *key, F f,
|
||||
T &state) {
|
||||
template<typename F, typename T>
|
||||
size_t Vector(const char *key, F f, T &state) {
|
||||
auto start = StartVector(key);
|
||||
f(state);
|
||||
return EndVector(start, false, false);
|
||||
@@ -1070,8 +1107,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
EndVector(start, false, false);
|
||||
}
|
||||
}
|
||||
template<typename T> void Vector(const char *key, const T *elems,
|
||||
size_t len) {
|
||||
template<typename T>
|
||||
void Vector(const char *key, const T *elems, size_t len) {
|
||||
Key(key);
|
||||
Vector(elems, len);
|
||||
}
|
||||
@@ -1084,7 +1121,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
f();
|
||||
return EndVector(start, true, false);
|
||||
}
|
||||
template <typename F, typename T> size_t TypedVector(F f, T &state) {
|
||||
template<typename F, typename T> size_t TypedVector(F f, T &state) {
|
||||
auto start = StartVector();
|
||||
f(state);
|
||||
return EndVector(start, true, false);
|
||||
@@ -1094,8 +1131,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
f();
|
||||
return EndVector(start, true, false);
|
||||
}
|
||||
template <typename F, typename T> size_t TypedVector(const char *key, F f,
|
||||
T &state) {
|
||||
template<typename F, typename T>
|
||||
size_t TypedVector(const char *key, F f, T &state) {
|
||||
auto start = StartVector(key);
|
||||
f(state);
|
||||
return EndVector(start, true, false);
|
||||
@@ -1110,8 +1147,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
return ScalarVector(elems, len, true);
|
||||
}
|
||||
|
||||
template<typename T> size_t FixedTypedVector(const char *key, const T *elems,
|
||||
size_t len) {
|
||||
template<typename T>
|
||||
size_t FixedTypedVector(const char *key, const T *elems, size_t len) {
|
||||
Key(key);
|
||||
return FixedTypedVector(elems, len);
|
||||
}
|
||||
@@ -1121,7 +1158,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
f();
|
||||
return EndMap(start);
|
||||
}
|
||||
template <typename F, typename T> size_t Map(F f, T &state) {
|
||||
template<typename F, typename T> size_t Map(F f, T &state) {
|
||||
auto start = StartMap();
|
||||
f(state);
|
||||
return EndMap(start);
|
||||
@@ -1131,8 +1168,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
f();
|
||||
return EndMap(start);
|
||||
}
|
||||
template <typename F, typename T> size_t Map(const char *key, F f,
|
||||
T &state) {
|
||||
template<typename F, typename T> size_t Map(const char *key, F f, T &state) {
|
||||
auto start = StartMap(key);
|
||||
f(state);
|
||||
return EndMap(start);
|
||||
@@ -1160,9 +1196,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
void Add(const std::string &str) { String(str); }
|
||||
void Add(const flexbuffers::String &str) { String(str); }
|
||||
|
||||
template<typename T> void Add(const std::vector<T> &vec) {
|
||||
Vector(vec);
|
||||
}
|
||||
template<typename T> void Add(const std::vector<T> &vec) { Vector(vec); }
|
||||
|
||||
template<typename T> void Add(const char *key, const T &t) {
|
||||
Key(key);
|
||||
@@ -1173,9 +1207,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
Map(map);
|
||||
}
|
||||
|
||||
template<typename T> void operator+=(const T &t) {
|
||||
Add(t);
|
||||
}
|
||||
template<typename T> void operator+=(const T &t) { Add(t); }
|
||||
|
||||
// This function is useful in combination with the Mutate* functions above.
|
||||
// It forces elements of vectors and maps to have a minimum size, such that
|
||||
@@ -1220,8 +1252,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
}
|
||||
|
||||
void WriteBytes(const void *val, size_t size) {
|
||||
buf_.insert(buf_.end(),
|
||||
reinterpret_cast<const uint8_t *>(val),
|
||||
buf_.insert(buf_.end(), reinterpret_cast<const uint8_t *>(val),
|
||||
reinterpret_cast<const uint8_t *>(val) + size);
|
||||
}
|
||||
|
||||
@@ -1235,8 +1266,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
switch (byte_width) {
|
||||
case 8: Write(f, byte_width); break;
|
||||
case 4: Write(static_cast<float>(f), byte_width); break;
|
||||
//case 2: Write(static_cast<half>(f), byte_width); break;
|
||||
//case 1: Write(static_cast<quarter>(f), byte_width); break;
|
||||
// case 2: Write(static_cast<half>(f), byte_width); break;
|
||||
// case 1: Write(static_cast<quarter>(f), byte_width); break;
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
@@ -1267,9 +1298,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
template<typename T> static Type GetScalarType() {
|
||||
assert(flatbuffers::is_scalar<T>::value);
|
||||
return flatbuffers::is_floating_point<T>::value
|
||||
? TYPE_FLOAT
|
||||
: flatbuffers::is_same<T, bool>::value ? TYPE_BOOL
|
||||
: (flatbuffers::is_unsigned<T>::value ? TYPE_UINT : TYPE_INT);
|
||||
? TYPE_FLOAT
|
||||
: flatbuffers::is_same<T, bool>::value
|
||||
? TYPE_BOOL
|
||||
: (flatbuffers::is_unsigned<T>::value ? TYPE_UINT
|
||||
: TYPE_INT);
|
||||
}
|
||||
|
||||
struct Value {
|
||||
@@ -1286,19 +1319,20 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
|
||||
Value() : i_(0), type_(TYPE_NULL), min_bit_width_(BIT_WIDTH_8) {}
|
||||
|
||||
Value(bool b) : u_(static_cast<uint64_t>(b)), type_(TYPE_BOOL), min_bit_width_(BIT_WIDTH_8) {}
|
||||
Value(bool b)
|
||||
: u_(static_cast<uint64_t>(b)),
|
||||
type_(TYPE_BOOL),
|
||||
min_bit_width_(BIT_WIDTH_8) {}
|
||||
|
||||
Value(int64_t i, Type t, BitWidth bw)
|
||||
: i_(i), type_(t), min_bit_width_(bw) {}
|
||||
: i_(i), type_(t), min_bit_width_(bw) {}
|
||||
Value(uint64_t u, Type t, BitWidth bw)
|
||||
: u_(u), type_(t), min_bit_width_(bw) {}
|
||||
: u_(u), type_(t), min_bit_width_(bw) {}
|
||||
|
||||
Value(float f)
|
||||
: f_(f), type_(TYPE_FLOAT), min_bit_width_(BIT_WIDTH_32) {}
|
||||
Value(double f)
|
||||
: f_(f), type_(TYPE_FLOAT), min_bit_width_(WidthF(f)) {}
|
||||
Value(float f) : f_(f), type_(TYPE_FLOAT), min_bit_width_(BIT_WIDTH_32) {}
|
||||
Value(double f) : f_(f), type_(TYPE_FLOAT), min_bit_width_(WidthF(f)) {}
|
||||
|
||||
uint8_t StoredPackedType(BitWidth parent_bit_width_= BIT_WIDTH_8) const {
|
||||
uint8_t StoredPackedType(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
|
||||
return PackedType(StoredWidth(parent_bit_width_), type_);
|
||||
}
|
||||
|
||||
@@ -1315,15 +1349,15 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
byte_width <= sizeof(flatbuffers::largest_scalar_t);
|
||||
byte_width *= 2) {
|
||||
// Where are we going to write this offset?
|
||||
auto offset_loc =
|
||||
buf_size +
|
||||
flatbuffers::PaddingBytes(buf_size, byte_width) +
|
||||
elem_index * byte_width;
|
||||
auto offset_loc = buf_size +
|
||||
flatbuffers::PaddingBytes(buf_size, byte_width) +
|
||||
elem_index * byte_width;
|
||||
// Compute relative offset.
|
||||
auto offset = offset_loc - u_;
|
||||
// Does it fit?
|
||||
auto bit_width = WidthU(offset);
|
||||
if (static_cast<size_t>(static_cast<size_t>(1U) << bit_width) == byte_width)
|
||||
if (static_cast<size_t>(static_cast<size_t>(1U) << bit_width) ==
|
||||
byte_width)
|
||||
return bit_width;
|
||||
}
|
||||
assert(false); // Must match one of the sizes above.
|
||||
@@ -1333,9 +1367,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
|
||||
BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
|
||||
if (IsInline(type_)) {
|
||||
return (std::max)(min_bit_width_, parent_bit_width_);
|
||||
return (std::max)(min_bit_width_, parent_bit_width_);
|
||||
} else {
|
||||
return min_bit_width_;
|
||||
return min_bit_width_;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1343,19 +1377,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
void WriteAny(const Value &val, uint8_t byte_width) {
|
||||
switch (val.type_) {
|
||||
case TYPE_NULL:
|
||||
case TYPE_INT:
|
||||
Write(val.i_, byte_width);
|
||||
break;
|
||||
case TYPE_INT: Write(val.i_, byte_width); break;
|
||||
case TYPE_BOOL:
|
||||
case TYPE_UINT:
|
||||
Write(val.u_, byte_width);
|
||||
break;
|
||||
case TYPE_FLOAT:
|
||||
WriteDouble(val.f_, byte_width);
|
||||
break;
|
||||
default:
|
||||
WriteOffset(val.u_, byte_width);
|
||||
break;
|
||||
case TYPE_UINT: Write(val.u_, byte_width); break;
|
||||
case TYPE_FLOAT: WriteDouble(val.f_, byte_width); break;
|
||||
default: WriteOffset(val.u_, byte_width); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1369,8 +1395,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
return sloc;
|
||||
}
|
||||
|
||||
template<typename T> size_t ScalarVector(const T *elems, size_t len,
|
||||
bool fixed) {
|
||||
template<typename T>
|
||||
size_t ScalarVector(const T *elems, size_t len, bool fixed) {
|
||||
auto vector_type = GetScalarType<T>();
|
||||
auto byte_width = sizeof(T);
|
||||
auto bit_width = WidthB(byte_width);
|
||||
@@ -1436,12 +1462,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
buf_.push_back(stack_[i].StoredPackedType(bit_width));
|
||||
}
|
||||
}
|
||||
return Value(static_cast<uint64_t>(vloc), keys
|
||||
? TYPE_MAP
|
||||
: (typed
|
||||
? ToTypedVector(vector_type, fixed ? vec_len : 0)
|
||||
: TYPE_VECTOR),
|
||||
bit_width);
|
||||
return Value(static_cast<uint64_t>(vloc),
|
||||
keys ? TYPE_MAP
|
||||
: (typed ? ToTypedVector(vector_type, fixed ? vec_len : 0)
|
||||
: TYPE_VECTOR),
|
||||
bit_width);
|
||||
}
|
||||
|
||||
// You shouldn't really be copying instances of this class.
|
||||
@@ -1473,10 +1498,10 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
struct StringOffsetCompare {
|
||||
StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
|
||||
bool operator()(const StringOffset &a, const StringOffset &b) const {
|
||||
auto stra = reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) +
|
||||
a.first);
|
||||
auto strb = reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) +
|
||||
b.first);
|
||||
auto stra = reinterpret_cast<const char *>(
|
||||
flatbuffers::vector_data(*buf_) + a.first);
|
||||
auto strb = reinterpret_cast<const char *>(
|
||||
flatbuffers::vector_data(*buf_) + b.first);
|
||||
return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0;
|
||||
}
|
||||
const std::vector<uint8_t> *buf_;
|
||||
@@ -1491,8 +1516,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
|
||||
} // namespace flexbuffers
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
# if defined(_MSC_VER)
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
|
||||
#endif // FLATBUFFERS_FLEXBUFFERS_H_
|
||||
|
||||
@@ -30,13 +30,12 @@ namespace grpc {
|
||||
// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify`
|
||||
// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer
|
||||
// is refcounted and ownership is be managed automatically.
|
||||
template <class T>
|
||||
class Message {
|
||||
template<class T> class Message {
|
||||
public:
|
||||
Message() : slice_(grpc_empty_slice()) {}
|
||||
|
||||
Message(grpc_slice slice, bool add_ref)
|
||||
: slice_(add_ref ? grpc_slice_ref(slice) : slice) {}
|
||||
: slice_(add_ref ? grpc_slice_ref(slice) : slice) {}
|
||||
|
||||
Message &operator=(const Message &other) = delete;
|
||||
|
||||
@@ -137,7 +136,7 @@ namespace detail {
|
||||
struct SliceAllocatorMember {
|
||||
SliceAllocator slice_allocator_;
|
||||
};
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
// MessageBuilder is a gRPC-specific FlatBufferBuilder that uses SliceAllocator
|
||||
// to allocate gRPC buffers.
|
||||
@@ -145,7 +144,7 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
||||
public FlatBufferBuilder {
|
||||
public:
|
||||
explicit MessageBuilder(uoffset_t initial_size = 1024)
|
||||
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
||||
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
||||
|
||||
MessageBuilder(const MessageBuilder &other) = delete;
|
||||
MessageBuilder &operator=(const MessageBuilder &other) = delete;
|
||||
@@ -155,8 +154,7 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
||||
// GetMessage extracts the subslice of the buffer corresponding to the
|
||||
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
|
||||
// ownership.
|
||||
template <class T>
|
||||
Message<T> GetMessage() {
|
||||
template<class T> Message<T> GetMessage() {
|
||||
auto buf_data = buf_.buf(); // pointer to memory
|
||||
auto buf_size = buf_.capacity(); // size of memory
|
||||
auto msg_data = buf_.data(); // pointer to msg
|
||||
@@ -178,8 +176,7 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
||||
return msg;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
Message<T> ReleaseMessage() {
|
||||
template<class T> Message<T> ReleaseMessage() {
|
||||
Message<T> msg = GetMessage<T>();
|
||||
Reset();
|
||||
return msg;
|
||||
@@ -194,8 +191,7 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
||||
|
||||
namespace grpc {
|
||||
|
||||
template <class T>
|
||||
class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
||||
template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
||||
public:
|
||||
static grpc::Status Serialize(const flatbuffers::grpc::Message<T> &msg,
|
||||
grpc_byte_buffer **buffer, bool *own_buffer) {
|
||||
@@ -237,19 +233,19 @@ class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
||||
*msg = flatbuffers::grpc::Message<T>(slice, false);
|
||||
}
|
||||
grpc_byte_buffer_destroy(buffer);
|
||||
#if FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
|
||||
#if FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
|
||||
return ::grpc::Status::OK;
|
||||
#else
|
||||
#else
|
||||
if (msg->Verify()) {
|
||||
return ::grpc::Status::OK;
|
||||
} else {
|
||||
return ::grpc::Status(::grpc::StatusCode::INTERNAL,
|
||||
"Message verification failed");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace grpc;
|
||||
} // namespace grpc
|
||||
|
||||
#endif // FLATBUFFERS_GRPC_H_
|
||||
|
||||
@@ -24,26 +24,22 @@
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
template <typename T>
|
||||
struct FnvTraits {
|
||||
template<typename T> struct FnvTraits {
|
||||
static const T kFnvPrime;
|
||||
static const T kOffsetBasis;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FnvTraits<uint32_t> {
|
||||
template<> struct FnvTraits<uint32_t> {
|
||||
static const uint32_t kFnvPrime = 0x01000193;
|
||||
static const uint32_t kOffsetBasis = 0x811C9DC5;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct FnvTraits<uint64_t> {
|
||||
template<> struct FnvTraits<uint64_t> {
|
||||
static const uint64_t kFnvPrime = 0x00000100000001b3ULL;
|
||||
static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
T HashFnv1(const char *input) {
|
||||
template<typename T> T HashFnv1(const char *input) {
|
||||
T hash = FnvTraits<T>::kOffsetBasis;
|
||||
for (const char *c = input; *c; ++c) {
|
||||
hash *= FnvTraits<T>::kFnvPrime;
|
||||
@@ -52,8 +48,7 @@ T HashFnv1(const char *input) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T HashFnv1a(const char *input) {
|
||||
template<typename T> T HashFnv1a(const char *input) {
|
||||
T hash = FnvTraits<T>::kOffsetBasis;
|
||||
for (const char *c = input; *c; ++c) {
|
||||
hash ^= static_cast<unsigned char>(*c);
|
||||
@@ -62,21 +57,20 @@ T HashFnv1a(const char *input) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct NamedHashFunction {
|
||||
template<typename T> struct NamedHashFunction {
|
||||
const char *name;
|
||||
|
||||
typedef T (*HashFunction)(const char*);
|
||||
typedef T (*HashFunction)(const char *);
|
||||
HashFunction function;
|
||||
};
|
||||
|
||||
const NamedHashFunction<uint32_t> kHashFunctions32[] = {
|
||||
{ "fnv1_32", HashFnv1<uint32_t> },
|
||||
{ "fnv1_32", HashFnv1<uint32_t> },
|
||||
{ "fnv1a_32", HashFnv1a<uint32_t> },
|
||||
};
|
||||
|
||||
const NamedHashFunction<uint64_t> kHashFunctions64[] = {
|
||||
{ "fnv1_64", HashFnv1<uint64_t> },
|
||||
{ "fnv1_64", HashFnv1<uint64_t> },
|
||||
{ "fnv1a_64", HashFnv1a<uint64_t> },
|
||||
};
|
||||
|
||||
|
||||
@@ -18,17 +18,17 @@
|
||||
#define FLATBUFFERS_IDL_H_
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/flexbuffers.h"
|
||||
#include "flatbuffers/hash.h"
|
||||
#include "flatbuffers/reflection.h"
|
||||
#include "flatbuffers/flexbuffers.h"
|
||||
|
||||
#if !defined(FLATBUFFERS_CPP98_STL)
|
||||
#include <functional>
|
||||
# include <functional>
|
||||
#endif // !defined(FLATBUFFERS_CPP98_STL)
|
||||
|
||||
// This file defines the data types representing a parsed IDL (Interface
|
||||
@@ -39,6 +39,7 @@ namespace flatbuffers {
|
||||
// The order of these matters for Is*() functions below.
|
||||
// Additionally, Parser::ParseType assumes bool..string is a contiguous range
|
||||
// of type tokens.
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
|
||||
TD(NONE, "", uint8_t, byte, byte, byte, uint8) \
|
||||
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8) /* begin scalar/int */ \
|
||||
@@ -110,13 +111,12 @@ inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT ||
|
||||
inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
|
||||
t == BASE_TYPE_ULONG; }
|
||||
inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; }
|
||||
// clang-format on
|
||||
|
||||
extern const char *const kTypeNames[];
|
||||
extern const char kTypeSizes[];
|
||||
|
||||
inline size_t SizeOf(BaseType t) {
|
||||
return kTypeSizes[t];
|
||||
}
|
||||
inline size_t SizeOf(BaseType t) { return kTypeSizes[t]; }
|
||||
|
||||
struct StructDef;
|
||||
struct EnumDef;
|
||||
@@ -125,13 +125,12 @@ class Parser;
|
||||
// Represents any type in the IDL, which is a combination of the BaseType
|
||||
// and additional information for vectors/structs_.
|
||||
struct Type {
|
||||
explicit Type(BaseType _base_type = BASE_TYPE_NONE,
|
||||
StructDef *_sd = nullptr, EnumDef *_ed = nullptr)
|
||||
: base_type(_base_type),
|
||||
element(BASE_TYPE_NONE),
|
||||
struct_def(_sd),
|
||||
enum_def(_ed)
|
||||
{}
|
||||
explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
|
||||
EnumDef *_ed = nullptr)
|
||||
: base_type(_base_type),
|
||||
element(BASE_TYPE_NONE),
|
||||
struct_def(_sd),
|
||||
enum_def(_ed) {}
|
||||
|
||||
bool operator==(const Type &o) {
|
||||
return base_type == o.base_type && element == o.element &&
|
||||
@@ -151,8 +150,9 @@ struct Type {
|
||||
|
||||
// Represents a parsed scalar value, it's type, and field offset.
|
||||
struct Value {
|
||||
Value() : constant("0"), offset(static_cast<voffset_t>(
|
||||
~(static_cast<voffset_t>(0U)))) {}
|
||||
Value()
|
||||
: constant("0"),
|
||||
offset(static_cast<voffset_t>(~(static_cast<voffset_t>(0U)))) {}
|
||||
Type type;
|
||||
std::string constant;
|
||||
voffset_t offset;
|
||||
@@ -163,9 +163,7 @@ struct Value {
|
||||
template<typename T> class SymbolTable {
|
||||
public:
|
||||
~SymbolTable() {
|
||||
for (auto it = vec.begin(); it != vec.end(); ++it) {
|
||||
delete *it;
|
||||
}
|
||||
for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; }
|
||||
}
|
||||
|
||||
bool Add(const std::string &name, T *e) {
|
||||
@@ -193,15 +191,14 @@ template<typename T> class SymbolTable {
|
||||
}
|
||||
|
||||
public:
|
||||
std::map<std::string, T *> dict; // quick lookup
|
||||
std::vector<T *> vec; // Used to iterate in order of insertion
|
||||
std::map<std::string, T *> dict; // quick lookup
|
||||
std::vector<T *> vec; // Used to iterate in order of insertion
|
||||
};
|
||||
|
||||
// A name space, as set in the schema.
|
||||
struct Namespace {
|
||||
Namespace() : from_table(0) {}
|
||||
|
||||
|
||||
// Given a (potentally unqualified) name, return the "fully qualified" name
|
||||
// which has a full namespaced descriptor.
|
||||
// With max_components you can request less than the number of components
|
||||
@@ -215,13 +212,16 @@ struct Namespace {
|
||||
|
||||
// Base class for all definition types (fields, structs_, enums_).
|
||||
struct Definition {
|
||||
Definition() : generated(false), defined_namespace(nullptr),
|
||||
serialized_location(0), index(-1), refcount(1) {}
|
||||
Definition()
|
||||
: generated(false),
|
||||
defined_namespace(nullptr),
|
||||
serialized_location(0),
|
||||
index(-1),
|
||||
refcount(1) {}
|
||||
|
||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<
|
||||
reflection::KeyValue>>>
|
||||
SerializeAttributes(FlatBufferBuilder *builder,
|
||||
const Parser &parser) const;
|
||||
flatbuffers::Offset<
|
||||
flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
|
||||
SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const;
|
||||
|
||||
std::string name;
|
||||
std::string file;
|
||||
@@ -237,34 +237,38 @@ struct Definition {
|
||||
};
|
||||
|
||||
struct FieldDef : public Definition {
|
||||
FieldDef() : deprecated(false), required(false), key(false),
|
||||
native_inline(false), flexbuffer(false), nested_flatbuffer(NULL),
|
||||
padding(0) {}
|
||||
FieldDef()
|
||||
: deprecated(false),
|
||||
required(false),
|
||||
key(false),
|
||||
native_inline(false),
|
||||
flexbuffer(false),
|
||||
nested_flatbuffer(NULL),
|
||||
padding(0) {}
|
||||
|
||||
Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
|
||||
const Parser &parser) const;
|
||||
|
||||
Value value;
|
||||
bool deprecated; // Field is allowed to be present in old data, but can't be.
|
||||
// written in new data nor accessed in new code.
|
||||
bool required; // Field must always be present.
|
||||
bool key; // Field functions as a key for creating sorted vectors.
|
||||
bool deprecated; // Field is allowed to be present in old data, but can't be.
|
||||
// written in new data nor accessed in new code.
|
||||
bool required; // Field must always be present.
|
||||
bool key; // Field functions as a key for creating sorted vectors.
|
||||
bool native_inline; // Field will be defined inline (instead of as a pointer)
|
||||
// for native tables if field is a struct.
|
||||
bool flexbuffer; // This field contains FlexBuffer data.
|
||||
StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data.
|
||||
size_t padding; // Bytes to always pad after this field.
|
||||
bool flexbuffer; // This field contains FlexBuffer data.
|
||||
StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data.
|
||||
size_t padding; // Bytes to always pad after this field.
|
||||
};
|
||||
|
||||
struct StructDef : public Definition {
|
||||
StructDef()
|
||||
: fixed(false),
|
||||
predecl(true),
|
||||
sortbysize(true),
|
||||
has_key(false),
|
||||
minalign(1),
|
||||
bytesize(0)
|
||||
{}
|
||||
: fixed(false),
|
||||
predecl(true),
|
||||
sortbysize(true),
|
||||
has_key(false),
|
||||
minalign(1),
|
||||
bytesize(0) {}
|
||||
|
||||
void PadLastField(size_t min_align) {
|
||||
auto padding = PaddingBytes(bytesize, min_align);
|
||||
@@ -300,8 +304,7 @@ inline size_t InlineAlignment(const Type &type) {
|
||||
}
|
||||
|
||||
struct EnumVal {
|
||||
EnumVal(const std::string &_name, int64_t _val)
|
||||
: name(_name), value(_val) {}
|
||||
EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
|
||||
|
||||
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder) const;
|
||||
|
||||
@@ -315,12 +318,10 @@ struct EnumDef : public Definition {
|
||||
EnumDef() : is_union(false), uses_type_aliases(false) {}
|
||||
|
||||
EnumVal *ReverseLookup(int enum_idx, bool skip_union_default = true) {
|
||||
for (auto it = vals.vec.begin() + static_cast<int>(is_union &&
|
||||
skip_union_default);
|
||||
it != vals.vec.end(); ++it) {
|
||||
if ((*it)->value == enum_idx) {
|
||||
return *it;
|
||||
}
|
||||
for (auto it = vals.vec.begin() +
|
||||
static_cast<int>(is_union && skip_union_default);
|
||||
it != vals.vec.end(); ++it) {
|
||||
if ((*it)->value == enum_idx) { return *it; }
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@@ -338,8 +339,7 @@ inline bool EqualByName(const Type &a, const Type &b) {
|
||||
return a.base_type == b.base_type && a.element == b.element &&
|
||||
(a.struct_def == b.struct_def ||
|
||||
a.struct_def->name == b.struct_def->name) &&
|
||||
(a.enum_def == b.enum_def ||
|
||||
a.enum_def->name == b.enum_def->name);
|
||||
(a.enum_def == b.enum_def || a.enum_def->name == b.enum_def->name);
|
||||
}
|
||||
|
||||
struct RPCCall {
|
||||
@@ -389,16 +389,16 @@ struct IDLOptions {
|
||||
|
||||
// Possible options for the more general generator below.
|
||||
enum Language {
|
||||
kJava = 1 << 0,
|
||||
kJava = 1 << 0,
|
||||
kCSharp = 1 << 1,
|
||||
kGo = 1 << 2,
|
||||
kCpp = 1 << 3,
|
||||
kJs = 1 << 4,
|
||||
kGo = 1 << 2,
|
||||
kCpp = 1 << 3,
|
||||
kJs = 1 << 4,
|
||||
kPython = 1 << 5,
|
||||
kPhp = 1 << 6,
|
||||
kJson = 1 << 7,
|
||||
kPhp = 1 << 6,
|
||||
kJson = 1 << 7,
|
||||
kBinary = 1 << 8,
|
||||
kTs = 1 << 9,
|
||||
kTs = 1 << 9,
|
||||
kJsonSchema = 1 << 10,
|
||||
kMAX
|
||||
};
|
||||
@@ -414,33 +414,35 @@ struct IDLOptions {
|
||||
unsigned long lang_to_generate;
|
||||
|
||||
IDLOptions()
|
||||
: strict_json(false),
|
||||
skip_js_exports(false),
|
||||
use_goog_js_export_format(false),
|
||||
output_default_scalars_in_json(false),
|
||||
indent_step(2),
|
||||
output_enum_identifiers(true), prefixed_enums(true), scoped_enums(false),
|
||||
include_dependence_headers(true),
|
||||
mutable_buffer(false),
|
||||
one_file(false),
|
||||
proto_mode(false),
|
||||
generate_all(false),
|
||||
skip_unexpected_fields_in_json(false),
|
||||
generate_name_strings(false),
|
||||
generate_object_based_api(false),
|
||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||
gen_nullable(false),
|
||||
object_suffix("T"),
|
||||
union_value_namespacing(true),
|
||||
allow_non_utf8(false),
|
||||
keep_include_path(false),
|
||||
binary_schema_comments(false),
|
||||
skip_flatbuffers_import(false),
|
||||
reexport_ts_modules(true),
|
||||
protobuf_ascii_alike(false),
|
||||
lang(IDLOptions::kJava),
|
||||
mini_reflect(IDLOptions::kNone),
|
||||
lang_to_generate(0) {}
|
||||
: strict_json(false),
|
||||
skip_js_exports(false),
|
||||
use_goog_js_export_format(false),
|
||||
output_default_scalars_in_json(false),
|
||||
indent_step(2),
|
||||
output_enum_identifiers(true),
|
||||
prefixed_enums(true),
|
||||
scoped_enums(false),
|
||||
include_dependence_headers(true),
|
||||
mutable_buffer(false),
|
||||
one_file(false),
|
||||
proto_mode(false),
|
||||
generate_all(false),
|
||||
skip_unexpected_fields_in_json(false),
|
||||
generate_name_strings(false),
|
||||
generate_object_based_api(false),
|
||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||
gen_nullable(false),
|
||||
object_suffix("T"),
|
||||
union_value_namespacing(true),
|
||||
allow_non_utf8(false),
|
||||
keep_include_path(false),
|
||||
binary_schema_comments(false),
|
||||
skip_flatbuffers_import(false),
|
||||
reexport_ts_modules(true),
|
||||
protobuf_ascii_alike(false),
|
||||
lang(IDLOptions::kJava),
|
||||
mini_reflect(IDLOptions::kNone),
|
||||
lang_to_generate(0) {}
|
||||
};
|
||||
|
||||
// This encapsulates where the parser is in the current source file.
|
||||
@@ -466,7 +468,7 @@ struct ParserState {
|
||||
class CheckedError {
|
||||
public:
|
||||
explicit CheckedError(bool error)
|
||||
: is_error_(error), has_been_checked_(false) {}
|
||||
: is_error_(error), has_been_checked_(false) {}
|
||||
|
||||
CheckedError &operator=(const CheckedError &other) {
|
||||
is_error_ = other.is_error_;
|
||||
@@ -481,7 +483,10 @@ class CheckedError {
|
||||
|
||||
~CheckedError() { assert(has_been_checked_); }
|
||||
|
||||
bool Check() { has_been_checked_ = true; return is_error_; }
|
||||
bool Check() {
|
||||
has_been_checked_ = true;
|
||||
return is_error_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_error_;
|
||||
@@ -490,23 +495,25 @@ class CheckedError {
|
||||
|
||||
// Additionally, in GCC we can get these errors statically, for additional
|
||||
// assurance:
|
||||
// clang-format off
|
||||
#ifdef __GNUC__
|
||||
#define FLATBUFFERS_CHECKED_ERROR CheckedError \
|
||||
__attribute__((warn_unused_result))
|
||||
#else
|
||||
#define FLATBUFFERS_CHECKED_ERROR CheckedError
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
class Parser : public ParserState {
|
||||
public:
|
||||
explicit Parser(const IDLOptions &options = IDLOptions())
|
||||
: current_namespace_(nullptr),
|
||||
empty_namespace_(nullptr),
|
||||
root_struct_def_(nullptr),
|
||||
opts(options),
|
||||
uses_flexbuffers_(false),
|
||||
source_(nullptr),
|
||||
anonymous_counter(0) {
|
||||
: current_namespace_(nullptr),
|
||||
empty_namespace_(nullptr),
|
||||
root_struct_def_(nullptr),
|
||||
opts(options),
|
||||
uses_flexbuffers_(false),
|
||||
source_(nullptr),
|
||||
anonymous_counter(0) {
|
||||
// Start out with the empty namespace being current.
|
||||
empty_namespace_ = new Namespace();
|
||||
namespaces_.push_back(empty_namespace_);
|
||||
@@ -581,7 +588,7 @@ class Parser : public ParserState {
|
||||
|
||||
StructDef *LookupStruct(const std::string &id) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
void Message(const std::string &msg);
|
||||
void Warning(const std::string &msg);
|
||||
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
||||
@@ -606,6 +613,7 @@ private:
|
||||
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
|
||||
size_t parent_fieldn,
|
||||
const StructDef *parent_struct_def);
|
||||
// clang-format off
|
||||
#if defined(FLATBUFFERS_CPP98_STL)
|
||||
typedef CheckedError (*ParseTableDelimitersBody)(
|
||||
const std::string &name, size_t &fieldn, const StructDef *struct_def,
|
||||
@@ -615,6 +623,7 @@ private:
|
||||
const StructDef*, void*)>
|
||||
ParseTableDelimitersBody;
|
||||
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||
// clang-format on
|
||||
FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
|
||||
const StructDef *struct_def,
|
||||
ParseTableDelimitersBody body,
|
||||
@@ -623,6 +632,7 @@ private:
|
||||
std::string *value, uoffset_t *ovalue);
|
||||
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
||||
void AddVector(bool sortbysize, int count);
|
||||
// clang-format off
|
||||
#if defined(FLATBUFFERS_CPP98_STL)
|
||||
typedef CheckedError (*ParseVectorDelimitersBody)(size_t &count,
|
||||
void *state);
|
||||
@@ -630,6 +640,7 @@ private:
|
||||
typedef std::function<CheckedError(size_t&, void*)>
|
||||
ParseVectorDelimitersBody;
|
||||
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||
// clang-format on
|
||||
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(
|
||||
size_t &count, ParseVectorDelimitersBody body, void *state);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue);
|
||||
@@ -844,7 +855,7 @@ bool GenerateCppGRPC(const Parser &parser,
|
||||
bool GenerateGoGRPC(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
|
||||
// Generate GRPC Java classes.
|
||||
// See idl_gen_grpc.cpp
|
||||
bool GenerateJavaGRPC(const Parser &parser,
|
||||
|
||||
@@ -65,8 +65,7 @@ struct IterationVisitor {
|
||||
virtual void EndVector() {}
|
||||
virtual void Element(size_t /*i*/, ElementaryType /*type*/,
|
||||
const TypeTable * /*type_table*/,
|
||||
const uint8_t * /*val*/)
|
||||
{}
|
||||
const uint8_t * /*val*/) {}
|
||||
virtual ~IterationVisitor() {}
|
||||
};
|
||||
|
||||
@@ -75,34 +74,24 @@ inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
|
||||
case ET_UTYPE:
|
||||
case ET_BOOL:
|
||||
case ET_CHAR:
|
||||
case ET_UCHAR:
|
||||
return 1;
|
||||
case ET_UCHAR: return 1;
|
||||
case ET_SHORT:
|
||||
case ET_USHORT:
|
||||
return 2;
|
||||
case ET_USHORT: return 2;
|
||||
case ET_INT:
|
||||
case ET_UINT:
|
||||
case ET_FLOAT:
|
||||
case ET_STRING:
|
||||
return 4;
|
||||
case ET_STRING: return 4;
|
||||
case ET_LONG:
|
||||
case ET_ULONG:
|
||||
case ET_DOUBLE:
|
||||
return 8;
|
||||
case ET_DOUBLE: return 8;
|
||||
case ET_SEQUENCE:
|
||||
switch (type_table->st) {
|
||||
case ST_TABLE:
|
||||
case ST_UNION:
|
||||
return 4;
|
||||
case ST_STRUCT:
|
||||
return type_table->values[type_table->num_elems];
|
||||
default:
|
||||
assert(false);
|
||||
return 1;
|
||||
case ST_UNION: return 4;
|
||||
case ST_STRUCT: return type_table->values[type_table->num_elems];
|
||||
default: assert(false); return 1;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
return 1;
|
||||
default: assert(false); return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +107,7 @@ inline int32_t LookupEnum(int32_t enum_val, const int32_t *values,
|
||||
template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
|
||||
if (!type_table || !type_table->names) return nullptr;
|
||||
auto i = LookupEnum(static_cast<int32_t>(tval), type_table->values,
|
||||
type_table->num_elems);
|
||||
type_table->num_elems);
|
||||
if (i >= 0 && i < static_cast<int32_t>(type_table->num_elems)) {
|
||||
return type_table->names[i];
|
||||
}
|
||||
@@ -126,13 +115,11 @@ template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
|
||||
}
|
||||
|
||||
void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||
IterationVisitor *visitor);
|
||||
IterationVisitor *visitor);
|
||||
|
||||
inline void IterateValue(ElementaryType type, const uint8_t *val,
|
||||
const TypeTable *type_table,
|
||||
const uint8_t *prev_val,
|
||||
soffset_t vector_index,
|
||||
IterationVisitor *visitor) {
|
||||
const TypeTable *type_table, const uint8_t *prev_val,
|
||||
soffset_t vector_index, IterationVisitor *visitor) {
|
||||
switch (type) {
|
||||
case ET_UTYPE: {
|
||||
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||
@@ -200,9 +187,7 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
|
||||
val += ReadScalar<uoffset_t>(val);
|
||||
IterateObject(val, type_table, visitor);
|
||||
break;
|
||||
case ST_STRUCT:
|
||||
IterateObject(val, type_table, visitor);
|
||||
break;
|
||||
case ST_STRUCT: IterateObject(val, type_table, visitor); break;
|
||||
case ST_UNION: {
|
||||
val += ReadScalar<uoffset_t>(val);
|
||||
assert(prev_val);
|
||||
@@ -211,10 +196,10 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
|
||||
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val);
|
||||
union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
||||
}
|
||||
auto type_code_idx = LookupEnum(union_type, type_table->values,
|
||||
type_table->num_elems);
|
||||
if (type_code_idx >= 0 && type_code_idx <
|
||||
static_cast<int32_t>(type_table->num_elems)) {
|
||||
auto type_code_idx =
|
||||
LookupEnum(union_type, type_table->values, type_table->num_elems);
|
||||
if (type_code_idx >= 0 &&
|
||||
type_code_idx < static_cast<int32_t>(type_table->num_elems)) {
|
||||
auto type_code = type_table->type_codes[type_code_idx];
|
||||
switch (type_code.base_type) {
|
||||
case ET_SEQUENCE: {
|
||||
@@ -225,17 +210,14 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
|
||||
case ET_STRING:
|
||||
visitor->String(reinterpret_cast<const String *>(val));
|
||||
break;
|
||||
default:
|
||||
visitor->Unknown(val);
|
||||
default: visitor->Unknown(val);
|
||||
}
|
||||
} else {
|
||||
visitor->Unknown(val);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ST_ENUM:
|
||||
assert(false);
|
||||
break;
|
||||
case ST_ENUM: assert(false); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -257,14 +239,12 @@ inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||
auto is_vector = type_code.is_vector != 0;
|
||||
auto ref_idx = type_code.sequence_ref;
|
||||
const TypeTable *ref = nullptr;
|
||||
if (ref_idx >= 0) {
|
||||
ref = type_table->type_refs[ref_idx]();
|
||||
}
|
||||
if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); }
|
||||
auto name = type_table->names ? type_table->names[i] : nullptr;
|
||||
const uint8_t *val = nullptr;
|
||||
if (type_table->st == ST_TABLE) {
|
||||
val = reinterpret_cast<const Table *>(obj)->GetAddressOf(
|
||||
FieldIndexToOffset(static_cast<voffset_t>(i)));
|
||||
FieldIndexToOffset(static_cast<voffset_t>(i)));
|
||||
} else {
|
||||
val = obj + type_table->values[i];
|
||||
}
|
||||
@@ -310,24 +290,29 @@ struct ToStringVisitor : public IterationVisitor {
|
||||
const char *name, const uint8_t *val) {
|
||||
if (!val) return;
|
||||
if (set_idx) s += ", ";
|
||||
if (name) { s += name; s += ": "; }
|
||||
if (name) {
|
||||
s += name;
|
||||
s += ": ";
|
||||
}
|
||||
}
|
||||
template<typename T> void Named(T x, const char *name) {
|
||||
if (name) s+= name;
|
||||
else s+= NumToString(x);
|
||||
if (name)
|
||||
s += name;
|
||||
else
|
||||
s += NumToString(x);
|
||||
}
|
||||
void UType(uint8_t x, const char *name) { Named(x, name); }
|
||||
void Bool(bool x) { s+= x ? "true" : "false"; }
|
||||
void Bool(bool x) { s += x ? "true" : "false"; }
|
||||
void Char(int8_t x, const char *name) { Named(x, name); }
|
||||
void UChar(uint8_t x, const char *name) { Named(x, name); }
|
||||
void Short(int16_t x, const char *name) { Named(x, name); }
|
||||
void UShort(uint16_t x, const char *name) { Named(x, name); }
|
||||
void Int(int32_t x, const char *name) { Named(x, name); }
|
||||
void UInt(uint32_t x, const char *name) { Named(x, name); }
|
||||
void Long(int64_t x) { s+= NumToString(x); }
|
||||
void ULong(uint64_t x) { s+= NumToString(x); }
|
||||
void Float(float x) { s+= NumToString(x); }
|
||||
void Double(double x) { s+= NumToString(x); }
|
||||
void Long(int64_t x) { s += NumToString(x); }
|
||||
void ULong(uint64_t x) { s += NumToString(x); }
|
||||
void Float(float x) { s += NumToString(x); }
|
||||
void Double(double x) { s += NumToString(x); }
|
||||
void String(const struct String *str) {
|
||||
EscapeString(str->c_str(), str->size(), &s, true);
|
||||
}
|
||||
|
||||
@@ -30,14 +30,18 @@ namespace flatbuffers {
|
||||
|
||||
// ------------------------- GETTERS -------------------------
|
||||
|
||||
inline bool IsScalar (reflection::BaseType t) { return t >= reflection::UType &&
|
||||
t <= reflection::Double; }
|
||||
inline bool IsInteger(reflection::BaseType t) { return t >= reflection::UType &&
|
||||
t <= reflection::ULong; }
|
||||
inline bool IsFloat (reflection::BaseType t) { return t == reflection::Float ||
|
||||
t == reflection::Double; }
|
||||
inline bool IsLong (reflection::BaseType t) { return t == reflection::Long ||
|
||||
t == reflection::ULong; }
|
||||
inline bool IsScalar(reflection::BaseType t) {
|
||||
return t >= reflection::UType && t <= reflection::Double;
|
||||
}
|
||||
inline bool IsInteger(reflection::BaseType t) {
|
||||
return t >= reflection::UType && t <= reflection::ULong;
|
||||
}
|
||||
inline bool IsFloat(reflection::BaseType t) {
|
||||
return t == reflection::Float || t == reflection::Double;
|
||||
}
|
||||
inline bool IsLong(reflection::BaseType t) {
|
||||
return t == reflection::Long || t == reflection::ULong;
|
||||
}
|
||||
|
||||
// Size of a basic type, don't use with structs.
|
||||
inline size_t GetTypeSize(reflection::BaseType base_type) {
|
||||
@@ -48,8 +52,7 @@ inline size_t GetTypeSize(reflection::BaseType base_type) {
|
||||
|
||||
// Same as above, but now correctly returns the size of a struct if
|
||||
// the field (or vector element) is a struct.
|
||||
inline size_t GetTypeSizeInline(reflection::BaseType base_type,
|
||||
int type_index,
|
||||
inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index,
|
||||
const reflection::Schema &schema) {
|
||||
if (base_type == reflection::Obj &&
|
||||
schema.objects()->Get(type_index)->is_struct()) {
|
||||
@@ -80,16 +83,16 @@ template<typename T> T GetFieldDefaultF(const reflection::Field &field) {
|
||||
}
|
||||
|
||||
// Get a field, if you know it's an integer, and its exact type.
|
||||
template<typename T> T GetFieldI(const Table &table,
|
||||
const reflection::Field &field) {
|
||||
template<typename T>
|
||||
T GetFieldI(const Table &table, const reflection::Field &field) {
|
||||
assert(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
||||
return table.GetField<T>(field.offset(),
|
||||
static_cast<T>(field.default_integer()));
|
||||
}
|
||||
|
||||
// Get a field, if you know it's floating point and its exact type.
|
||||
template<typename T> T GetFieldF(const Table &table,
|
||||
const reflection::Field &field) {
|
||||
template<typename T>
|
||||
T GetFieldF(const Table &table, const reflection::Field &field) {
|
||||
assert(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
||||
return table.GetField<T>(field.offset(),
|
||||
static_cast<T>(field.default_real()));
|
||||
@@ -103,8 +106,8 @@ inline const String *GetFieldS(const Table &table,
|
||||
}
|
||||
|
||||
// Get a field, if you know it's a vector.
|
||||
template<typename T> Vector<T> *GetFieldV(const Table &table,
|
||||
const reflection::Field &field) {
|
||||
template<typename T>
|
||||
Vector<T> *GetFieldV(const Table &table, const reflection::Field &field) {
|
||||
assert(field.type()->base_type() == reflection::Vector &&
|
||||
sizeof(T) == GetTypeSize(field.type()->element()));
|
||||
return table.GetPointer<Vector<T> *>(field.offset());
|
||||
@@ -119,8 +122,7 @@ inline VectorOfAny *GetFieldAnyV(const Table &table,
|
||||
}
|
||||
|
||||
// Get a field, if you know it's a table.
|
||||
inline Table *GetFieldT(const Table &table,
|
||||
const reflection::Field &field) {
|
||||
inline Table *GetFieldT(const Table &table, const reflection::Field &field) {
|
||||
assert(field.type()->base_type() == reflection::Obj ||
|
||||
field.type()->base_type() == reflection::Union);
|
||||
return table.GetPointer<Table *>(field.offset());
|
||||
@@ -153,8 +155,7 @@ double GetAnyValueF(reflection::BaseType type, const uint8_t *data);
|
||||
// All scalars converted using stringstream, strings as-is, and all other
|
||||
// data types provide some level of debug-pretty-printing.
|
||||
std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
|
||||
const reflection::Schema *schema,
|
||||
int type_index);
|
||||
const reflection::Schema *schema, int type_index);
|
||||
|
||||
// Get any table field as a 64bit int, regardless of what type it is.
|
||||
inline int64_t GetAnyFieldI(const Table &table,
|
||||
@@ -165,14 +166,12 @@ inline int64_t GetAnyFieldI(const Table &table,
|
||||
}
|
||||
|
||||
// Get any table field as a double, regardless of what type it is.
|
||||
inline double GetAnyFieldF(const Table &table,
|
||||
const reflection::Field &field) {
|
||||
inline double GetAnyFieldF(const Table &table, const reflection::Field &field) {
|
||||
auto field_ptr = table.GetAddressOf(field.offset());
|
||||
return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr)
|
||||
: field.default_real();
|
||||
}
|
||||
|
||||
|
||||
// Get any table field as a string, regardless of what type it is.
|
||||
// You may pass nullptr for the schema if you don't care to have fields that
|
||||
// are of table type pretty-printed.
|
||||
@@ -186,15 +185,13 @@ inline std::string GetAnyFieldS(const Table &table,
|
||||
}
|
||||
|
||||
// Get any struct field as a 64bit int, regardless of what type it is.
|
||||
inline int64_t GetAnyFieldI(const Struct &st,
|
||||
const reflection::Field &field) {
|
||||
inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) {
|
||||
return GetAnyValueI(field.type()->base_type(),
|
||||
st.GetAddressOf(field.offset()));
|
||||
}
|
||||
|
||||
// Get any struct field as a double, regardless of what type it is.
|
||||
inline double GetAnyFieldF(const Struct &st,
|
||||
const reflection::Field &field) {
|
||||
inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) {
|
||||
return GetAnyValueF(field.type()->base_type(),
|
||||
st.GetAddressOf(field.offset()));
|
||||
}
|
||||
@@ -228,8 +225,8 @@ inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
|
||||
// Get a vector element that's a table/string/vector from a generic vector.
|
||||
// Pass Table/String/VectorOfAny as template parameter.
|
||||
// Warning: does no typechecking.
|
||||
template<typename T> T *GetAnyVectorElemPointer(const VectorOfAny *vec,
|
||||
size_t i) {
|
||||
template<typename T>
|
||||
T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
|
||||
auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
|
||||
return (T *)(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
|
||||
}
|
||||
@@ -239,34 +236,32 @@ template<typename T> T *GetAnyVectorElemPointer(const VectorOfAny *vec,
|
||||
// Get elem_size from GetTypeSizeInline().
|
||||
// Note: little-endian data on all platforms, use EndianScalar() instead of
|
||||
// raw pointer access with scalars).
|
||||
template<typename T> T *GetAnyVectorElemAddressOf(const VectorOfAny *vec,
|
||||
size_t i,
|
||||
size_t elem_size) {
|
||||
template<typename T>
|
||||
T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i,
|
||||
size_t elem_size) {
|
||||
// C-cast to allow const conversion.
|
||||
return (T *)(vec->Data() + elem_size * i);
|
||||
}
|
||||
|
||||
// Similarly, for elements of tables.
|
||||
template<typename T> T *GetAnyFieldAddressOf(const Table &table,
|
||||
const reflection::Field &field) {
|
||||
template<typename T>
|
||||
T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) {
|
||||
return (T *)table.GetAddressOf(field.offset());
|
||||
}
|
||||
|
||||
// Similarly, for elements of structs.
|
||||
template<typename T> T *GetAnyFieldAddressOf(const Struct &st,
|
||||
const reflection::Field &field) {
|
||||
template<typename T>
|
||||
T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) {
|
||||
return (T *)st.GetAddressOf(field.offset());
|
||||
}
|
||||
|
||||
// ------------------------- SETTERS -------------------------
|
||||
|
||||
// Set any scalar field, if you know its exact type.
|
||||
template<typename T> bool SetField(Table *table, const reflection::Field &field,
|
||||
T val) {
|
||||
template<typename T>
|
||||
bool SetField(Table *table, const reflection::Field &field, T val) {
|
||||
reflection::BaseType type = field.type()->base_type();
|
||||
if (!IsScalar(type)) {
|
||||
return false;
|
||||
}
|
||||
if (!IsScalar(type)) { return false; }
|
||||
assert(sizeof(T) == GetTypeSize(type));
|
||||
T def;
|
||||
if (IsInteger(type)) {
|
||||
@@ -306,7 +301,7 @@ inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
|
||||
|
||||
// Set any table field as a string, regardless of what type it is.
|
||||
inline bool SetAnyFieldS(Table *table, const reflection::Field &field,
|
||||
const char *val) {
|
||||
const char *val) {
|
||||
auto field_ptr = table->GetAddressOf(field.offset());
|
||||
if (!field_ptr) return false;
|
||||
SetAnyValueS(field.type()->base_type(), field_ptr, val);
|
||||
@@ -352,7 +347,6 @@ inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
|
||||
SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------- RESIZING SETTERS -------------------------
|
||||
|
||||
// "smart" pointer for use with resizing vectors: turns a pointer inside
|
||||
@@ -360,27 +354,25 @@ inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
|
||||
template<typename T, typename U> class pointer_inside_vector {
|
||||
public:
|
||||
pointer_inside_vector(T *ptr, std::vector<U> &vec)
|
||||
: offset_(reinterpret_cast<uint8_t *>(ptr) -
|
||||
reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))),
|
||||
vec_(vec) {}
|
||||
: offset_(reinterpret_cast<uint8_t *>(ptr) -
|
||||
reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))),
|
||||
vec_(vec) {}
|
||||
|
||||
T *operator*() const {
|
||||
return reinterpret_cast<T *>(
|
||||
reinterpret_cast<uint8_t *>(
|
||||
flatbuffers::vector_data(vec_)) + offset_);
|
||||
}
|
||||
T *operator->() const {
|
||||
return operator*();
|
||||
reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec_)) + offset_);
|
||||
}
|
||||
T *operator->() const { return operator*(); }
|
||||
void operator=(const pointer_inside_vector &piv);
|
||||
|
||||
private:
|
||||
size_t offset_;
|
||||
std::vector<U> &vec_;
|
||||
};
|
||||
|
||||
// Helper to create the above easily without specifying template args.
|
||||
template<typename T, typename U> pointer_inside_vector<T, U> piv(T *ptr,
|
||||
std::vector<U> &vec) {
|
||||
template<typename T, typename U>
|
||||
pointer_inside_vector<T, U> piv(T *ptr, std::vector<U> &vec) {
|
||||
return pointer_inside_vector<T, U>(ptr, vec);
|
||||
}
|
||||
|
||||
@@ -393,7 +385,7 @@ inline const reflection::Object &GetUnionType(
|
||||
auto enumdef = schema.enums()->Get(unionfield.type()->index());
|
||||
// TODO: this is clumsy and slow, but no other way to find it?
|
||||
auto type_field = parent.fields()->LookupByKey(
|
||||
(unionfield.name()->str() + UnionTypeFieldSuffix()).c_str());
|
||||
(unionfield.name()->str() + UnionTypeFieldSuffix()).c_str());
|
||||
assert(type_field);
|
||||
auto union_type = GetFieldI<uint8_t>(table, *type_field);
|
||||
auto enumval = enumdef->values()->LookupByKey(union_type);
|
||||
@@ -419,16 +411,14 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
||||
uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
|
||||
const reflection::Object *root_table = nullptr);
|
||||
|
||||
template <typename T>
|
||||
template<typename T>
|
||||
void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
||||
const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
|
||||
const reflection::Object *root_table = nullptr) {
|
||||
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size());
|
||||
auto newelems = ResizeAnyVector(schema, newsize,
|
||||
reinterpret_cast<const VectorOfAny *>(vec),
|
||||
vec->size(),
|
||||
static_cast<uoffset_t>(sizeof(T)), flatbuf,
|
||||
root_table);
|
||||
auto newelems = ResizeAnyVector(
|
||||
schema, newsize, reinterpret_cast<const VectorOfAny *>(vec), vec->size(),
|
||||
static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table);
|
||||
// Set new elements to "val".
|
||||
for (int i = 0; i < delta_elem; i++) {
|
||||
auto loc = newelems + i * sizeof(T);
|
||||
@@ -479,10 +469,8 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
||||
// root should point to the root type for this flatbuffer.
|
||||
// buf should point to the start of flatbuffer data.
|
||||
// length specifies the size of the flatbuffer data.
|
||||
bool Verify(const reflection::Schema &schema,
|
||||
const reflection::Object &root,
|
||||
const uint8_t *buf,
|
||||
size_t length);
|
||||
bool Verify(const reflection::Schema &schema, const reflection::Object &root,
|
||||
const uint8_t *buf, size_t length);
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
|
||||
@@ -37,18 +37,16 @@ class Registry {
|
||||
|
||||
// Generate text from an arbitrary FlatBuffer by looking up its
|
||||
// file_identifier in the registry.
|
||||
bool FlatBufferToText(const uint8_t *flatbuf, size_t len,
|
||||
std::string *dest) {
|
||||
bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest) {
|
||||
// Get the identifier out of the buffer.
|
||||
// If the buffer is truncated, exit.
|
||||
if (len < sizeof(uoffset_t) +
|
||||
FlatBufferBuilder::kFileIdentifierLength) {
|
||||
if (len < sizeof(uoffset_t) + FlatBufferBuilder::kFileIdentifierLength) {
|
||||
lasterror_ = "buffer truncated";
|
||||
return false;
|
||||
}
|
||||
std::string ident(reinterpret_cast<const char *>(flatbuf) +
|
||||
sizeof(uoffset_t),
|
||||
FlatBufferBuilder::kFileIdentifierLength);
|
||||
std::string ident(
|
||||
reinterpret_cast<const char *>(flatbuf) + sizeof(uoffset_t),
|
||||
FlatBufferBuilder::kFileIdentifierLength);
|
||||
// Load and parse the schema.
|
||||
Parser parser;
|
||||
if (!LoadSchema(ident, &parser)) return false;
|
||||
@@ -82,38 +80,36 @@ class Registry {
|
||||
|
||||
// If schemas used contain include statements, call this function for every
|
||||
// directory the parser should search them for.
|
||||
void AddIncludeDirectory(const char *path) {
|
||||
include_paths_.push_back(path);
|
||||
}
|
||||
void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); }
|
||||
|
||||
// Returns a human readable error if any of the above functions fail.
|
||||
const std::string &GetLastError() { return lasterror_; }
|
||||
|
||||
private:
|
||||
bool LoadSchema(const std::string &ident, Parser *parser) {
|
||||
// Find the schema, if not, exit.
|
||||
auto it = schemas_.find(ident);
|
||||
if (it == schemas_.end()) {
|
||||
// Don't attach the identifier, since it may not be human readable.
|
||||
lasterror_ = "identifier for this buffer not in the registry";
|
||||
return false;
|
||||
}
|
||||
auto &schema = it->second;
|
||||
// Load the schema from disk. If not, exit.
|
||||
std::string schematext;
|
||||
if (!LoadFile(schema.path_.c_str(), false, &schematext)) {
|
||||
lasterror_ = "could not load schema: " + schema.path_;
|
||||
return false;
|
||||
}
|
||||
// Parse schema.
|
||||
parser->opts = opts_;
|
||||
if (!parser->Parse(schematext.c_str(), vector_data(include_paths_),
|
||||
schema.path_.c_str())) {
|
||||
lasterror_ = parser->error_;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool LoadSchema(const std::string &ident, Parser *parser) {
|
||||
// Find the schema, if not, exit.
|
||||
auto it = schemas_.find(ident);
|
||||
if (it == schemas_.end()) {
|
||||
// Don't attach the identifier, since it may not be human readable.
|
||||
lasterror_ = "identifier for this buffer not in the registry";
|
||||
return false;
|
||||
}
|
||||
auto &schema = it->second;
|
||||
// Load the schema from disk. If not, exit.
|
||||
std::string schematext;
|
||||
if (!LoadFile(schema.path_.c_str(), false, &schematext)) {
|
||||
lasterror_ = "could not load schema: " + schema.path_;
|
||||
return false;
|
||||
}
|
||||
// Parse schema.
|
||||
parser->opts = opts_;
|
||||
if (!parser->Parse(schematext.c_str(), vector_data(include_paths_),
|
||||
schema.path_.c_str())) {
|
||||
lasterror_ = parser->error_;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct Schema {
|
||||
std::string path_;
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef FLATBUFFERS_STL_EMULATION_H_
|
||||
#define FLATBUFFERS_STL_EMULATION_H_
|
||||
|
||||
// clang-format off
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
@@ -17,32 +17,31 @@
|
||||
#ifndef FLATBUFFERS_UTIL_H_
|
||||
#define FLATBUFFERS_UTIL_H_
|
||||
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <winbase.h>
|
||||
#include <direct.h>
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# include <direct.h>
|
||||
# include <winbase.h>
|
||||
# include <windows.h>
|
||||
#else
|
||||
#include <limits.h>
|
||||
# include <limits.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
// Convert an integer or floating point value to a string.
|
||||
@@ -61,18 +60,18 @@ template<> inline std::string NumToString<unsigned char>(unsigned char t) {
|
||||
return NumToString(static_cast<int>(t));
|
||||
}
|
||||
#if defined(FLATBUFFERS_CPP98_STL)
|
||||
template <> inline std::string NumToString<long long>(long long t) {
|
||||
char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2
|
||||
snprintf(buf, sizeof(buf), "%lld", t);
|
||||
return std::string(buf);
|
||||
}
|
||||
template<> inline std::string NumToString<long long>(long long t) {
|
||||
char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2
|
||||
snprintf(buf, sizeof(buf), "%lld", t);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
template <> inline std::string NumToString<unsigned long long>(
|
||||
unsigned long long t) {
|
||||
char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1
|
||||
snprintf(buf, sizeof(buf), "%llu", t);
|
||||
return std::string(buf);
|
||||
}
|
||||
template<>
|
||||
inline std::string NumToString<unsigned long long>(unsigned long long t) {
|
||||
char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1
|
||||
snprintf(buf, sizeof(buf), "%llu", t);
|
||||
return std::string(buf);
|
||||
}
|
||||
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||
|
||||
// Special versions for floats/doubles.
|
||||
@@ -100,10 +99,7 @@ template<> inline std::string NumToString<float>(float t) {
|
||||
// For example, IntToStringHex(0x23, 8) returns the string "00000023".
|
||||
inline std::string IntToStringHex(int i, int xdigits) {
|
||||
std::stringstream ss;
|
||||
ss << std::setw(xdigits)
|
||||
<< std::setfill('0')
|
||||
<< std::hex
|
||||
<< std::uppercase
|
||||
ss << std::setw(xdigits) << std::setfill('0') << std::hex << std::uppercase
|
||||
<< i;
|
||||
return ss.str();
|
||||
}
|
||||
@@ -111,21 +107,25 @@ inline std::string IntToStringHex(int i, int xdigits) {
|
||||
// Portable implementation of strtoll().
|
||||
inline int64_t StringToInt(const char *str, char **endptr = nullptr,
|
||||
int base = 10) {
|
||||
// clang-format off
|
||||
#ifdef _MSC_VER
|
||||
return _strtoi64(str, endptr, base);
|
||||
#else
|
||||
return strtoll(str, endptr, base);
|
||||
#endif
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Portable implementation of strtoull().
|
||||
inline uint64_t StringToUInt(const char *str, char **endptr = nullptr,
|
||||
int base = 10) {
|
||||
// clang-format off
|
||||
#ifdef _MSC_VER
|
||||
return _strtoui64(str, endptr, base);
|
||||
#else
|
||||
return strtoull(str, endptr, base);
|
||||
#endif
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
typedef bool (*LoadFileFunction)(const char *filename, bool binary,
|
||||
@@ -134,9 +134,8 @@ typedef bool (*FileExistsFunction)(const char *filename);
|
||||
|
||||
LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function);
|
||||
|
||||
FileExistsFunction SetFileExistsFunction(FileExistsFunction
|
||||
file_exists_function);
|
||||
|
||||
FileExistsFunction SetFileExistsFunction(
|
||||
FileExistsFunction file_exists_function);
|
||||
|
||||
// Check if file "name" exists.
|
||||
bool FileExists(const char *name);
|
||||
@@ -239,16 +238,19 @@ inline std::string PosixPath(const char *path) {
|
||||
inline void EnsureDirExists(const std::string &filepath) {
|
||||
auto parent = StripFileName(filepath);
|
||||
if (parent.length()) EnsureDirExists(parent);
|
||||
// clang-format off
|
||||
#ifdef _WIN32
|
||||
(void)_mkdir(filepath.c_str());
|
||||
#else
|
||||
mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP);
|
||||
#endif
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// Obtains the absolute path from any other path.
|
||||
// Returns the input path if the absolute path couldn't be resolved.
|
||||
inline std::string AbsolutePath(const std::string &filepath) {
|
||||
// clang-format off
|
||||
#ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
|
||||
return filepath;
|
||||
#else
|
||||
@@ -262,6 +264,7 @@ inline std::string AbsolutePath(const std::string &filepath) {
|
||||
? abs_path
|
||||
: filepath;
|
||||
#endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
// To and from UTF-8 unicode conversion functions
|
||||
@@ -279,7 +282,7 @@ inline int ToUTF8(uint32_t ucc, std::string *out) {
|
||||
uint32_t remain_bits = i * 6;
|
||||
// Store first byte:
|
||||
(*out) += static_cast<char>((0xFE << (max_bits - remain_bits)) |
|
||||
(ucc >> remain_bits));
|
||||
(ucc >> remain_bits));
|
||||
// Store remaining bytes:
|
||||
for (int j = i - 1; j >= 0; j--) {
|
||||
(*out) += static_cast<char>(((ucc >> (j * 6)) & 0x3F) | 0x80);
|
||||
@@ -309,9 +312,7 @@ inline int FromUTF8(const char **in) {
|
||||
if ((**in << len) & 0x80) return -1; // Bit after leading 1's must be 0.
|
||||
if (!len) return *(*in)++;
|
||||
// UTF-8 encoded values with a length are between 2 and 4 bytes.
|
||||
if (len < 2 || len > 4) {
|
||||
return -1;
|
||||
}
|
||||
if (len < 2 || len > 4) { return -1; }
|
||||
// Grab initial bits of the code.
|
||||
int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
|
||||
for (int i = 0; i < len - 1; i++) {
|
||||
@@ -321,28 +322,20 @@ inline int FromUTF8(const char **in) {
|
||||
}
|
||||
// UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for
|
||||
// UTF-16 surrogate pairs).
|
||||
if (ucc >= 0xD800 && ucc <= 0xDFFF) {
|
||||
return -1;
|
||||
}
|
||||
if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; }
|
||||
// UTF-8 must represent code points in their shortest possible encoding.
|
||||
switch (len) {
|
||||
case 2:
|
||||
// Two bytes of UTF-8 can represent code points from U+0080 to U+07FF.
|
||||
if (ucc < 0x0080 || ucc > 0x07FF) {
|
||||
return -1;
|
||||
}
|
||||
if (ucc < 0x0080 || ucc > 0x07FF) { return -1; }
|
||||
break;
|
||||
case 3:
|
||||
// Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF.
|
||||
if (ucc < 0x0800 || ucc > 0xFFFF) {
|
||||
return -1;
|
||||
}
|
||||
if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; }
|
||||
break;
|
||||
case 4:
|
||||
// Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF.
|
||||
if (ucc < 0x10000 || ucc > 0x10FFFF) {
|
||||
return -1;
|
||||
}
|
||||
if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; }
|
||||
break;
|
||||
}
|
||||
return ucc;
|
||||
@@ -421,7 +414,8 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
|
||||
text += "\\u";
|
||||
text += IntToStringHex(ucc, 4);
|
||||
} else if (ucc <= 0x10FFFF) {
|
||||
// Encode Unicode SMP values to a surrogate pair using two \u escapes.
|
||||
// Encode Unicode SMP values to a surrogate pair using two \u
|
||||
// escapes.
|
||||
uint32_t base = ucc - 0x10000;
|
||||
auto high_surrogate = (base >> 10) + 0xD800;
|
||||
auto low_surrogate = (base & 0x03FF) + 0xDC00;
|
||||
|
||||
Reference in New Issue
Block a user