mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-09 06:30:54 +00:00
Add support for fixed-size arrays (#5313)
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
0d2cebccfe
commit
e635141d5b
@@ -69,26 +69,27 @@ bool Print(T val, Type type, int /*indent*/, Type * /*union_type*/,
|
||||
return true;
|
||||
}
|
||||
|
||||
// Print a vector a sequence of JSON values, comma separated, wrapped in "[]".
|
||||
template<typename T>
|
||||
bool PrintVector(const Vector<T> &v, Type type, int indent,
|
||||
const IDLOptions &opts, std::string *_text) {
|
||||
// Print a vector or an array of JSON values, comma seperated, wrapped in "[]".
|
||||
template<typename T, typename Container>
|
||||
bool PrintContainer(const Container &c, size_t size, Type type, int indent,
|
||||
const IDLOptions &opts, std::string *_text) {
|
||||
std::string &text = *_text;
|
||||
text += "[";
|
||||
text += NewLine(opts);
|
||||
for (uoffset_t i = 0; i < v.size(); i++) {
|
||||
for (uoffset_t i = 0; i < size; i++) {
|
||||
if (i) {
|
||||
if (!opts.protobuf_ascii_alike) text += ",";
|
||||
text += NewLine(opts);
|
||||
}
|
||||
text.append(indent + Indent(opts), ' ');
|
||||
if (IsStruct(type)) {
|
||||
if (!Print(v.GetStructFromOffset(i * type.struct_def->bytesize), type,
|
||||
indent + Indent(opts), nullptr, opts, _text)) {
|
||||
if (!Print(reinterpret_cast<const void *>(c.Data() +
|
||||
i * type.struct_def->bytesize),
|
||||
type, indent + Indent(opts), nullptr, opts, _text)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!Print(v[i], type, indent + Indent(opts), nullptr, opts, _text)) {
|
||||
if (!Print(c[i], type, indent + Indent(opts), nullptr, opts, _text)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -99,6 +100,20 @@ bool PrintVector(const Vector<T> &v, Type type, int indent,
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool PrintVector(const Vector<T> &v, Type type, int indent,
|
||||
const IDLOptions &opts, std::string *_text) {
|
||||
return PrintContainer<T, Vector<T>>(v, v.size(), type, indent, opts, _text);
|
||||
}
|
||||
|
||||
// Print an array a sequence of JSON values, comma separated, wrapped in "[]".
|
||||
template<typename T>
|
||||
bool PrintArray(const Array<T, 0xFFFF> &a, size_t size, Type type, int indent,
|
||||
const IDLOptions &opts, std::string *_text) {
|
||||
return PrintContainer<T, Array<T, 0xFFFF>>(a, size, type, indent, opts,
|
||||
_text);
|
||||
}
|
||||
|
||||
// Specialization of Print above for pointer types.
|
||||
template<>
|
||||
bool Print<const void *>(const void *val, Type type, int indent,
|
||||
@@ -125,25 +140,49 @@ bool Print<const void *>(const void *val, Type type, int indent,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_VECTOR:
|
||||
type = type.VectorType();
|
||||
case BASE_TYPE_VECTOR: {
|
||||
const auto vec_type = type.VectorType();
|
||||
// Call PrintVector above specifically for each element type:
|
||||
switch (type.base_type) {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
switch (vec_type.base_type) {
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
|
||||
case BASE_TYPE_ ## ENUM: \
|
||||
if (!PrintVector<CTYPE>( \
|
||||
*reinterpret_cast<const Vector<CTYPE> *>(val), \
|
||||
type, indent, opts, _text)) { \
|
||||
vec_type, indent, opts, _text)) { \
|
||||
return false; \
|
||||
} \
|
||||
break;
|
||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
// clang-format on
|
||||
}
|
||||
// clang-format on
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_ARRAY: {
|
||||
const auto vec_type = type.VectorType();
|
||||
// Call PrintArray above specifically for each element type:
|
||||
// clang-format off
|
||||
switch (vec_type.base_type) {
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
|
||||
case BASE_TYPE_ ## ENUM: \
|
||||
if (!PrintArray<CTYPE>( \
|
||||
*reinterpret_cast<const Array<CTYPE, 0xFFFF> *>(val), \
|
||||
type.fixed_length, \
|
||||
vec_type, indent, opts, _text)) { \
|
||||
return false; \
|
||||
} \
|
||||
break;
|
||||
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
||||
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0);
|
||||
}
|
||||
// clang-format on
|
||||
break;
|
||||
}
|
||||
default: FLATBUFFERS_ASSERT(0);
|
||||
}
|
||||
return true;
|
||||
@@ -177,8 +216,8 @@ static bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
||||
std::string *_text) {
|
||||
const void *val = nullptr;
|
||||
if (fixed) {
|
||||
// The only non-scalar fields in structs are structs.
|
||||
FLATBUFFERS_ASSERT(IsStruct(fd.value.type));
|
||||
// The only non-scalar fields in structs are structs or arrays.
|
||||
FLATBUFFERS_ASSERT(IsStruct(fd.value.type) || IsArray(fd.value.type));
|
||||
val = reinterpret_cast<const Struct *>(table)->GetStruct<const void *>(
|
||||
fd.value.offset);
|
||||
} else if (fd.flexbuffer) {
|
||||
@@ -241,6 +280,7 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
|
||||
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE) \
|
||||
case BASE_TYPE_ ## ENUM:
|
||||
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
||||
FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
if (!GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
|
||||
union_type, opts, _text)) {
|
||||
|
||||
Reference in New Issue
Block a user