| 1194 | |
| 1195 | template<typename F> |
| 1196 | CheckedError Parser::ParseTableDelimiters(size_t &fieldn, |
| 1197 | const StructDef *struct_def, F body) { |
| 1198 | // We allow tables both as JSON object{ .. } with field names |
| 1199 | // or vector[..] with all fields in order |
| 1200 | char terminator = '}'; |
| 1201 | bool is_nested_vector = struct_def && Is('['); |
| 1202 | if (is_nested_vector) { |
| 1203 | NEXT(); |
| 1204 | terminator = ']'; |
| 1205 | } else { |
| 1206 | EXPECT('{'); |
| 1207 | } |
| 1208 | for (;;) { |
| 1209 | if ((!opts.strict_json || !fieldn) && Is(terminator)) break; |
| 1210 | std::string name; |
| 1211 | if (is_nested_vector) { |
| 1212 | if (fieldn >= struct_def->fields.vec.size()) { |
| 1213 | return Error("too many unnamed fields in nested array"); |
| 1214 | } |
| 1215 | name = struct_def->fields.vec[fieldn]->name; |
| 1216 | } else { |
| 1217 | name = attribute_; |
| 1218 | if (Is(kTokenStringConstant)) { |
| 1219 | NEXT(); |
| 1220 | } else { |
| 1221 | EXPECT(opts.strict_json ? kTokenStringConstant : kTokenIdentifier); |
| 1222 | } |
| 1223 | if (!opts.protobuf_ascii_alike || !(Is('{') || Is('['))) EXPECT(':'); |
| 1224 | } |
| 1225 | ECHECK(body(name, fieldn, struct_def)); |
| 1226 | if (Is(terminator)) break; |
| 1227 | ECHECK(ParseComma()); |
| 1228 | } |
| 1229 | NEXT(); |
| 1230 | if (is_nested_vector && fieldn != struct_def->fields.vec.size()) { |
| 1231 | return Error("wrong number of unnamed fields in table vector"); |
| 1232 | } |
| 1233 | return NoError(); |
| 1234 | } |
| 1235 | |
| 1236 | CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value, |
| 1237 | uoffset_t *ovalue) { |