mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-29 21:52:01 +00:00
GenerateText gives text error on failure
This commit is contained in:
@@ -36,6 +36,8 @@ class CodeGenerator {
|
|||||||
NOT_IMPLEMENTED = 3
|
NOT_IMPLEMENTED = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string status_detail;
|
||||||
|
|
||||||
// Generate code from the provided `parser`.
|
// Generate code from the provided `parser`.
|
||||||
//
|
//
|
||||||
// DEPRECATED: prefer using the other overload of GenerateCode for bfbs.
|
// DEPRECATED: prefer using the other overload of GenerateCode for bfbs.
|
||||||
|
|||||||
@@ -1200,13 +1200,14 @@ class Parser : public ParserState {
|
|||||||
// strict_json adds "quotes" around field names if true.
|
// strict_json adds "quotes" around field names if true.
|
||||||
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
|
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
|
||||||
// byte arrays in String values), returns false.
|
// byte arrays in String values), returns false.
|
||||||
extern bool GenerateTextFromTable(const Parser &parser, const void *table,
|
extern const char *GenerateTextFromTable(const Parser &parser, const void *table,
|
||||||
const std::string &tablename,
|
const std::string &tablename,
|
||||||
std::string *text);
|
std::string *text);
|
||||||
extern bool GenerateText(const Parser &parser, const void *flatbuffer,
|
extern const char *GenerateText(const Parser &parser, const void *flatbuffer,
|
||||||
std::string *text);
|
std::string *text);
|
||||||
extern bool GenerateTextFile(const Parser &parser, const std::string &path,
|
extern const char *GenerateTextFile(const Parser &parser,
|
||||||
const std::string &file_name);
|
const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Json schema to string
|
// Generate Json schema to string
|
||||||
// See idl_gen_json_schema.cpp.
|
// See idl_gen_json_schema.cpp.
|
||||||
|
|||||||
@@ -52,8 +52,10 @@ class Registry {
|
|||||||
Parser parser;
|
Parser parser;
|
||||||
if (!LoadSchema(ident, &parser)) return false;
|
if (!LoadSchema(ident, &parser)) return false;
|
||||||
// Now we're ready to generate text.
|
// Now we're ready to generate text.
|
||||||
if (!GenerateText(parser, flatbuf, dest)) {
|
auto err = GenerateText(parser, flatbuf, dest);
|
||||||
lasterror_ = "unable to generate text for FlatBuffer binary";
|
if (err) {
|
||||||
|
lasterror_ = "unable to generate text for FlatBuffer binary: " +
|
||||||
|
std::string(err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
// to ensure it is correct, we now generate text back from the binary,
|
// to ensure it is correct, we now generate text back from the binary,
|
||||||
// and compare the two:
|
// and compare the two:
|
||||||
std::string jsongen1;
|
std::string jsongen1;
|
||||||
if (!GenerateText(parser1, parser1.builder_.GetBufferPointer(), &jsongen1)) {
|
if (GenerateText(parser1, parser1.builder_.GetBufferPointer(), &jsongen1)) {
|
||||||
printf("Couldn't serialize parsed data to JSON!\n");
|
printf("Couldn't serialize parsed data to JSON!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string jsongen2;
|
std::string jsongen2;
|
||||||
if (!GenerateText(parser2, parser2.builder_.GetBufferPointer(), &jsongen2)) {
|
if (GenerateText(parser2, parser2.builder_.GetBufferPointer(), &jsongen2)) {
|
||||||
printf("Couldn't serialize parsed data to JSON!\n");
|
printf("Couldn't serialize parsed data to JSON!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
// to ensure it is correct, we now generate text back from the binary,
|
// to ensure it is correct, we now generate text back from the binary,
|
||||||
// and compare the two:
|
// and compare the two:
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen)) {
|
if (GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen)) {
|
||||||
printf("Couldn't serialize parsed data to JSON!\n");
|
printf("Couldn't serialize parsed data to JSON!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -869,7 +869,8 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
|||||||
code_generator->GenerateCode(bfbs_buffer, bfbs_length);
|
code_generator->GenerateCode(bfbs_buffer, bfbs_length);
|
||||||
if (status != CodeGenerator::Status::OK) {
|
if (status != CodeGenerator::Status::OK) {
|
||||||
Error("Unable to generate " + code_generator->LanguageName() +
|
Error("Unable to generate " + code_generator->LanguageName() +
|
||||||
" for " + filebase + " using bfbs generator.");
|
" for " + filebase + code_generator->status_detail +
|
||||||
|
" using bfbs generator.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((!code_generator->IsSchemaOnly() ||
|
if ((!code_generator->IsSchemaOnly() ||
|
||||||
@@ -878,7 +879,7 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
|||||||
filebase) !=
|
filebase) !=
|
||||||
CodeGenerator::Status::OK) {
|
CodeGenerator::Status::OK) {
|
||||||
Error("Unable to generate " + code_generator->LanguageName() +
|
Error("Unable to generate " + code_generator->LanguageName() +
|
||||||
" for " + filebase);
|
" for " + filebase + code_generator->status_detail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,10 +54,10 @@ struct JsonPrinter {
|
|||||||
// for a single FlatBuffer value into JSON format.
|
// for a single FlatBuffer value into JSON format.
|
||||||
// The general case for scalars:
|
// The general case for scalars:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool PrintScalar(T val, const Type &type, int /*indent*/) {
|
void PrintScalar(T val, const Type &type, int /*indent*/) {
|
||||||
if (IsBool(type.base_type)) {
|
if (IsBool(type.base_type)) {
|
||||||
text += val != 0 ? "true" : "false";
|
text += val != 0 ? "true" : "false";
|
||||||
return true; // done
|
return; // done
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.output_enum_identifiers && type.enum_def) {
|
if (opts.output_enum_identifiers && type.enum_def) {
|
||||||
@@ -66,7 +66,7 @@ struct JsonPrinter {
|
|||||||
text += '\"';
|
text += '\"';
|
||||||
text += ev->name;
|
text += ev->name;
|
||||||
text += '\"';
|
text += '\"';
|
||||||
return true; // done
|
return; // done
|
||||||
} else if (val && enum_def.attributes.Lookup("bit_flags")) {
|
} else if (val && enum_def.attributes.Lookup("bit_flags")) {
|
||||||
const auto entry_len = text.length();
|
const auto entry_len = text.length();
|
||||||
const auto u64 = static_cast<uint64_t>(val);
|
const auto u64 = static_cast<uint64_t>(val);
|
||||||
@@ -84,7 +84,7 @@ struct JsonPrinter {
|
|||||||
// Don't slice if (u64 != mask)
|
// Don't slice if (u64 != mask)
|
||||||
if (mask && (u64 == mask)) {
|
if (mask && (u64 == mask)) {
|
||||||
text[text.length() - 1] = '\"';
|
text[text.length() - 1] = '\"';
|
||||||
return true; // done
|
return; // done
|
||||||
}
|
}
|
||||||
text.resize(entry_len); // restore
|
text.resize(entry_len); // restore
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ struct JsonPrinter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
text += NumToString(val);
|
text += NumToString(val);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddComma() {
|
void AddComma() {
|
||||||
@@ -102,7 +102,7 @@ struct JsonPrinter {
|
|||||||
// Print a vector or an array of JSON values, comma seperated, wrapped in
|
// Print a vector or an array of JSON values, comma seperated, wrapped in
|
||||||
// "[]".
|
// "[]".
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
bool PrintContainer(PrintScalarTag, const Container &c, size_t size,
|
const char *PrintContainer(PrintScalarTag, const Container &c, size_t size,
|
||||||
const Type &type, int indent, const uint8_t *) {
|
const Type &type, int indent, const uint8_t *) {
|
||||||
const auto elem_indent = indent + Indent();
|
const auto elem_indent = indent + Indent();
|
||||||
text += '[';
|
text += '[';
|
||||||
@@ -113,18 +113,18 @@ struct JsonPrinter {
|
|||||||
AddNewLine();
|
AddNewLine();
|
||||||
}
|
}
|
||||||
AddIndent(elem_indent);
|
AddIndent(elem_indent);
|
||||||
if (!PrintScalar(c[i], type, elem_indent)) { return false; }
|
PrintScalar(c[i], type, elem_indent);
|
||||||
}
|
}
|
||||||
AddNewLine();
|
AddNewLine();
|
||||||
AddIndent(indent);
|
AddIndent(indent);
|
||||||
text += ']';
|
text += ']';
|
||||||
return true;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print a vector or an array of JSON values, comma seperated, wrapped in
|
// Print a vector or an array of JSON values, comma seperated, wrapped in
|
||||||
// "[]".
|
// "[]".
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
bool PrintContainer(PrintPointerTag, const Container &c, size_t size,
|
const char *PrintContainer(PrintPointerTag, const Container &c, size_t size,
|
||||||
const Type &type, int indent, const uint8_t *prev_val) {
|
const Type &type, int indent, const uint8_t *prev_val) {
|
||||||
const auto is_struct = IsStruct(type);
|
const auto is_struct = IsStruct(type);
|
||||||
const auto elem_indent = indent + Indent();
|
const auto elem_indent = indent + Indent();
|
||||||
@@ -139,19 +139,18 @@ struct JsonPrinter {
|
|||||||
auto ptr = is_struct ? reinterpret_cast<const void *>(
|
auto ptr = is_struct ? reinterpret_cast<const void *>(
|
||||||
c.Data() + type.struct_def->bytesize * i)
|
c.Data() + type.struct_def->bytesize * i)
|
||||||
: c[i];
|
: c[i];
|
||||||
if (!PrintOffset(ptr, type, elem_indent, prev_val,
|
auto err = PrintOffset(ptr, type, elem_indent, prev_val,
|
||||||
static_cast<soffset_t>(i))) {
|
static_cast<soffset_t>(i));
|
||||||
return false;
|
if (err) return err;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AddNewLine();
|
AddNewLine();
|
||||||
AddIndent(indent);
|
AddIndent(indent);
|
||||||
text += ']';
|
text += ']';
|
||||||
return true;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool PrintVector(const void *val, const Type &type, int indent,
|
const char *PrintVector(const void *val, const Type &type, int indent,
|
||||||
const uint8_t *prev_val) {
|
const uint8_t *prev_val) {
|
||||||
typedef Vector<T> Container;
|
typedef Vector<T> Container;
|
||||||
typedef typename PrintTag<typename Container::return_type>::type tag;
|
typedef typename PrintTag<typename Container::return_type>::type tag;
|
||||||
@@ -162,14 +161,15 @@ struct JsonPrinter {
|
|||||||
|
|
||||||
// Print an array a sequence of JSON values, comma separated, wrapped in "[]".
|
// Print an array a sequence of JSON values, comma separated, wrapped in "[]".
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool PrintArray(const void *val, size_t size, const Type &type, int indent) {
|
const char *PrintArray(const void *val, size_t size, const Type &type,
|
||||||
|
int indent) {
|
||||||
typedef Array<T, 0xFFFF> Container;
|
typedef Array<T, 0xFFFF> Container;
|
||||||
typedef typename PrintTag<typename Container::return_type>::type tag;
|
typedef typename PrintTag<typename Container::return_type>::type tag;
|
||||||
auto &arr = *reinterpret_cast<const Container *>(val);
|
auto &arr = *reinterpret_cast<const Container *>(val);
|
||||||
return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr);
|
return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PrintOffset(const void *val, const Type &type, int indent,
|
const char *PrintOffset(const void *val, const Type &type, int indent,
|
||||||
const uint8_t *prev_val, soffset_t vector_index) {
|
const uint8_t *prev_val, soffset_t vector_index) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_UNION: {
|
case BASE_TYPE_UNION: {
|
||||||
@@ -186,7 +186,7 @@ struct JsonPrinter {
|
|||||||
if (enum_val) {
|
if (enum_val) {
|
||||||
return PrintOffset(val, enum_val->union_type, indent, nullptr, -1);
|
return PrintOffset(val, enum_val->union_type, indent, nullptr, -1);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return "unknown enum value";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case BASE_TYPE_STRUCT:
|
case BASE_TYPE_STRUCT:
|
||||||
@@ -194,8 +194,9 @@ struct JsonPrinter {
|
|||||||
indent);
|
indent);
|
||||||
case BASE_TYPE_STRING: {
|
case BASE_TYPE_STRING: {
|
||||||
auto s = reinterpret_cast<const String *>(val);
|
auto s = reinterpret_cast<const String *>(val);
|
||||||
return EscapeString(s->c_str(), s->size(), &text, opts.allow_non_utf8,
|
bool ok = EscapeString(s->c_str(), s->size(), &text, opts.allow_non_utf8,
|
||||||
opts.natural_utf8);
|
opts.natural_utf8);
|
||||||
|
return ok ? nullptr : "string contains non-utf8 bytes";
|
||||||
}
|
}
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
const auto vec_type = type.VectorType();
|
const auto vec_type = type.VectorType();
|
||||||
@@ -203,17 +204,15 @@ struct JsonPrinter {
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
switch (vec_type.base_type) {
|
switch (vec_type.base_type) {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
||||||
case BASE_TYPE_ ## ENUM: \
|
case BASE_TYPE_ ## ENUM: { \
|
||||||
if (!PrintVector<CTYPE>( \
|
auto err = PrintVector<CTYPE>(val, vec_type, indent, prev_val); \
|
||||||
val, vec_type, indent, prev_val)) { \
|
if (err) return err; \
|
||||||
return false; \
|
break; }
|
||||||
} \
|
|
||||||
break;
|
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
return true;
|
return nullptr;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_ARRAY: {
|
case BASE_TYPE_ARRAY: {
|
||||||
const auto vec_type = type.VectorType();
|
const auto vec_type = type.VectorType();
|
||||||
@@ -221,12 +220,10 @@ struct JsonPrinter {
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
switch (vec_type.base_type) {
|
switch (vec_type.base_type) {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
||||||
case BASE_TYPE_ ## ENUM: \
|
case BASE_TYPE_ ## ENUM: { \
|
||||||
if (!PrintArray<CTYPE>( \
|
auto err = PrintArray<CTYPE>(val, type.fixed_length, vec_type, indent); \
|
||||||
val, type.fixed_length, vec_type, indent)) { \
|
if (err) return err; \
|
||||||
return false; \
|
break; }
|
||||||
} \
|
|
||||||
break;
|
|
||||||
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
||||||
// Arrays of scalars or structs are only possible.
|
// Arrays of scalars or structs are only possible.
|
||||||
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
||||||
@@ -234,9 +231,11 @@ struct JsonPrinter {
|
|||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0);
|
case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0);
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
return true;
|
return nullptr;
|
||||||
}
|
}
|
||||||
default: FLATBUFFERS_ASSERT(0); return false;
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
|
return "unknown type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,29 +249,28 @@ struct JsonPrinter {
|
|||||||
|
|
||||||
// Generate text for a scalar field.
|
// Generate text for a scalar field.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool GenField(const FieldDef &fd, const Table *table, bool fixed,
|
void GenField(const FieldDef &fd, const Table *table, bool fixed,
|
||||||
int indent) {
|
int indent) {
|
||||||
if (fixed) {
|
if (fixed) {
|
||||||
return PrintScalar(
|
PrintScalar(
|
||||||
reinterpret_cast<const Struct *>(table)->GetField<T>(fd.value.offset),
|
reinterpret_cast<const Struct *>(table)->GetField<T>(fd.value.offset),
|
||||||
fd.value.type, indent);
|
fd.value.type, indent);
|
||||||
} else if (fd.IsOptional()) {
|
} else if (fd.IsOptional()) {
|
||||||
auto opt = table->GetOptional<T, T>(fd.value.offset);
|
auto opt = table->GetOptional<T, T>(fd.value.offset);
|
||||||
if (opt) {
|
if (opt) {
|
||||||
return PrintScalar(*opt, fd.value.type, indent);
|
PrintScalar(*opt, fd.value.type, indent);
|
||||||
} else {
|
} else {
|
||||||
text += "null";
|
text += "null";
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return PrintScalar(
|
PrintScalar(
|
||||||
table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
|
table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
|
||||||
fd.value.type, indent);
|
fd.value.type, indent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate text for non-scalar field.
|
// Generate text for non-scalar field.
|
||||||
bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
const char *GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
||||||
int indent, const uint8_t *prev_val) {
|
int indent, const uint8_t *prev_val) {
|
||||||
const void *val = nullptr;
|
const void *val = nullptr;
|
||||||
if (fixed) {
|
if (fixed) {
|
||||||
@@ -290,7 +288,7 @@ struct JsonPrinter {
|
|||||||
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
||||||
auto root = flexbuffers::GetRoot(vec->data(), vec->size());
|
auto root = flexbuffers::GetRoot(vec->data(), vec->size());
|
||||||
root.ToString(true, opts.strict_json, text);
|
root.ToString(true, opts.strict_json, text);
|
||||||
return true;
|
return nullptr;
|
||||||
} else if (fd.nested_flatbuffer && opts.json_nested_flatbuffers) {
|
} else if (fd.nested_flatbuffer && opts.json_nested_flatbuffers) {
|
||||||
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
||||||
auto root = GetRoot<Table>(vec->data());
|
auto root = GetRoot<Table>(vec->data());
|
||||||
@@ -305,7 +303,8 @@ struct JsonPrinter {
|
|||||||
|
|
||||||
// Generate text for a struct or table, values separated by commas, indented,
|
// Generate text for a struct or table, values separated by commas, indented,
|
||||||
// and bracketed by "{}"
|
// and bracketed by "{}"
|
||||||
bool GenStruct(const StructDef &struct_def, const Table *table, int indent) {
|
const char *GenStruct(const StructDef &struct_def, const Table *table,
|
||||||
|
int indent) {
|
||||||
text += '{';
|
text += '{';
|
||||||
int fieldout = 0;
|
int fieldout = 0;
|
||||||
const uint8_t *prev_val = nullptr;
|
const uint8_t *prev_val = nullptr;
|
||||||
@@ -329,11 +328,9 @@ struct JsonPrinter {
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
switch (fd.value.type.base_type) {
|
switch (fd.value.type.base_type) {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
||||||
case BASE_TYPE_ ## ENUM: \
|
case BASE_TYPE_ ## ENUM: { \
|
||||||
if (!GenField<CTYPE>(fd, table, struct_def.fixed, elem_indent)) { \
|
GenField<CTYPE>(fd, table, struct_def.fixed, elem_indent); \
|
||||||
return false; \
|
break; }
|
||||||
} \
|
|
||||||
break;
|
|
||||||
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
// Generate drop-thru case statements for all pointer types:
|
// Generate drop-thru case statements for all pointer types:
|
||||||
@@ -342,10 +339,11 @@ struct JsonPrinter {
|
|||||||
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
||||||
FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
if (!GenFieldOffset(fd, table, struct_def.fixed, elem_indent, prev_val)) {
|
{
|
||||||
return false;
|
auto err = GenFieldOffset(fd, table, struct_def.fixed, elem_indent, prev_val);
|
||||||
}
|
if (err) return err;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// clang-format on
|
// clang-format on
|
||||||
// Track prev val for use with union types.
|
// Track prev val for use with union types.
|
||||||
@@ -359,7 +357,7 @@ struct JsonPrinter {
|
|||||||
AddNewLine();
|
AddNewLine();
|
||||||
AddIndent(indent);
|
AddIndent(indent);
|
||||||
text += '}';
|
text += '}';
|
||||||
return true;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonPrinter(const Parser &parser, std::string &dest)
|
JsonPrinter(const Parser &parser, std::string &dest)
|
||||||
@@ -371,16 +369,17 @@ struct JsonPrinter {
|
|||||||
std::string &text;
|
std::string &text;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool GenerateTextImpl(const Parser &parser, const Table *table,
|
static const char *GenerateTextImpl(const Parser &parser, const Table *table,
|
||||||
const StructDef &struct_def, std::string *_text) {
|
const StructDef &struct_def, std::string *_text) {
|
||||||
JsonPrinter printer(parser, *_text);
|
JsonPrinter printer(parser, *_text);
|
||||||
if (!printer.GenStruct(struct_def, table, 0)) { return false; }
|
auto err = printer.GenStruct(struct_def, table, 0);
|
||||||
|
if (err) return err;
|
||||||
printer.AddNewLine();
|
printer.AddNewLine();
|
||||||
return true;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a text representation of a flatbuffer in JSON format.
|
// Generate a text representation of a flatbuffer in JSON format.
|
||||||
bool GenerateTextFromTable(const Parser &parser, const void *table,
|
const char *GenerateTextFromTable(const Parser &parser, const void *table,
|
||||||
const std::string &table_name, std::string *_text) {
|
const std::string &table_name, std::string *_text) {
|
||||||
auto struct_def = parser.LookupStruct(table_name);
|
auto struct_def = parser.LookupStruct(table_name);
|
||||||
if (struct_def == nullptr) { return false; }
|
if (struct_def == nullptr) { return false; }
|
||||||
@@ -389,7 +388,7 @@ bool GenerateTextFromTable(const Parser &parser, const void *table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a text representation of a flatbuffer in JSON format.
|
// Generate a text representation of a flatbuffer in JSON format.
|
||||||
bool GenerateText(const Parser &parser, const void *flatbuffer,
|
const char *GenerateText(const Parser &parser, const void *flatbuffer,
|
||||||
std::string *_text) {
|
std::string *_text) {
|
||||||
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
|
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
|
||||||
auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
|
auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
|
||||||
@@ -402,21 +401,24 @@ static std::string TextFileName(const std::string &path,
|
|||||||
return path + file_name + ".json";
|
return path + file_name + ".json";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateTextFile(const Parser &parser, const std::string &path,
|
const char *GenerateTextFile(const Parser &parser, const std::string &path,
|
||||||
const std::string &file_name) {
|
const std::string &file_name) {
|
||||||
if (parser.opts.use_flexbuffers) {
|
if (parser.opts.use_flexbuffers) {
|
||||||
std::string json;
|
std::string json;
|
||||||
parser.flex_root_.ToString(true, parser.opts.strict_json, json);
|
parser.flex_root_.ToString(true, parser.opts.strict_json, json);
|
||||||
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(),
|
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(),
|
||||||
json.c_str(), json.size(), true);
|
json.c_str(), json.size(), true)
|
||||||
|
? nullptr
|
||||||
|
: "SaveFile failed";
|
||||||
}
|
}
|
||||||
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true;
|
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return nullptr;
|
||||||
std::string text;
|
std::string text;
|
||||||
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) {
|
auto err = GenerateText(parser, parser.builder_.GetBufferPointer(), &text);
|
||||||
return false;
|
if (err) return err;
|
||||||
}
|
|
||||||
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), text,
|
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(), text,
|
||||||
false);
|
false)
|
||||||
|
? nullptr
|
||||||
|
: "SaveFile failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TextMakeRule(const Parser &parser, const std::string &path,
|
std::string TextMakeRule(const Parser &parser, const std::string &path,
|
||||||
@@ -439,7 +441,11 @@ class TextCodeGenerator : public CodeGenerator {
|
|||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser &parser, const std::string &path,
|
||||||
const std::string &filename) override {
|
const std::string &filename) override {
|
||||||
if (!GenerateTextFile(parser, path, filename)) { return Status::ERROR; }
|
auto err = GenerateTextFile(parser, path, filename);
|
||||||
|
if (err) {
|
||||||
|
status_detail = " (" + std::string(err) + ")";
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ void FuzzTest2() {
|
|||||||
parser.opts.indent_step = 0;
|
parser.opts.indent_step = 0;
|
||||||
auto result =
|
auto result =
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
|
|
||||||
if (jsongen != json) {
|
if (jsongen != json) {
|
||||||
// These strings are larger than a megabyte, so we show the bytes around
|
// These strings are larger than a megabyte, so we show the bytes around
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void JsonDefaultTest(const std::string& tests_data_path) {
|
|||||||
FinishMonsterBuffer(builder, color_monster.Finish());
|
FinishMonsterBuffer(builder, color_monster.Finish());
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
// default value of the "color" field is Blue
|
// default value of the "color" field is Blue
|
||||||
TEST_EQ(std::string::npos != jsongen.find("color: \"Blue\""), true);
|
TEST_EQ(std::string::npos != jsongen.find("color: \"Blue\""), true);
|
||||||
// default value of the "testf" field is 3.14159
|
// default value of the "testf" field is 3.14159
|
||||||
@@ -66,7 +66,7 @@ void JsonEnumsTest(const std::string& tests_data_path) {
|
|||||||
FinishMonsterBuffer(builder, color_monster.Finish());
|
FinishMonsterBuffer(builder, color_monster.Finish());
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ(std::string::npos != jsongen.find("color: \"Red Blue\""), true);
|
TEST_EQ(std::string::npos != jsongen.find("color: \"Red Blue\""), true);
|
||||||
// Test forward compatibility with 'output_enum_identifiers = true'.
|
// Test forward compatibility with 'output_enum_identifiers = true'.
|
||||||
// Current Color doesn't have '(1u << 2)' field, let's add it.
|
// Current Color doesn't have '(1u << 2)' field, let's add it.
|
||||||
@@ -79,7 +79,7 @@ void JsonEnumsTest(const std::string& tests_data_path) {
|
|||||||
static_cast<Color>((1u << 2) | Color_Blue | Color_Red));
|
static_cast<Color>((1u << 2) | Color_Blue | Color_Red));
|
||||||
FinishMonsterBuffer(builder, future_color.Finish());
|
FinishMonsterBuffer(builder, future_color.Finish());
|
||||||
result = GenerateText(parser, builder.GetBufferPointer(), &future_json);
|
result = GenerateText(parser, builder.GetBufferPointer(), &future_json);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ(std::string::npos != future_json.find("color: 13"), true);
|
TEST_EQ(std::string::npos != future_json.find("color: 13"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ void JsonOptionalTest(const std::string& tests_data_path, bool default_scalars)
|
|||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result =
|
auto result =
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
|
TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +199,7 @@ root_type JsonUnionStructTest;
|
|||||||
std::string json_generated;
|
std::string json_generated;
|
||||||
auto generate_result =
|
auto generate_result =
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &json_generated);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &json_generated);
|
||||||
TEST_EQ(true, generate_result);
|
TEST_NULL(generate_result);
|
||||||
TEST_EQ_STR(json_source, json_generated.c_str());
|
TEST_EQ_STR(json_source, json_generated.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -626,7 +626,7 @@ void TestMonsterExtraFloats(const std::string &tests_data_path) {
|
|||||||
TEST_EQ(def_extra->d3(), -infinity_d);
|
TEST_EQ(def_extra->d3(), -infinity_d);
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result = GenerateText(parser, def_obj, &jsongen);
|
auto result = GenerateText(parser, def_obj, &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
// Check expected default values.
|
// Check expected default values.
|
||||||
TEST_EQ(std::string::npos != jsongen.find("f0: nan"), true);
|
TEST_EQ(std::string::npos != jsongen.find("f0: nan"), true);
|
||||||
TEST_EQ(std::string::npos != jsongen.find("f1: nan"), true);
|
TEST_EQ(std::string::npos != jsongen.find("f1: nan"), true);
|
||||||
@@ -777,7 +777,7 @@ void ParseAndGenerateTextTest(const std::string &tests_data_path, bool binary) {
|
|||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result =
|
auto result =
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
|
TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
|
||||||
|
|
||||||
// We can also do the above using the convenient Registry that knows about
|
// We can also do the above using the convenient Registry that knows about
|
||||||
@@ -815,9 +815,8 @@ void ParseAndGenerateTextTest(const std::string &tests_data_path, bool binary) {
|
|||||||
// request natural printing for utf-8 strings
|
// request natural printing for utf-8 strings
|
||||||
parser.opts.natural_utf8 = true;
|
parser.opts.natural_utf8 = true;
|
||||||
parser.opts.strict_json = true;
|
parser.opts.strict_json = true;
|
||||||
TEST_EQ(
|
TEST_NULL(
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen_utf8),
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen_utf8));
|
||||||
true);
|
|
||||||
TEST_EQ_STR(jsongen_utf8.c_str(), jsonfile_utf8.c_str());
|
TEST_EQ_STR(jsongen_utf8.c_str(), jsonfile_utf8.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -455,8 +455,8 @@ T TestValue(const char *json, const char *type_name,
|
|||||||
// Check with print.
|
// Check with print.
|
||||||
std::string print_back;
|
std::string print_back;
|
||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
TEST_EQ(GenerateText(parser, parser.builder_.GetBufferPointer(), &print_back),
|
TEST_NULL(
|
||||||
true);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &print_back));
|
||||||
// restore value from its default
|
// restore value from its default
|
||||||
if (check_default) { TEST_EQ(parser.Parse(print_back.c_str()), true); }
|
if (check_default) { TEST_EQ(parser.Parse(print_back.c_str()), true); }
|
||||||
|
|
||||||
@@ -713,7 +713,7 @@ void UnicodeTest() {
|
|||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
auto result =
|
auto result =
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(),
|
TEST_EQ_STR(jsongen.c_str(),
|
||||||
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||||
"\\u5225\\u30B5\\u30A4\\u30C8\\u20AC\\u0080\\uD83D\\uDE0E\"}");
|
"\\u5225\\u30B5\\u30A4\\u30C8\\u20AC\\u0080\\uD83D\\uDE0E\"}");
|
||||||
@@ -733,7 +733,7 @@ void UnicodeTestAllowNonUTF8() {
|
|||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
auto result =
|
auto result =
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(
|
TEST_EQ_STR(
|
||||||
jsongen.c_str(),
|
jsongen.c_str(),
|
||||||
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
"{F: \"\\u20AC\\u00A2\\u30E6\\u30FC\\u30B6\\u30FC"
|
||||||
@@ -759,7 +759,7 @@ void UnicodeTestGenerateTextFailsOnNonUTF8() {
|
|||||||
parser.opts.allow_non_utf8 = false;
|
parser.opts.allow_non_utf8 = false;
|
||||||
auto result =
|
auto result =
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, false);
|
TEST_EQ_STR(result, "string contains non-utf8 bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnicodeSurrogatesTest() {
|
void UnicodeSurrogatesTest() {
|
||||||
@@ -800,7 +800,7 @@ void UnknownFieldsTest() {
|
|||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
auto result =
|
auto result =
|
||||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(), "{str: \"test\",i: 10}");
|
TEST_EQ_STR(jsongen.c_str(), "{str: \"test\",i: 10}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -317,9 +317,9 @@ void ParseProtoBufAsciiTest() {
|
|||||||
TEST_EQ(parser.Parse("{ A [1 2] C { B:2 }}"), true);
|
TEST_EQ(parser.Parse("{ A [1 2] C { B:2 }}"), true);
|
||||||
// Similarly, in text output, it should omit these.
|
// Similarly, in text output, it should omit these.
|
||||||
std::string text;
|
std::string text;
|
||||||
auto ok = flatbuffers::GenerateText(
|
auto err = flatbuffers::GenerateText(
|
||||||
parser, parser.builder_.GetBufferPointer(), &text);
|
parser, parser.builder_.GetBufferPointer(), &text);
|
||||||
TEST_EQ(ok, true);
|
TEST_NULL(err);
|
||||||
TEST_EQ_STR(text.c_str(),
|
TEST_EQ_STR(text.c_str(),
|
||||||
"{\n A [\n 1\n 2\n ]\n C {\n B: 2\n }\n}\n");
|
"{\n A [\n 1\n 2\n ]\n C {\n B: 2\n }\n}\n");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,12 +120,12 @@ void GenerateTableTextTest(const std::string &tests_data_path) {
|
|||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result = GenerateTextFromTable(parser, monster, "MyGame.Example.Monster",
|
auto result = GenerateTextFromTable(parser, monster, "MyGame.Example.Monster",
|
||||||
&jsongen);
|
&jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
// Test sub table
|
// Test sub table
|
||||||
const Vec3 *pos = monster->pos();
|
const Vec3 *pos = monster->pos();
|
||||||
jsongen.clear();
|
jsongen.clear();
|
||||||
result = GenerateTextFromTable(parser, pos, "MyGame.Example.Vec3", &jsongen);
|
result = GenerateTextFromTable(parser, pos, "MyGame.Example.Vec3", &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(
|
TEST_EQ_STR(
|
||||||
jsongen.c_str(),
|
jsongen.c_str(),
|
||||||
"{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}");
|
"{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}");
|
||||||
@@ -133,13 +133,13 @@ void GenerateTableTextTest(const std::string &tests_data_path) {
|
|||||||
jsongen.clear();
|
jsongen.clear();
|
||||||
result =
|
result =
|
||||||
GenerateTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
|
GenerateTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}");
|
TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}");
|
||||||
const Test *test4 = monster->test4()->Get(0);
|
const Test *test4 = monster->test4()->Get(0);
|
||||||
jsongen.clear();
|
jsongen.clear();
|
||||||
result =
|
result =
|
||||||
GenerateTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
|
GenerateTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}");
|
TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ void UnionVectorTest(const std::string &tests_data_path) {
|
|||||||
// Generate text using parsed schema.
|
// Generate text using parsed schema.
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen);
|
auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen);
|
||||||
TEST_EQ(result, true);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(),
|
TEST_EQ_STR(jsongen.c_str(),
|
||||||
"{\n"
|
"{\n"
|
||||||
" main_character_type: \"Rapunzel\",\n"
|
" main_character_type: \"Rapunzel\",\n"
|
||||||
@@ -955,9 +955,8 @@ void FixedLengthArrayJsonTest(const std::string &tests_data_path, bool binary) {
|
|||||||
|
|
||||||
// Export to JSON
|
// Export to JSON
|
||||||
std::string jsonGen;
|
std::string jsonGen;
|
||||||
TEST_EQ(
|
TEST_NULL(
|
||||||
GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen),
|
GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen));
|
||||||
true);
|
|
||||||
|
|
||||||
// Import from JSON
|
// Import from JSON
|
||||||
TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
|
TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
|
||||||
@@ -1082,9 +1081,8 @@ void TestEmbeddedBinarySchema(const std::string &tests_data_path) {
|
|||||||
|
|
||||||
// Export to JSON
|
// Export to JSON
|
||||||
std::string jsonGen;
|
std::string jsonGen;
|
||||||
TEST_EQ(
|
TEST_NULL(
|
||||||
GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen),
|
GenerateText(parserOrg, parserOrg.builder_.GetBufferPointer(), &jsonGen));
|
||||||
true);
|
|
||||||
|
|
||||||
// Import from JSON
|
// Import from JSON
|
||||||
TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
|
TEST_EQ(parserGen.Parse(jsonGen.c_str()), true);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#define TEST_EQ(exp, val) TestEq(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, "")
|
#define TEST_EQ(exp, val) TestEq(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, "")
|
||||||
#define TEST_NE(exp, val) TestNe(exp, val, "'" #exp "' == '" #val "'", __FILE__, __LINE__, "")
|
#define TEST_NE(exp, val) TestNe(exp, val, "'" #exp "' == '" #val "'", __FILE__, __LINE__, "")
|
||||||
#define TEST_ASSERT(val) TestEq(true, !!(val), "'" "true" "' != '" #val "'", __FILE__, __LINE__, "")
|
#define TEST_ASSERT(val) TestEq(true, !!(val), "'" "true" "' != '" #val "'", __FILE__, __LINE__, "")
|
||||||
|
#define TEST_NULL(val) TestEq(true, (val) == nullptr, "'" "nullptr" "' != '" #val "'", __FILE__, __LINE__, "")
|
||||||
#define TEST_NOTNULL(val) TestEq(true, (val) != nullptr, "'" "nullptr" "' == '" #val "'", __FILE__, __LINE__, "")
|
#define TEST_NOTNULL(val) TestEq(true, (val) != nullptr, "'" "nullptr" "' == '" #val "'", __FILE__, __LINE__, "")
|
||||||
#define TEST_EQ_STR(exp, val) TestEqStr(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, "")
|
#define TEST_EQ_STR(exp, val) TestEqStr(exp, val, "'" #exp "' != '" #val "'", __FILE__, __LINE__, "")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user