/src/flatbuffers/src/idl_gen_text.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2014 Google Inc. All rights reserved. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | // independent from idl_parser, since this code is not needed for most clients |
18 | | #include "idl_gen_text.h" |
19 | | |
20 | | #include <algorithm> |
21 | | |
22 | | #include "flatbuffers/base.h" |
23 | | #include "flatbuffers/code_generator.h" |
24 | | #include "flatbuffers/flatbuffers.h" |
25 | | #include "flatbuffers/flexbuffers.h" |
26 | | #include "flatbuffers/idl.h" |
27 | | #include "flatbuffers/util.h" |
28 | | |
29 | | namespace flatbuffers { |
30 | | |
31 | | struct PrintScalarTag {}; |
32 | | struct PrintPointerTag {}; |
33 | | template <typename T> |
34 | | struct PrintTag { |
35 | | typedef PrintScalarTag type; |
36 | | }; |
37 | | template <> |
38 | | struct PrintTag<const void*> { |
39 | | typedef PrintPointerTag type; |
40 | | }; |
41 | | |
42 | | struct JsonPrinter { |
43 | | // If indentation is less than 0, that indicates we don't want any newlines |
44 | | // either. |
45 | 2.13M | void AddNewLine() { |
46 | 2.13M | if (opts.indent_step >= 0) text += '\n'; |
47 | 2.13M | } |
48 | | |
49 | 1.73M | void AddIndent(int ident) { text.append(ident, ' '); } |
50 | | |
51 | 612k | int Indent() const { return std::max(opts.indent_step, 0); } |
52 | | |
53 | | // Output an identifier with or without quotes depending on strictness. |
54 | 708k | void OutputIdentifier(const std::string& name) { |
55 | 708k | if (opts.strict_json) text += '\"'; |
56 | 708k | text += name; |
57 | 708k | if (opts.strict_json) text += '\"'; |
58 | 708k | } |
59 | | |
60 | | // Print (and its template specialization below for pointers) generate text |
61 | | // for a single FlatBuffer value into JSON format. |
62 | | // The general case for scalars: |
63 | | template <typename T> |
64 | 785k | void PrintScalar(T val, const Type& type, int /*indent*/) { |
65 | 785k | if (IsBool(type.base_type)) { |
66 | 35.3k | text += val != 0 ? "true" : "false"; |
67 | 35.3k | return; // done |
68 | 35.3k | } |
69 | | |
70 | 750k | if (opts.output_enum_identifiers && type.enum_def) { |
71 | 37.6k | const auto& enum_def = *type.enum_def; |
72 | 37.6k | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { |
73 | 19.0k | text += '\"'; |
74 | 19.0k | text += ev->name; |
75 | 19.0k | text += '\"'; |
76 | 19.0k | return; // done |
77 | 19.0k | } else if (val && enum_def.attributes.Lookup("bit_flags")) { |
78 | 14.8k | const auto entry_len = text.length(); |
79 | 14.8k | const auto u64 = static_cast<uint64_t>(val); |
80 | 14.8k | uint64_t mask = 0; |
81 | 14.8k | text += '\"'; |
82 | 14.8k | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); |
83 | 59.5k | it != e; ++it) { |
84 | 44.6k | auto f = (*it)->GetAsUInt64(); |
85 | 44.6k | if (f & u64) { |
86 | 19.3k | mask |= f; |
87 | 19.3k | text += (*it)->name; |
88 | 19.3k | text += ' '; |
89 | 19.3k | } |
90 | 44.6k | } |
91 | | // Don't slice if (u64 != mask) |
92 | 14.8k | if (mask && (u64 == mask)) { |
93 | 7.10k | text[text.length() - 1] = '\"'; |
94 | 7.10k | return; // done |
95 | 7.10k | } |
96 | 7.77k | text.resize(entry_len); // restore |
97 | 7.77k | } |
98 | | // print as numeric value |
99 | 37.6k | } |
100 | | |
101 | 724k | text += NumToString(val); |
102 | 724k | return; |
103 | 750k | } void flatbuffers::JsonPrinter::PrintScalar<unsigned char>(unsigned char, flatbuffers::Type const&, int) Line | Count | Source | 64 | 84.0k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 84.0k | if (IsBool(type.base_type)) { | 66 | 35.3k | text += val != 0 ? "true" : "false"; | 67 | 35.3k | return; // done | 68 | 35.3k | } | 69 | | | 70 | 48.7k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 32.9k | const auto& enum_def = *type.enum_def; | 72 | 32.9k | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 17.7k | text += '\"'; | 74 | 17.7k | text += ev->name; | 75 | 17.7k | text += '\"'; | 76 | 17.7k | return; // done | 77 | 17.7k | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 12.4k | const auto entry_len = text.length(); | 79 | 12.4k | const auto u64 = static_cast<uint64_t>(val); | 80 | 12.4k | uint64_t mask = 0; | 81 | 12.4k | text += '\"'; | 82 | 12.4k | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 49.7k | it != e; ++it) { | 84 | 37.2k | auto f = (*it)->GetAsUInt64(); | 85 | 37.2k | if (f & u64) { | 86 | 16.5k | mask |= f; | 87 | 16.5k | text += (*it)->name; | 88 | 16.5k | text += ' '; | 89 | 16.5k | } | 90 | 37.2k | } | 91 | | // Don't slice if (u64 != mask) | 92 | 12.4k | if (mask && (u64 == mask)) { | 93 | 6.30k | text[text.length() - 1] = '\"'; | 94 | 6.30k | return; // done | 95 | 6.30k | } | 96 | 6.12k | text.resize(entry_len); // restore | 97 | 6.12k | } | 98 | | // print as numeric value | 99 | 32.9k | } | 100 | | | 101 | 24.6k | text += NumToString(val); | 102 | 24.6k | return; | 103 | 48.7k | } |
void flatbuffers::JsonPrinter::PrintScalar<signed char>(signed char, flatbuffers::Type const&, int) Line | Count | Source | 64 | 31.2k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 31.2k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 31.2k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 1.71k | const auto& enum_def = *type.enum_def; | 72 | 1.71k | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 980 | text += '\"'; | 74 | 980 | text += ev->name; | 75 | 980 | text += '\"'; | 76 | 980 | return; // done | 77 | 980 | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 0 | const auto entry_len = text.length(); | 79 | 0 | const auto u64 = static_cast<uint64_t>(val); | 80 | 0 | uint64_t mask = 0; | 81 | 0 | text += '\"'; | 82 | 0 | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 0 | it != e; ++it) { | 84 | 0 | auto f = (*it)->GetAsUInt64(); | 85 | 0 | if (f & u64) { | 86 | 0 | mask |= f; | 87 | 0 | text += (*it)->name; | 88 | 0 | text += ' '; | 89 | 0 | } | 90 | 0 | } | 91 | | // Don't slice if (u64 != mask) | 92 | 0 | if (mask && (u64 == mask)) { | 93 | 0 | text[text.length() - 1] = '\"'; | 94 | 0 | return; // done | 95 | 0 | } | 96 | 0 | text.resize(entry_len); // restore | 97 | 0 | } | 98 | | // print as numeric value | 99 | 1.71k | } | 100 | | | 101 | 30.3k | text += NumToString(val); | 102 | 30.3k | return; | 103 | 31.2k | } |
void flatbuffers::JsonPrinter::PrintScalar<short>(short, flatbuffers::Type const&, int) Line | Count | Source | 64 | 35.7k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 35.7k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 35.7k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 0 | const auto& enum_def = *type.enum_def; | 72 | 0 | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 0 | text += '\"'; | 74 | 0 | text += ev->name; | 75 | 0 | text += '\"'; | 76 | 0 | return; // done | 77 | 0 | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 0 | const auto entry_len = text.length(); | 79 | 0 | const auto u64 = static_cast<uint64_t>(val); | 80 | 0 | uint64_t mask = 0; | 81 | 0 | text += '\"'; | 82 | 0 | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 0 | it != e; ++it) { | 84 | 0 | auto f = (*it)->GetAsUInt64(); | 85 | 0 | if (f & u64) { | 86 | 0 | mask |= f; | 87 | 0 | text += (*it)->name; | 88 | 0 | text += ' '; | 89 | 0 | } | 90 | 0 | } | 91 | | // Don't slice if (u64 != mask) | 92 | 0 | if (mask && (u64 == mask)) { | 93 | 0 | text[text.length() - 1] = '\"'; | 94 | 0 | return; // done | 95 | 0 | } | 96 | 0 | text.resize(entry_len); // restore | 97 | 0 | } | 98 | | // print as numeric value | 99 | 0 | } | 100 | | | 101 | 35.7k | text += NumToString(val); | 102 | 35.7k | return; | 103 | 35.7k | } |
void flatbuffers::JsonPrinter::PrintScalar<unsigned short>(unsigned short, flatbuffers::Type const&, int) Line | Count | Source | 64 | 107k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 107k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 107k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 0 | const auto& enum_def = *type.enum_def; | 72 | 0 | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 0 | text += '\"'; | 74 | 0 | text += ev->name; | 75 | 0 | text += '\"'; | 76 | 0 | return; // done | 77 | 0 | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 0 | const auto entry_len = text.length(); | 79 | 0 | const auto u64 = static_cast<uint64_t>(val); | 80 | 0 | uint64_t mask = 0; | 81 | 0 | text += '\"'; | 82 | 0 | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 0 | it != e; ++it) { | 84 | 0 | auto f = (*it)->GetAsUInt64(); | 85 | 0 | if (f & u64) { | 86 | 0 | mask |= f; | 87 | 0 | text += (*it)->name; | 88 | 0 | text += ' '; | 89 | 0 | } | 90 | 0 | } | 91 | | // Don't slice if (u64 != mask) | 92 | 0 | if (mask && (u64 == mask)) { | 93 | 0 | text[text.length() - 1] = '\"'; | 94 | 0 | return; // done | 95 | 0 | } | 96 | 0 | text.resize(entry_len); // restore | 97 | 0 | } | 98 | | // print as numeric value | 99 | 0 | } | 100 | | | 101 | 107k | text += NumToString(val); | 102 | 107k | return; | 103 | 107k | } |
void flatbuffers::JsonPrinter::PrintScalar<int>(int, flatbuffers::Type const&, int) Line | Count | Source | 64 | 44.1k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 44.1k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 44.1k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 0 | const auto& enum_def = *type.enum_def; | 72 | 0 | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 0 | text += '\"'; | 74 | 0 | text += ev->name; | 75 | 0 | text += '\"'; | 76 | 0 | return; // done | 77 | 0 | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 0 | const auto entry_len = text.length(); | 79 | 0 | const auto u64 = static_cast<uint64_t>(val); | 80 | 0 | uint64_t mask = 0; | 81 | 0 | text += '\"'; | 82 | 0 | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 0 | it != e; ++it) { | 84 | 0 | auto f = (*it)->GetAsUInt64(); | 85 | 0 | if (f & u64) { | 86 | 0 | mask |= f; | 87 | 0 | text += (*it)->name; | 88 | 0 | text += ' '; | 89 | 0 | } | 90 | 0 | } | 91 | | // Don't slice if (u64 != mask) | 92 | 0 | if (mask && (u64 == mask)) { | 93 | 0 | text[text.length() - 1] = '\"'; | 94 | 0 | return; // done | 95 | 0 | } | 96 | 0 | text.resize(entry_len); // restore | 97 | 0 | } | 98 | | // print as numeric value | 99 | 0 | } | 100 | | | 101 | 44.1k | text += NumToString(val); | 102 | 44.1k | return; | 103 | 44.1k | } |
void flatbuffers::JsonPrinter::PrintScalar<unsigned int>(unsigned int, flatbuffers::Type const&, int) Line | Count | Source | 64 | 64.9k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 64.9k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 64.9k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 0 | const auto& enum_def = *type.enum_def; | 72 | 0 | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 0 | text += '\"'; | 74 | 0 | text += ev->name; | 75 | 0 | text += '\"'; | 76 | 0 | return; // done | 77 | 0 | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 0 | const auto entry_len = text.length(); | 79 | 0 | const auto u64 = static_cast<uint64_t>(val); | 80 | 0 | uint64_t mask = 0; | 81 | 0 | text += '\"'; | 82 | 0 | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 0 | it != e; ++it) { | 84 | 0 | auto f = (*it)->GetAsUInt64(); | 85 | 0 | if (f & u64) { | 86 | 0 | mask |= f; | 87 | 0 | text += (*it)->name; | 88 | 0 | text += ' '; | 89 | 0 | } | 90 | 0 | } | 91 | | // Don't slice if (u64 != mask) | 92 | 0 | if (mask && (u64 == mask)) { | 93 | 0 | text[text.length() - 1] = '\"'; | 94 | 0 | return; // done | 95 | 0 | } | 96 | 0 | text.resize(entry_len); // restore | 97 | 0 | } | 98 | | // print as numeric value | 99 | 0 | } | 100 | | | 101 | 64.9k | text += NumToString(val); | 102 | 64.9k | return; | 103 | 64.9k | } |
void flatbuffers::JsonPrinter::PrintScalar<long>(long, flatbuffers::Type const&, int) Line | Count | Source | 64 | 94.5k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 94.5k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 94.5k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 0 | const auto& enum_def = *type.enum_def; | 72 | 0 | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 0 | text += '\"'; | 74 | 0 | text += ev->name; | 75 | 0 | text += '\"'; | 76 | 0 | return; // done | 77 | 0 | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 0 | const auto entry_len = text.length(); | 79 | 0 | const auto u64 = static_cast<uint64_t>(val); | 80 | 0 | uint64_t mask = 0; | 81 | 0 | text += '\"'; | 82 | 0 | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 0 | it != e; ++it) { | 84 | 0 | auto f = (*it)->GetAsUInt64(); | 85 | 0 | if (f & u64) { | 86 | 0 | mask |= f; | 87 | 0 | text += (*it)->name; | 88 | 0 | text += ' '; | 89 | 0 | } | 90 | 0 | } | 91 | | // Don't slice if (u64 != mask) | 92 | 0 | if (mask && (u64 == mask)) { | 93 | 0 | text[text.length() - 1] = '\"'; | 94 | 0 | return; // done | 95 | 0 | } | 96 | 0 | text.resize(entry_len); // restore | 97 | 0 | } | 98 | | // print as numeric value | 99 | 0 | } | 100 | | | 101 | 94.5k | text += NumToString(val); | 102 | 94.5k | return; | 103 | 94.5k | } |
void flatbuffers::JsonPrinter::PrintScalar<unsigned long>(unsigned long, flatbuffers::Type const&, int) Line | Count | Source | 64 | 147k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 147k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 147k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 3.06k | const auto& enum_def = *type.enum_def; | 72 | 3.06k | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 284 | text += '\"'; | 74 | 284 | text += ev->name; | 75 | 284 | text += '\"'; | 76 | 284 | return; // done | 77 | 2.77k | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 2.44k | const auto entry_len = text.length(); | 79 | 2.44k | const auto u64 = static_cast<uint64_t>(val); | 80 | 2.44k | uint64_t mask = 0; | 81 | 2.44k | text += '\"'; | 82 | 2.44k | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 9.79k | it != e; ++it) { | 84 | 7.34k | auto f = (*it)->GetAsUInt64(); | 85 | 7.34k | if (f & u64) { | 86 | 2.82k | mask |= f; | 87 | 2.82k | text += (*it)->name; | 88 | 2.82k | text += ' '; | 89 | 2.82k | } | 90 | 7.34k | } | 91 | | // Don't slice if (u64 != mask) | 92 | 2.44k | if (mask && (u64 == mask)) { | 93 | 806 | text[text.length() - 1] = '\"'; | 94 | 806 | return; // done | 95 | 806 | } | 96 | 1.64k | text.resize(entry_len); // restore | 97 | 1.64k | } | 98 | | // print as numeric value | 99 | 3.06k | } | 100 | | | 101 | 146k | text += NumToString(val); | 102 | 146k | return; | 103 | 147k | } |
void flatbuffers::JsonPrinter::PrintScalar<float>(float, flatbuffers::Type const&, int) Line | Count | Source | 64 | 69.7k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 69.7k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 69.7k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 0 | const auto& enum_def = *type.enum_def; | 72 | 0 | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 0 | text += '\"'; | 74 | 0 | text += ev->name; | 75 | 0 | text += '\"'; | 76 | 0 | return; // done | 77 | 0 | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 0 | const auto entry_len = text.length(); | 79 | 0 | const auto u64 = static_cast<uint64_t>(val); | 80 | 0 | uint64_t mask = 0; | 81 | 0 | text += '\"'; | 82 | 0 | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 0 | it != e; ++it) { | 84 | 0 | auto f = (*it)->GetAsUInt64(); | 85 | 0 | if (f & u64) { | 86 | 0 | mask |= f; | 87 | 0 | text += (*it)->name; | 88 | 0 | text += ' '; | 89 | 0 | } | 90 | 0 | } | 91 | | // Don't slice if (u64 != mask) | 92 | 0 | if (mask && (u64 == mask)) { | 93 | 0 | text[text.length() - 1] = '\"'; | 94 | 0 | return; // done | 95 | 0 | } | 96 | 0 | text.resize(entry_len); // restore | 97 | 0 | } | 98 | | // print as numeric value | 99 | 0 | } | 100 | | | 101 | 69.7k | text += NumToString(val); | 102 | 69.7k | return; | 103 | 69.7k | } |
void flatbuffers::JsonPrinter::PrintScalar<double>(double, flatbuffers::Type const&, int) Line | Count | Source | 64 | 105k | void PrintScalar(T val, const Type& type, int /*indent*/) { | 65 | 105k | if (IsBool(type.base_type)) { | 66 | 0 | text += val != 0 ? "true" : "false"; | 67 | 0 | return; // done | 68 | 0 | } | 69 | | | 70 | 105k | if (opts.output_enum_identifiers && type.enum_def) { | 71 | 0 | const auto& enum_def = *type.enum_def; | 72 | 0 | if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) { | 73 | 0 | text += '\"'; | 74 | 0 | text += ev->name; | 75 | 0 | text += '\"'; | 76 | 0 | return; // done | 77 | 0 | } else if (val && enum_def.attributes.Lookup("bit_flags")) { | 78 | 0 | const auto entry_len = text.length(); | 79 | 0 | const auto u64 = static_cast<uint64_t>(val); | 80 | 0 | uint64_t mask = 0; | 81 | 0 | text += '\"'; | 82 | 0 | for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end(); | 83 | 0 | it != e; ++it) { | 84 | 0 | auto f = (*it)->GetAsUInt64(); | 85 | 0 | if (f & u64) { | 86 | 0 | mask |= f; | 87 | 0 | text += (*it)->name; | 88 | 0 | text += ' '; | 89 | 0 | } | 90 | 0 | } | 91 | | // Don't slice if (u64 != mask) | 92 | 0 | if (mask && (u64 == mask)) { | 93 | 0 | text[text.length() - 1] = '\"'; | 94 | 0 | return; // done | 95 | 0 | } | 96 | 0 | text.resize(entry_len); // restore | 97 | 0 | } | 98 | | // print as numeric value | 99 | 0 | } | 100 | | | 101 | 105k | text += NumToString(val); | 102 | 105k | return; | 103 | 105k | } |
|
104 | | |
105 | 516k | void AddComma() { |
106 | 516k | if (!opts.protobuf_ascii_alike) text += ','; |
107 | 516k | } |
108 | | |
109 | | // Print a vector or an array of JSON values, comma seperated, wrapped in |
110 | | // "[]". |
111 | | template <typename Container, typename SizeT = typename Container::size_type> |
112 | | const char* PrintContainer(PrintScalarTag, const Container& c, SizeT size, |
113 | 3.75k | const Type& type, int indent, const uint8_t*) { |
114 | 3.75k | const auto elem_indent = indent + Indent(); |
115 | 3.75k | text += '['; |
116 | 3.75k | AddNewLine(); |
117 | 185k | for (SizeT i = 0; i < size; i++) { |
118 | 181k | if (i) { |
119 | 178k | AddComma(); |
120 | 178k | AddNewLine(); |
121 | 178k | } |
122 | 181k | AddIndent(elem_indent); |
123 | 181k | PrintScalar(c[i], type, elem_indent); |
124 | 181k | } |
125 | 3.75k | AddNewLine(); |
126 | 3.75k | AddIndent(indent); |
127 | 3.75k | text += ']'; |
128 | 3.75k | return nullptr; |
129 | 3.75k | } char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<unsigned char, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<unsigned char, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 113 | 1.56k | const Type& type, int indent, const uint8_t*) { | 114 | 1.56k | const auto elem_indent = indent + Indent(); | 115 | 1.56k | text += '['; | 116 | 1.56k | AddNewLine(); | 117 | 36.3k | for (SizeT i = 0; i < size; i++) { | 118 | 34.8k | if (i) { | 119 | 33.7k | AddComma(); | 120 | 33.7k | AddNewLine(); | 121 | 33.7k | } | 122 | 34.8k | AddIndent(elem_indent); | 123 | 34.8k | PrintScalar(c[i], type, elem_indent); | 124 | 34.8k | } | 125 | 1.56k | AddNewLine(); | 126 | 1.56k | AddIndent(indent); | 127 | 1.56k | text += ']'; | 128 | 1.56k | return nullptr; | 129 | 1.56k | } |
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<signed char, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<signed char, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<short, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<short, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<unsigned short, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<unsigned short, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<int, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<int, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<unsigned int, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<unsigned int, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<long, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<long, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 113 | 778 | const Type& type, int indent, const uint8_t*) { | 114 | 778 | const auto elem_indent = indent + Indent(); | 115 | 778 | text += '['; | 116 | 778 | AddNewLine(); | 117 | 46.2k | for (SizeT i = 0; i < size; i++) { | 118 | 45.4k | if (i) { | 119 | 44.9k | AddComma(); | 120 | 44.9k | AddNewLine(); | 121 | 44.9k | } | 122 | 45.4k | AddIndent(elem_indent); | 123 | 45.4k | PrintScalar(c[i], type, elem_indent); | 124 | 45.4k | } | 125 | 778 | AddNewLine(); | 126 | 778 | AddIndent(indent); | 127 | 778 | text += ']'; | 128 | 778 | return nullptr; | 129 | 778 | } |
char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<unsigned long, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<unsigned long, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 113 | 768 | const Type& type, int indent, const uint8_t*) { | 114 | 768 | const auto elem_indent = indent + Indent(); | 115 | 768 | text += '['; | 116 | 768 | AddNewLine(); | 117 | 44.3k | for (SizeT i = 0; i < size; i++) { | 118 | 43.5k | if (i) { | 119 | 42.9k | AddComma(); | 120 | 42.9k | AddNewLine(); | 121 | 42.9k | } | 122 | 43.5k | AddIndent(elem_indent); | 123 | 43.5k | PrintScalar(c[i], type, elem_indent); | 124 | 43.5k | } | 125 | 768 | AddNewLine(); | 126 | 768 | AddIndent(indent); | 127 | 768 | text += ']'; | 128 | 768 | return nullptr; | 129 | 768 | } |
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<float, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<float, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<double, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<double, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 113 | 644 | const Type& type, int indent, const uint8_t*) { | 114 | 644 | const auto elem_indent = indent + Indent(); | 115 | 644 | text += '['; | 116 | 644 | AddNewLine(); | 117 | 58.2k | for (SizeT i = 0; i < size; i++) { | 118 | 57.5k | if (i) { | 119 | 57.1k | AddComma(); | 120 | 57.1k | AddNewLine(); | 121 | 57.1k | } | 122 | 57.5k | AddIndent(elem_indent); | 123 | 57.5k | PrintScalar(c[i], type, elem_indent); | 124 | 57.5k | } | 125 | 644 | AddNewLine(); | 126 | 644 | AddIndent(indent); | 127 | 644 | text += ']'; | 128 | 644 | return nullptr; | 129 | 644 | } |
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<unsigned char, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<unsigned char, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<signed char, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<signed char, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<short, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<short, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<unsigned short, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<unsigned short, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<int, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<int, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<unsigned int, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<unsigned int, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<long, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<long, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<unsigned long, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<unsigned long, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<float, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<float, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<double, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<double, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) |
130 | | |
131 | | // Print a vector or an array of JSON values, comma seperated, wrapped in |
132 | | // "[]". |
133 | | template <typename Container, typename SizeT = typename Container::size_type> |
134 | | const char* PrintContainer(PrintPointerTag, const Container& c, SizeT size, |
135 | | const Type& type, int indent, |
136 | 6.48k | const uint8_t* prev_val) { |
137 | 6.48k | const auto is_struct = IsStruct(type); |
138 | 6.48k | const auto elem_indent = indent + Indent(); |
139 | 6.48k | text += '['; |
140 | 6.48k | AddNewLine(); |
141 | 240k | for (SizeT i = 0; i < size; i++) { |
142 | 234k | if (i) { |
143 | 230k | AddComma(); |
144 | 230k | AddNewLine(); |
145 | 230k | } |
146 | 234k | AddIndent(elem_indent); |
147 | 234k | auto ptr = is_struct ? reinterpret_cast<const void*>( |
148 | 13.7k | c.Data() + type.struct_def->bytesize * i) |
149 | 234k | : c[i]; |
150 | 234k | auto err = PrintOffset(ptr, type, elem_indent, prev_val, |
151 | 234k | static_cast<soffset_t>(i)); |
152 | 234k | if (err) return err; |
153 | 234k | } |
154 | 6.48k | AddNewLine(); |
155 | 6.48k | AddIndent(indent); |
156 | 6.48k | text += ']'; |
157 | 6.48k | return nullptr; |
158 | 6.48k | } char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<flatbuffers::Offset<void>, unsigned int>, unsigned int>(flatbuffers::PrintPointerTag, flatbuffers::Vector<flatbuffers::Offset<void>, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 136 | 6.48k | const uint8_t* prev_val) { | 137 | 6.48k | const auto is_struct = IsStruct(type); | 138 | 6.48k | const auto elem_indent = indent + Indent(); | 139 | 6.48k | text += '['; | 140 | 6.48k | AddNewLine(); | 141 | 240k | for (SizeT i = 0; i < size; i++) { | 142 | 234k | if (i) { | 143 | 230k | AddComma(); | 144 | 230k | AddNewLine(); | 145 | 230k | } | 146 | 234k | AddIndent(elem_indent); | 147 | 234k | auto ptr = is_struct ? reinterpret_cast<const void*>( | 148 | 13.7k | c.Data() + type.struct_def->bytesize * i) | 149 | 234k | : c[i]; | 150 | 234k | auto err = PrintOffset(ptr, type, elem_indent, prev_val, | 151 | 234k | static_cast<soffset_t>(i)); | 152 | 234k | if (err) return err; | 153 | 234k | } | 154 | 6.48k | AddNewLine(); | 155 | 6.48k | AddIndent(indent); | 156 | 6.48k | text += ']'; | 157 | 6.48k | return nullptr; | 158 | 6.48k | } |
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<flatbuffers::Offset64<void>, unsigned int>, unsigned int>(flatbuffers::PrintPointerTag, flatbuffers::Vector<flatbuffers::Offset64<void>, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<flatbuffers::Offset<void>, (unsigned short)65535>, unsigned short>(flatbuffers::PrintPointerTag, flatbuffers::Array<flatbuffers::Offset<void>, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<flatbuffers::Offset64<void>, (unsigned short)65535>, unsigned short>(flatbuffers::PrintPointerTag, flatbuffers::Array<flatbuffers::Offset64<void>, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*) |
159 | | |
160 | | template <typename T, typename SizeT = uoffset_t> |
161 | | const char* PrintVector(const void* val, const Type& type, int indent, |
162 | 10.2k | const uint8_t* prev_val) { |
163 | 10.2k | typedef Vector<T, SizeT> Container; |
164 | 10.2k | typedef typename PrintTag<typename Container::return_type>::type tag; |
165 | 10.2k | auto& vec = *reinterpret_cast<const Container*>(val); |
166 | 10.2k | return PrintContainer<Container>(tag(), vec, vec.size(), type, indent, |
167 | 10.2k | prev_val); |
168 | 10.2k | } char const* flatbuffers::JsonPrinter::PrintVector<unsigned char, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 162 | 1.56k | const uint8_t* prev_val) { | 163 | 1.56k | typedef Vector<T, SizeT> Container; | 164 | 1.56k | typedef typename PrintTag<typename Container::return_type>::type tag; | 165 | 1.56k | auto& vec = *reinterpret_cast<const Container*>(val); | 166 | 1.56k | return PrintContainer<Container>(tag(), vec, vec.size(), type, indent, | 167 | 1.56k | prev_val); | 168 | 1.56k | } |
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<signed char, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<short, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<unsigned short, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<int, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<unsigned int, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) char const* flatbuffers::JsonPrinter::PrintVector<long, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 162 | 778 | const uint8_t* prev_val) { | 163 | 778 | typedef Vector<T, SizeT> Container; | 164 | 778 | typedef typename PrintTag<typename Container::return_type>::type tag; | 165 | 778 | auto& vec = *reinterpret_cast<const Container*>(val); | 166 | 778 | return PrintContainer<Container>(tag(), vec, vec.size(), type, indent, | 167 | 778 | prev_val); | 168 | 778 | } |
char const* flatbuffers::JsonPrinter::PrintVector<unsigned long, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 162 | 768 | const uint8_t* prev_val) { | 163 | 768 | typedef Vector<T, SizeT> Container; | 164 | 768 | typedef typename PrintTag<typename Container::return_type>::type tag; | 165 | 768 | auto& vec = *reinterpret_cast<const Container*>(val); | 166 | 768 | return PrintContainer<Container>(tag(), vec, vec.size(), type, indent, | 167 | 768 | prev_val); | 168 | 768 | } |
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<float, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) char const* flatbuffers::JsonPrinter::PrintVector<double, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 162 | 644 | const uint8_t* prev_val) { | 163 | 644 | typedef Vector<T, SizeT> Container; | 164 | 644 | typedef typename PrintTag<typename Container::return_type>::type tag; | 165 | 644 | auto& vec = *reinterpret_cast<const Container*>(val); | 166 | 644 | return PrintContainer<Container>(tag(), vec, vec.size(), type, indent, | 167 | 644 | prev_val); | 168 | 644 | } |
char const* flatbuffers::JsonPrinter::PrintVector<flatbuffers::Offset<void>, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) Line | Count | Source | 162 | 6.48k | const uint8_t* prev_val) { | 163 | 6.48k | typedef Vector<T, SizeT> Container; | 164 | 6.48k | typedef typename PrintTag<typename Container::return_type>::type tag; | 165 | 6.48k | auto& vec = *reinterpret_cast<const Container*>(val); | 166 | 6.48k | return PrintContainer<Container>(tag(), vec, vec.size(), type, indent, | 167 | 6.48k | prev_val); | 168 | 6.48k | } |
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<flatbuffers::Offset64<void>, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*) |
169 | | |
170 | | // Print an array a sequence of JSON values, comma separated, wrapped in "[]". |
171 | | template <typename T> |
172 | | const char* PrintArray(const void* val, uint16_t size, const Type& type, |
173 | | |
174 | 0 | int indent) { |
175 | 0 | typedef Array<T, 0xFFFF> Container; |
176 | 0 | typedef typename PrintTag<typename Container::return_type>::type tag; |
177 | 0 | auto& arr = *reinterpret_cast<const Container*>(val); |
178 | 0 | return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr); |
179 | 0 | } Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<unsigned char>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<signed char>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<short>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<unsigned short>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<int>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<unsigned int>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<long>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<unsigned long>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<float>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<double>(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<flatbuffers::Offset<void> >(void const*, unsigned short, flatbuffers::Type const&, int) Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<flatbuffers::Offset64<void> >(void const*, unsigned short, flatbuffers::Type const&, int) |
180 | | |
181 | | const char* PrintOffset(const void* val, const Type& type, int indent, |
182 | 322k | const uint8_t* prev_val, soffset_t vector_index) { |
183 | 322k | switch (type.base_type) { |
184 | 1.85k | case BASE_TYPE_UNION: { |
185 | | // If this assert hits, you have an corrupt buffer, a union type field |
186 | | // was not present or was out of range. |
187 | 1.85k | FLATBUFFERS_ASSERT(prev_val); |
188 | 1.85k | auto union_type_byte = *prev_val; // Always a uint8_t. |
189 | 1.85k | if (vector_index >= 0) { |
190 | 0 | auto type_vec = reinterpret_cast<const Vector<uint8_t>*>( |
191 | 0 | prev_val + ReadScalar<uoffset_t>(prev_val)); |
192 | 0 | union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index)); |
193 | 0 | } |
194 | 1.85k | auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true); |
195 | 1.85k | if (enum_val) { |
196 | 1.85k | return PrintOffset(val, enum_val->union_type, indent, nullptr, -1); |
197 | 1.85k | } else { |
198 | 0 | return "unknown enum value"; |
199 | 0 | } |
200 | 1.85k | } |
201 | 197k | case BASE_TYPE_STRUCT: |
202 | 197k | return GenStruct(*type.struct_def, reinterpret_cast<const Table*>(val), |
203 | 197k | indent); |
204 | 113k | case BASE_TYPE_STRING: { |
205 | 113k | auto s = reinterpret_cast<const String*>(val); |
206 | 113k | bool ok = EscapeString(s->c_str(), s->size(), &text, |
207 | 113k | opts.allow_non_utf8, opts.natural_utf8); |
208 | 113k | return ok ? nullptr : "string contains non-utf8 bytes"; |
209 | 1.85k | } |
210 | 10.2k | case BASE_TYPE_VECTOR: { |
211 | 10.2k | const auto vec_type = type.VectorType(); |
212 | | // Call PrintVector above specifically for each element type: |
213 | | // clang-format off |
214 | 10.2k | switch (vec_type.base_type) { |
215 | 0 | #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ |
216 | 10.2k | case BASE_TYPE_ ## ENUM: { \ |
217 | 10.2k | auto err = PrintVector<CTYPE>(val, vec_type, indent, prev_val); \ |
218 | 10.2k | if (err) return err; \ |
219 | 10.2k | break; } |
220 | 10.2k | FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) |
221 | 10.2k | #undef FLATBUFFERS_TD |
222 | 10.2k | } |
223 | | // clang-format on |
224 | 10.2k | return nullptr; |
225 | 10.2k | } |
226 | 0 | case BASE_TYPE_ARRAY: { |
227 | 0 | const auto vec_type = type.VectorType(); |
228 | | // Call PrintArray above specifically for each element type: |
229 | | // clang-format off |
230 | 0 | switch (vec_type.base_type) { |
231 | 0 | #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ |
232 | 0 | case BASE_TYPE_ ## ENUM: { \ |
233 | 0 | auto err = PrintArray<CTYPE>(val, type.fixed_length, vec_type, indent); \ |
234 | 0 | if (err) return err; \ |
235 | 0 | break; } |
236 | 0 | FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) |
237 | | // Arrays of scalars or structs are only possible. |
238 | 0 | FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) |
239 | 0 | #undef FLATBUFFERS_TD |
240 | 0 | case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0); |
241 | 0 | } |
242 | | // clang-format on |
243 | 0 | return nullptr; |
244 | 0 | } |
245 | 0 | default: |
246 | 0 | FLATBUFFERS_ASSERT(0); |
247 | 0 | return "unknown type"; |
248 | 322k | } |
249 | 322k | } |
250 | | |
251 | | template <typename T> |
252 | 542k | static T GetFieldDefault(const FieldDef& fd) { |
253 | 542k | T val{}; |
254 | 542k | auto check = StringToNumber(fd.value.constant.c_str(), &val); |
255 | 542k | (void)check; |
256 | 542k | FLATBUFFERS_ASSERT(check); |
257 | 542k | return val; |
258 | 542k | } unsigned char flatbuffers::JsonPrinter::GetFieldDefault<unsigned char>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 44.4k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 44.4k | T val{}; | 254 | 44.4k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 44.4k | (void)check; | 256 | 44.4k | FLATBUFFERS_ASSERT(check); | 257 | 44.4k | return val; | 258 | 44.4k | } |
signed char flatbuffers::JsonPrinter::GetFieldDefault<signed char>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 25.3k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 25.3k | T val{}; | 254 | 25.3k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 25.3k | (void)check; | 256 | 25.3k | FLATBUFFERS_ASSERT(check); | 257 | 25.3k | return val; | 258 | 25.3k | } |
short flatbuffers::JsonPrinter::GetFieldDefault<short>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 29.8k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 29.8k | T val{}; | 254 | 29.8k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 29.8k | (void)check; | 256 | 29.8k | FLATBUFFERS_ASSERT(check); | 257 | 29.8k | return val; | 258 | 29.8k | } |
unsigned short flatbuffers::JsonPrinter::GetFieldDefault<unsigned short>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 107k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 107k | T val{}; | 254 | 107k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 107k | (void)check; | 256 | 107k | FLATBUFFERS_ASSERT(check); | 257 | 107k | return val; | 258 | 107k | } |
int flatbuffers::JsonPrinter::GetFieldDefault<int>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 44.1k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 44.1k | T val{}; | 254 | 44.1k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 44.1k | (void)check; | 256 | 44.1k | FLATBUFFERS_ASSERT(check); | 257 | 44.1k | return val; | 258 | 44.1k | } |
unsigned int flatbuffers::JsonPrinter::GetFieldDefault<unsigned int>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 39.0k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 39.0k | T val{}; | 254 | 39.0k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 39.0k | (void)check; | 256 | 39.0k | FLATBUFFERS_ASSERT(check); | 257 | 39.0k | return val; | 258 | 39.0k | } |
long flatbuffers::JsonPrinter::GetFieldDefault<long>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 49.0k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 49.0k | T val{}; | 254 | 49.0k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 49.0k | (void)check; | 256 | 49.0k | FLATBUFFERS_ASSERT(check); | 257 | 49.0k | return val; | 258 | 49.0k | } |
unsigned long flatbuffers::JsonPrinter::GetFieldDefault<unsigned long>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 103k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 103k | T val{}; | 254 | 103k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 103k | (void)check; | 256 | 103k | FLATBUFFERS_ASSERT(check); | 257 | 103k | return val; | 258 | 103k | } |
float flatbuffers::JsonPrinter::GetFieldDefault<float>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 55.2k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 55.2k | T val{}; | 254 | 55.2k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 55.2k | (void)check; | 256 | 55.2k | FLATBUFFERS_ASSERT(check); | 257 | 55.2k | return val; | 258 | 55.2k | } |
double flatbuffers::JsonPrinter::GetFieldDefault<double>(flatbuffers::FieldDef const&) Line | Count | Source | 252 | 43.5k | static T GetFieldDefault(const FieldDef& fd) { | 253 | 43.5k | T val{}; | 254 | 43.5k | auto check = StringToNumber(fd.value.constant.c_str(), &val); | 255 | 43.5k | (void)check; | 256 | 43.5k | FLATBUFFERS_ASSERT(check); | 257 | 43.5k | return val; | 258 | 43.5k | } |
|
259 | | |
260 | | // Generate text for a scalar field. |
261 | | template <typename T> |
262 | | void GenField(const FieldDef& fd, const Table* table, bool fixed, |
263 | 604k | int indent) { |
264 | 604k | if (fixed) { |
265 | 62.0k | PrintScalar( |
266 | 62.0k | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), |
267 | 62.0k | fd.value.type, indent); |
268 | 542k | } else if (fd.IsOptional()) { |
269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); |
270 | 0 | if (opt) { |
271 | 0 | PrintScalar(*opt, fd.value.type, indent); |
272 | 0 | } else { |
273 | 0 | text += "null"; |
274 | 0 | } |
275 | 542k | } else { |
276 | 542k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), |
277 | 542k | fd.value.type, indent); |
278 | 542k | } |
279 | 604k | } void flatbuffers::JsonPrinter::GenField<unsigned char>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 49.2k | int indent) { | 264 | 49.2k | if (fixed) { | 265 | 4.84k | PrintScalar( | 266 | 4.84k | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 4.84k | fd.value.type, indent); | 268 | 44.4k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 44.4k | } else { | 276 | 44.4k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 44.4k | fd.value.type, indent); | 278 | 44.4k | } | 279 | 49.2k | } |
void flatbuffers::JsonPrinter::GenField<signed char>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 31.2k | int indent) { | 264 | 31.2k | if (fixed) { | 265 | 5.94k | PrintScalar( | 266 | 5.94k | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 5.94k | fd.value.type, indent); | 268 | 25.3k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 25.3k | } else { | 276 | 25.3k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 25.3k | fd.value.type, indent); | 278 | 25.3k | } | 279 | 31.2k | } |
void flatbuffers::JsonPrinter::GenField<short>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 35.7k | int indent) { | 264 | 35.7k | if (fixed) { | 265 | 5.94k | PrintScalar( | 266 | 5.94k | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 5.94k | fd.value.type, indent); | 268 | 29.8k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 29.8k | } else { | 276 | 29.8k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 29.8k | fd.value.type, indent); | 278 | 29.8k | } | 279 | 35.7k | } |
void flatbuffers::JsonPrinter::GenField<unsigned short>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 107k | int indent) { | 264 | 107k | if (fixed) { | 265 | 0 | PrintScalar( | 266 | 0 | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 0 | fd.value.type, indent); | 268 | 107k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 107k | } else { | 276 | 107k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 107k | fd.value.type, indent); | 278 | 107k | } | 279 | 107k | } |
void flatbuffers::JsonPrinter::GenField<int>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 44.1k | int indent) { | 264 | 44.1k | if (fixed) { | 265 | 0 | PrintScalar( | 266 | 0 | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 0 | fd.value.type, indent); | 268 | 44.1k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 44.1k | } else { | 276 | 44.1k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 44.1k | fd.value.type, indent); | 278 | 44.1k | } | 279 | 44.1k | } |
void flatbuffers::JsonPrinter::GenField<unsigned int>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 64.9k | int indent) { | 264 | 64.9k | if (fixed) { | 265 | 25.9k | PrintScalar( | 266 | 25.9k | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 25.9k | fd.value.type, indent); | 268 | 39.0k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 39.0k | } else { | 276 | 39.0k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 39.0k | fd.value.type, indent); | 278 | 39.0k | } | 279 | 64.9k | } |
void flatbuffers::JsonPrinter::GenField<long>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 49.0k | int indent) { | 264 | 49.0k | if (fixed) { | 265 | 0 | PrintScalar( | 266 | 0 | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 0 | fd.value.type, indent); | 268 | 49.0k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 49.0k | } else { | 276 | 49.0k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 49.0k | fd.value.type, indent); | 278 | 49.0k | } | 279 | 49.0k | } |
void flatbuffers::JsonPrinter::GenField<unsigned long>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 103k | int indent) { | 264 | 103k | if (fixed) { | 265 | 0 | PrintScalar( | 266 | 0 | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 0 | fd.value.type, indent); | 268 | 103k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 103k | } else { | 276 | 103k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 103k | fd.value.type, indent); | 278 | 103k | } | 279 | 103k | } |
void flatbuffers::JsonPrinter::GenField<float>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 69.7k | int indent) { | 264 | 69.7k | if (fixed) { | 265 | 14.5k | PrintScalar( | 266 | 14.5k | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 14.5k | fd.value.type, indent); | 268 | 55.2k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 55.2k | } else { | 276 | 55.2k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 55.2k | fd.value.type, indent); | 278 | 55.2k | } | 279 | 69.7k | } |
void flatbuffers::JsonPrinter::GenField<double>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int) Line | Count | Source | 263 | 48.3k | int indent) { | 264 | 48.3k | if (fixed) { | 265 | 4.84k | PrintScalar( | 266 | 4.84k | reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset), | 267 | 4.84k | fd.value.type, indent); | 268 | 43.5k | } else if (fd.IsOptional()) { | 269 | 0 | auto opt = table->GetOptional<T, T>(fd.value.offset); | 270 | 0 | if (opt) { | 271 | 0 | PrintScalar(*opt, fd.value.type, indent); | 272 | 0 | } else { | 273 | 0 | text += "null"; | 274 | 0 | } | 275 | 43.5k | } else { | 276 | 43.5k | PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)), | 277 | 43.5k | fd.value.type, indent); | 278 | 43.5k | } | 279 | 48.3k | } |
|
280 | | |
281 | | // Generate text for non-scalar field. |
282 | | const char* GenFieldOffset(const FieldDef& fd, const Table* table, bool fixed, |
283 | 103k | int indent, const uint8_t* prev_val) { |
284 | 103k | const void* val = nullptr; |
285 | 103k | if (fixed) { |
286 | | // The only non-scalar fields in structs are structs or arrays. |
287 | 4.84k | FLATBUFFERS_ASSERT(IsStruct(fd.value.type) || IsArray(fd.value.type)); |
288 | 4.84k | val = reinterpret_cast<const Struct*>(table)->GetStruct<const void*>( |
289 | 4.84k | fd.value.offset); |
290 | 99.0k | } else if (fd.flexbuffer && opts.json_nested_flexbuffers) { |
291 | | // We could verify this FlexBuffer before access, but since this sits |
292 | | // inside a FlatBuffer that we don't know wether it has been verified or |
293 | | // not, there is little point making this part safer than the parent.. |
294 | | // The caller should really be verifying the whole. |
295 | | // If the whole buffer is corrupt, we likely crash before we even get |
296 | | // here. |
297 | 11.1k | auto vec = table->GetPointer<const Vector<uint8_t>*>(fd.value.offset); |
298 | 11.1k | auto root = flexbuffers::GetRoot(vec->data(), vec->size()); |
299 | 11.1k | root.ToString(true, opts.strict_json, text); |
300 | 11.1k | return nullptr; |
301 | 87.8k | } else if (fd.nested_flatbuffer && opts.json_nested_flatbuffers) { |
302 | 6.49k | auto vec = table->GetPointer<const Vector<uint8_t>*>(fd.value.offset); |
303 | 6.49k | auto root = GetRoot<Table>(vec->data()); |
304 | 6.49k | return GenStruct(*fd.nested_flatbuffer, root, indent); |
305 | 81.3k | } else { |
306 | 81.3k | val = IsStruct(fd.value.type) |
307 | 81.3k | ? table->GetStruct<const void*>(fd.value.offset) |
308 | 81.3k | : table->GetPointer<const void*>(fd.value.offset); |
309 | 81.3k | } |
310 | 86.2k | return PrintOffset(val, fd.value.type, indent, prev_val, -1); |
311 | 103k | } |
312 | | |
313 | | // Generate text for a struct or table, values separated by commas, indented, |
314 | | // and bracketed by "{}" |
315 | | const char* GenStruct(const StructDef& struct_def, const Table* table, |
316 | 601k | int indent) { |
317 | 601k | text += '{'; |
318 | 601k | int fieldout = 0; |
319 | 601k | const uint8_t* prev_val = nullptr; |
320 | 601k | const auto elem_indent = indent + Indent(); |
321 | 601k | for (auto it = struct_def.fields.vec.begin(); |
322 | 5.01M | it != struct_def.fields.vec.end(); ++it) { |
323 | 4.41M | FieldDef& fd = **it; |
324 | 4.41M | auto is_present = struct_def.fixed || table->CheckField(fd.value.offset); |
325 | 4.41M | auto output_anyway = (opts.output_default_scalars_in_json || fd.key) && |
326 | 589k | IsScalar(fd.value.type.base_type) && !fd.deprecated; |
327 | 4.41M | if (is_present || output_anyway) { |
328 | 708k | if (fieldout++) { |
329 | 107k | AddComma(); |
330 | 107k | } |
331 | 708k | AddNewLine(); |
332 | 708k | AddIndent(elem_indent); |
333 | 708k | OutputIdentifier(fd.name); |
334 | 708k | if (!opts.protobuf_ascii_alike || |
335 | 0 | (fd.value.type.base_type != BASE_TYPE_STRUCT && |
336 | 0 | fd.value.type.base_type != BASE_TYPE_VECTOR)) |
337 | 708k | text += ':'; |
338 | 708k | text += ' '; |
339 | | // clang-format off |
340 | 708k | switch (fd.value.type.base_type) { |
341 | 0 | #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \ |
342 | 604k | case BASE_TYPE_ ## ENUM: { \ |
343 | 604k | GenField<CTYPE>(fd, table, struct_def.fixed, elem_indent); \ |
344 | 604k | break; } |
345 | 604k | FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) |
346 | 0 | #undef FLATBUFFERS_TD |
347 | | // Generate drop-thru case statements for all pointer types: |
348 | 0 | #define FLATBUFFERS_TD(ENUM, ...) \ |
349 | 545k | case BASE_TYPE_ ## ENUM: |
350 | 441k | FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) |
351 | 441k | FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD) |
352 | 103k | #undef FLATBUFFERS_TD |
353 | 103k | { |
354 | 103k | auto err = GenFieldOffset(fd, table, struct_def.fixed, elem_indent, prev_val); |
355 | 103k | if (err) return err; |
356 | 103k | break; |
357 | 103k | } |
358 | 708k | } |
359 | | // clang-format on |
360 | | // Track prev val for use with union types. |
361 | 708k | if (struct_def.fixed) { |
362 | 66.8k | prev_val = reinterpret_cast<const uint8_t*>(table) + fd.value.offset; |
363 | 641k | } else { |
364 | 641k | prev_val = table->GetAddressOf(fd.value.offset); |
365 | 641k | } |
366 | 708k | } |
367 | 4.41M | } |
368 | 601k | AddNewLine(); |
369 | 601k | AddIndent(indent); |
370 | 601k | text += '}'; |
371 | 601k | return nullptr; |
372 | 601k | } |
373 | | |
374 | | JsonPrinter(const Parser& parser, std::string& dest) |
375 | 398k | : opts(parser.opts), text(dest) { |
376 | 398k | text.reserve(1024); // Reduce amount of inevitable reallocs. |
377 | 398k | } |
378 | | |
379 | | const IDLOptions& opts; |
380 | | std::string& text; |
381 | | }; |
382 | | |
383 | | static const char* GenerateTextImpl(const Parser& parser, const Table* table, |
384 | | const StructDef& struct_def, |
385 | 398k | std::string* _text) { |
386 | 398k | JsonPrinter printer(parser, *_text); |
387 | 398k | auto err = printer.GenStruct(struct_def, table, 0); |
388 | 398k | if (err) return err; |
389 | 398k | printer.AddNewLine(); |
390 | 398k | return nullptr; |
391 | 398k | } |
392 | | |
393 | | // Generate a text representation of a flatbuffer in JSON format. |
394 | | // Deprecated: please use `GenTextFromTable` |
395 | | bool GenerateTextFromTable(const Parser& parser, const void* table, |
396 | 0 | const std::string& table_name, std::string* _text) { |
397 | 0 | return GenTextFromTable(parser, table, table_name, _text) != nullptr; |
398 | 0 | } |
399 | | |
400 | | // Generate a text representation of a flatbuffer in JSON format. |
401 | | const char* GenTextFromTable(const Parser& parser, const void* table, |
402 | | const std::string& table_name, |
403 | 0 | std::string* _text) { |
404 | 0 | auto struct_def = parser.LookupStruct(table_name); |
405 | 0 | if (struct_def == nullptr) { |
406 | 0 | return "unknown struct"; |
407 | 0 | } |
408 | 0 | auto root = static_cast<const Table*>(table); |
409 | 0 | return GenerateTextImpl(parser, root, *struct_def, _text); |
410 | 0 | } |
411 | | |
412 | | // Deprecated: please use `GenText` |
413 | | const char* GenerateText(const Parser& parser, const void* flatbuffer, |
414 | 0 | std::string* _text) { |
415 | 0 | return GenText(parser, flatbuffer, _text); |
416 | 0 | } |
417 | | |
418 | | // Generate a text representation of a flatbuffer in JSON format. |
419 | | const char* GenText(const Parser& parser, const void* flatbuffer, |
420 | 398k | std::string* _text) { |
421 | 398k | FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType() |
422 | 398k | auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer) |
423 | 398k | : GetRoot<Table>(flatbuffer); |
424 | 398k | return GenerateTextImpl(parser, root, *parser.root_struct_def_, _text); |
425 | 398k | } |
426 | | |
427 | | static std::string TextFileName(const std::string& path, |
428 | 0 | const std::string& file_name) { |
429 | 0 | return path + file_name + ".json"; |
430 | 0 | } |
431 | | |
432 | | // Deprecated: please use `GenTextFile` |
433 | | const char* GenerateTextFile(const Parser& parser, const std::string& path, |
434 | 0 | const std::string& file_name) { |
435 | 0 | return GenTextFile(parser, path, file_name); |
436 | 0 | } |
437 | | |
438 | | const char* GenTextFile(const Parser& parser, const std::string& path, |
439 | 0 | const std::string& file_name) { |
440 | 0 | if (parser.opts.use_flexbuffers) { |
441 | 0 | std::string json; |
442 | 0 | parser.flex_root_.ToString(true, parser.opts.strict_json, json); |
443 | 0 | return parser.opts.file_saver->SaveFile( |
444 | 0 | TextFileName(path, file_name).c_str(), json.c_str(), json.size(), |
445 | 0 | true) |
446 | 0 | ? nullptr |
447 | 0 | : "SaveFile failed"; |
448 | 0 | } |
449 | 0 | if (!parser.builder_.GetSize() || !parser.root_struct_def_) return nullptr; |
450 | 0 | std::string text; |
451 | 0 | auto err = GenText(parser, parser.builder_.GetBufferPointer(), &text); |
452 | 0 | if (err) return err; |
453 | 0 | return parser.opts.file_saver->SaveFile(TextFileName(path, file_name).c_str(), |
454 | 0 | text, false) |
455 | 0 | ? nullptr |
456 | 0 | : "SaveFile failed"; |
457 | 0 | } |
458 | | |
459 | | static std::string TextMakeRule(const Parser& parser, const std::string& path, |
460 | 0 | const std::string& file_name) { |
461 | 0 | if (!parser.builder_.GetSize() || !parser.root_struct_def_) return ""; |
462 | 0 | std::string filebase = |
463 | 0 | flatbuffers::StripPath(flatbuffers::StripExtension(file_name)); |
464 | 0 | std::string make_rule = TextFileName(path, filebase) + ": " + file_name; |
465 | 0 | auto included_files = |
466 | 0 | parser.GetIncludedFilesRecursive(parser.root_struct_def_->file); |
467 | 0 | for (auto it = included_files.begin(); it != included_files.end(); ++it) { |
468 | 0 | make_rule += " " + *it; |
469 | 0 | } |
470 | 0 | return make_rule; |
471 | 0 | } |
472 | | |
473 | | namespace { |
474 | | |
475 | | class TextCodeGenerator : public CodeGenerator { |
476 | | public: |
477 | | Status GenerateCode(const Parser& parser, const std::string& path, |
478 | 0 | const std::string& filename) override { |
479 | 0 | auto err = GenTextFile(parser, path, filename); |
480 | 0 | if (err) { |
481 | 0 | status_detail = " (" + std::string(err) + ")"; |
482 | 0 | return Status::ERROR; |
483 | 0 | } |
484 | 0 | return Status::OK; |
485 | 0 | } |
486 | | |
487 | | // Generate code from the provided `buffer` of given `length`. The buffer is a |
488 | | // serialized reflection.fbs. |
489 | 0 | Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override { |
490 | 0 | return Status::NOT_IMPLEMENTED; |
491 | 0 | } |
492 | | |
493 | | Status GenerateMakeRule(const Parser& parser, const std::string& path, |
494 | | const std::string& filename, |
495 | 0 | std::string& output) override { |
496 | 0 | output = TextMakeRule(parser, path, filename); |
497 | 0 | return Status::OK; |
498 | 0 | } |
499 | | |
500 | | Status GenerateGrpcCode(const Parser& parser, const std::string& path, |
501 | 0 | const std::string& filename) override { |
502 | 0 | (void)parser; |
503 | 0 | (void)path; |
504 | 0 | (void)filename; |
505 | 0 | return Status::NOT_IMPLEMENTED; |
506 | 0 | } |
507 | | |
508 | | Status GenerateRootFile(const Parser& parser, |
509 | 0 | const std::string& path) override { |
510 | 0 | (void)parser; |
511 | 0 | (void)path; |
512 | 0 | return Status::NOT_IMPLEMENTED; |
513 | 0 | } |
514 | | |
515 | 0 | bool IsSchemaOnly() const override { return false; } |
516 | | |
517 | 0 | bool SupportsBfbsGeneration() const override { return false; } |
518 | | |
519 | 0 | bool SupportsRootFileGeneration() const override { return false; } |
520 | | |
521 | 0 | IDLOptions::Language Language() const override { return IDLOptions::kJson; } |
522 | | |
523 | 0 | std::string LanguageName() const override { return "text"; } |
524 | | }; |
525 | | |
526 | | } // namespace |
527 | | |
528 | 0 | std::unique_ptr<CodeGenerator> NewTextCodeGenerator() { |
529 | 0 | return std::unique_ptr<TextCodeGenerator>(new TextCodeGenerator()); |
530 | 0 | } |
531 | | |
532 | | } // namespace flatbuffers |