in libvmaf/src/pdjson.c [681:785]
enum json_type json_next(json_stream *json)
{
if (json->flags & JSON_FLAG_ERROR)
return JSON_ERROR;
if (json->next != 0) {
enum json_type next = json->next;
json->next = (enum json_type)0;
return next;
}
if (json->ntokens > 0 && json->stack_top == (size_t)-1) {
/* In the streaming mode leave any trailing whitespaces in the stream.
* This allows the user to validate any desired separation between
* values (such as newlines) using json_source_get/peek() with any
* remaining whitespaces ignored as leading when we parse the next
* value. */
if (!(json->flags & JSON_FLAG_STREAMING)) {
int c;
do {
c = json->source.peek(&json->source);
if (json_isspace(c)) {
c = json->source.get(&json->source);
}
} while (json_isspace(c));
if (c != EOF) {
json_error(json, "expected end of text instead of byte '%c'", c);
return JSON_ERROR;
}
}
return JSON_DONE;
}
int c = next(json);
if (json->stack_top == (size_t)-1) {
if (c == EOF && (json->flags & JSON_FLAG_STREAMING))
return JSON_DONE;
return read_value(json, c);
}
if (json->stack[json->stack_top].type == JSON_ARRAY) {
if (json->stack[json->stack_top].count == 0) {
if (c == ']') {
return pop(json, c, JSON_ARRAY);
}
json->stack[json->stack_top].count++;
return read_value(json, c);
} else if (c == ',') {
json->stack[json->stack_top].count++;
return read_value(json, next(json));
} else if (c == ']') {
return pop(json, c, JSON_ARRAY);
} else {
json_error(json, "unexpected byte '%c'", c);
return JSON_ERROR;
}
} else if (json->stack[json->stack_top].type == JSON_OBJECT) {
if (json->stack[json->stack_top].count == 0) {
if (c == '}') {
return pop(json, c, JSON_OBJECT);
}
/* No member name/value pairs yet. */
enum json_type value = read_value(json, c);
if (value != JSON_STRING) {
if (value != JSON_ERROR)
json_error(json, "%s", "expected member name or '}'");
return JSON_ERROR;
} else {
json->stack[json->stack_top].count++;
return value;
}
} else if ((json->stack[json->stack_top].count % 2) == 0) {
/* Expecting comma followed by member name. */
if (c != ',' && c != '}') {
json_error(json, "%s", "expected ',' or '}' after member value");
return JSON_ERROR;
} else if (c == '}') {
return pop(json, c, JSON_OBJECT);
} else {
enum json_type value = read_value(json, next(json));
if (value != JSON_STRING) {
if (value != JSON_ERROR)
json_error(json, "%s", "expected member name");
return JSON_ERROR;
} else {
json->stack[json->stack_top].count++;
return value;
}
}
} else if ((json->stack[json->stack_top].count % 2) == 1) {
/* Expecting colon followed by value. */
if (c != ':') {
json_error(json, "%s", "expected ':' after member name");
return JSON_ERROR;
} else {
json->stack[json->stack_top].count++;
return read_value(json, next(json));
}
}
}
json_error(json, "%s", "invalid parser state");
return JSON_ERROR;
}