json.cpp is a baroque JSON parsing / serialization library for C++.
This project is a reaction against https://github.com/nlohmann/json/ which provides a modern C++ library for JSON. Our alternative:
-
Goes 2x-3x faster. With
gcc -O3
13.2 on Ubuntu 24.04 using an AMD Ryzen Threadripper PRO 7995WX this library was able to parse the complicated JSON example in json_test.cpp 3x faster than nlohmann's library. -
Compiles 10x faster. An object that does nothing with JSON except calling
nlohmann::ordered_json::parse
will take at minimum 1200 ms to compile. This is an unacceptably slow minimum overhead. With this project, you're instead looking at about 120 ms, and nearly all of that overhead is due our dependency on<string>
,<map>
, and<vector>
. -
Has 10x less code. nlohmann's json.h has 24,766 lines of code. Our json.h has 233 lines of code, and our json.cpp file has 1,303 lines. This makes our implementation more hackable and easily customizable. It's much more restrained when it comes to C++ language feature usage. You can easily reason about the behavior of this library and determine if it meets the requirements of your production environment.
-
Better JSONTestSuite conformance. Our JSON parser passes all the test cases from https://github.com/nst/JSONTestSuite/. However nlohmann's json library doesn't fully pass.
To use this library, you need three things. First, you need json.h. Secondly, you need json.cpp. Thirdly, you need Google's outstanding double-conversion library.
We like double-conversion because it has a really good method for
serializing 32-bit floating point numbers. This is useful if you're
building something like an HTTP server that serves embeddings. With
other JSON serializers that depend only on the C library and STL, floats
are upcast to double so you'd be sending big ugly arrays like
[0.2893893899832212, ...]
which doesn't make sense, because most of
those bits are made up, since a float32 can't hold that much precision.
But with this library, the Json
object will remember that you passed
it a float, and then serialize it as such when you call toString()
,
thus allowing for more efficient readable responses.
Here are some quick and dirty tests for parsing and serialization. The
lower numbers are better. See json_test.cpp and
nlohmann/json_test.cpp. Please note that the
json_test_suite()
function was modified locally to only include the
successful test cases, in the hope of controlling for differences in
exception handling. The test, as written, actually reports a 39x (rather
than 3x) advantage, which we haven't figured out how to explain yet.
# json.cpp
88 ns 2000x object_test()
304 ns 2000x deep_test()
816 ns 2000x parse_test()
1588 ns 2000x round_trip_test()
5838 ns 2000x json_test_suite()
# nlohmann::ordered_json
202 ns 2000x object_test()
659 ns 2000x deep_test()
1928 ns 2000x parse_test()
4258 ns 2000x round_trip_test()
16617 ns 2000x json_test_suite()
The llamafile project uses
this JSON library. Here are some excerpts from its OpenAI API compatible
/v1/chat/completions
endpoint.
Here's the code where it parses the incoming HTTP body and validates it.
// object<model, messages, ...>
std::pair<Json::Status, Json> json = Json::parse(payload_);
if (json.first != Json::success)
return send_error(400, Json::StatusToString(json.first));
if (!json.second.isObject())
return send_error(400, "JSON body must be an object");
// fields openai documents that we don't support yet
if (!json.second["tools"].isNull())
return send_error(400, "OpenAI tools field not supported yet");
if (!json.second["audio"].isNull())
return send_error(400, "OpenAI audio field not supported yet");
// model: string
Json& model = json.second["model"];
if (!model.isString())
return send_error(400, "JSON missing model string");
params->model = std::move(model.getString());
// messages: array<object<role:string, content:string>>
if (!json.second["messages"].isArray())
return send_error(400, "JSON missing messages array");
std::vector<Json>& messages = json.second["messages"].getArray();
if (messages.empty())
return send_error(400, "JSON messages array is empty");
for (Json& message : messages) {
if (!message.isObject())
return send_error(400, "messages array must hold objects");
if (!message["role"].isString())
return send_error(400, "message must have string role");
if (!is_legal_role(message["role"].getString()))
return send_error(400, "message role not system user assistant");
if (!message["content"].isString())
return send_error(400, "message must have string content");
params->messages.emplace_back(
std::move(message["role"].getString()),
std::move(message["content"].getString()));
}
// ...
Here's the code where it sends a response.
struct V1ChatCompletionResponse
{
std::string content;
Json json;
};
bool
Client::v1_chat_completions()
{
// ...
V1ChatCompletionResponse* response = new V1ChatCompletionResponse;
defer_cleanup(cleanup_response, response);
// ...
// setup response json
response->json["id"].setString(generate_id());
response->json["object"].setString("chat.completion");
response->json["model"].setString(params->model);
response->json["system_fingerprint"].setString(slot_->system_fingerprint_);
response->json["choices"].setArray();
Json& choice = response->json["choices"][0];
choice.setObject();
choice["index"].setLong(0);
choice["logprobs"].setNull();
choice["finish_reason"].setNull();
// initialize response
if (params->stream) {
char* p = append_http_response_message(obuf_.p, 200);
p = stpcpy(p, "Content-Type: text/event-stream\r\n");
if (!send_response_start(obuf_.p, p))
return false;
choice["delta"].setObject();
choice["delta"]["role"].setString("assistant");
choice["delta"]["content"].setString("");
response->json["created"].setLong(timespec_real().tv_sec);
response->content = make_event(response->json);
choice.getObject().erase("delta");
if (!send_response_chunk(response->content))
return false;
}
// prediction time
int completion_tokens = 0;
const char* finish_reason = "length";
for (;;) {
// do token generation ...
}
choice["finish_reason"].setString(finish_reason);
// finalize response
cleanup_slot(this);
if (params->stream) {
choice["delta"].setObject();
choice["delta"]["content"].setString("");
response->json["created"].setLong(timespec_real().tv_sec);
response->content = make_event(response->json);
choice.getObject().erase("delta");
if (!send_response_chunk(response->content))
return false;
return send_response_finish();
} else {
Json& usage = response->json["usage"];
usage.setObject();
usage["prompt_tokens"].setLong(prompt_tokens);
usage["completion_tokens"].setLong(completion_tokens);
usage["total_tokens"].setLong(completion_tokens + prompt_tokens);
choice["message"].setObject();
choice["message"]["role"].setString("assistant");
choice["message"]["content"].setString(std::move(response->content));
response->json["created"].setLong(timespec_real().tv_sec);
char* p = append_http_response_message(obuf_.p, 200);
p = stpcpy(p, "Content-Type: application/json\r\n");
response->content = response->json.toStringPretty();
response->content += '\n';
return send_response(obuf_.p, p, response->content);
}
See also https://github.com/Mozilla-Ocho/llamafile/blob/main/llamafile/server/v1_chat_completions.cpp
Here's the results of running jsontestsuite_test
for json.cpp.
The parser implementation is free to choose to accept or reject.
i_number_double_huge_neg_exp.json IMPLEMENTATION_PASS
i_number_huge_exp.json IMPLEMENTATION_PASS
i_number_neg_int_huge_exp.json IMPLEMENTATION_PASS
i_number_pos_double_huge_exp.json IMPLEMENTATION_PASS
i_number_real_neg_overflow.json IMPLEMENTATION_PASS
i_number_real_pos_overflow.json IMPLEMENTATION_PASS
i_number_real_underflow.json IMPLEMENTATION_PASS
i_number_too_big_neg_int.json IMPLEMENTATION_PASS
i_number_too_big_pos_int.json IMPLEMENTATION_PASS
i_number_very_big_negative_int.json IMPLEMENTATION_PASS
i_object_key_lone_2nd_surrogate.json IMPLEMENTATION_PASS
i_string_1st_surrogate_but_2nd_missing.json IMPLEMENTATION_PASS
i_string_1st_valid_surrogate_2nd_invalid.json IMPLEMENTATION_PASS
i_string_incomplete_surrogate_and_escape_valid.json IMPLEMENTATION_PASS
i_string_incomplete_surrogate_pair.json IMPLEMENTATION_PASS
i_string_incomplete_surrogates_escape_valid.json IMPLEMENTATION_PASS
i_string_invalid_lonely_surrogate.json IMPLEMENTATION_PASS
i_string_invalid_surrogate.json IMPLEMENTATION_PASS
i_string_invalid_utf-8.json IMPLEMENTATION_FAIL (illegal_utf8_character)
i_string_inverted_surrogates_U+1D11E.json IMPLEMENTATION_PASS
i_string_iso_latin_1.json IMPLEMENTATION_FAIL (malformed_utf8)
i_string_lone_second_surrogate.json IMPLEMENTATION_PASS
i_string_lone_utf8_continuation_byte.json IMPLEMENTATION_FAIL (c1_control_code_in_string)
i_string_not_in_unicode_range.json IMPLEMENTATION_FAIL (utf8_exceeds_utf16_range)
i_string_overlong_sequence_2_bytes.json IMPLEMENTATION_FAIL (overlong_ascii)
i_string_overlong_sequence_6_bytes.json IMPLEMENTATION_FAIL (illegal_utf8_character)
i_string_overlong_sequence_6_bytes_null.json IMPLEMENTATION_FAIL (illegal_utf8_character)
i_string_truncated-utf-8.json IMPLEMENTATION_FAIL (malformed_utf8)
i_string_utf16BE_no_BOM.json IMPLEMENTATION_FAIL (illegal_character)
i_string_utf16LE_no_BOM.json IMPLEMENTATION_FAIL (illegal_character)
i_string_UTF-16LE_with_BOM.json IMPLEMENTATION_FAIL (illegal_character)
i_string_UTF-8_invalid_sequence.json IMPLEMENTATION_FAIL (illegal_utf8_character)
i_string_UTF8_surrogate_U+D800.json IMPLEMENTATION_FAIL (utf16_surrogate_in_utf8)
i_structure_500_nested_arrays.json IMPLEMENTATION_FAIL (depth_exceeded)
i_structure_UTF-8_BOM_empty_object.json IMPLEMENTATION_FAIL (illegal_character)
The parser must reject this data.
n_array_1_true_without_comma.json REJECTED (missing_comma)
n_array_a_invalid_utf8.json REJECTED (illegal_character)
n_array_colon_instead_of_comma.json REJECTED (unexpected_colon)
n_array_comma_after_close.json REJECTED (trailing_content)
n_array_comma_and_number.json REJECTED (unexpected_comma)
n_array_double_comma.json REJECTED (unexpected_comma)
n_array_double_extra_comma.json REJECTED (unexpected_comma)
n_array_extra_close.json REJECTED (trailing_content)
n_array_extra_comma.json REJECTED (unexpected_end_of_array)
n_array_incomplete_invalid_value.json REJECTED (illegal_character)
n_array_incomplete.json REJECTED (unexpected_eof)
n_array_inner_array_no_comma.json REJECTED (missing_comma)
n_array_invalid_utf8.json REJECTED (illegal_character)
n_array_items_separated_by_semicolon.json REJECTED (unexpected_colon)
n_array_just_comma.json REJECTED (unexpected_comma)
n_array_just_minus.json REJECTED (bad_negative)
n_array_missing_value.json REJECTED (unexpected_comma)
n_array_newlines_unclosed.json REJECTED (unexpected_eof)
n_array_number_and_comma.json REJECTED (unexpected_end_of_array)
n_array_number_and_several_commas.json REJECTED (unexpected_comma)
n_array_spaces_vertical_tab_formfeed.json REJECTED (non_del_c0_control_code_in_string)
n_array_star_inside.json REJECTED (illegal_character)
n_array_unclosed.json REJECTED (unexpected_eof)
n_array_unclosed_trailing_comma.json REJECTED (unexpected_eof)
n_array_unclosed_with_new_lines.json REJECTED (unexpected_eof)
n_array_unclosed_with_object_inside.json REJECTED (unexpected_eof)
n_incomplete_false.json REJECTED (illegal_character)
n_incomplete_null.json REJECTED (illegal_character)
n_incomplete_true.json REJECTED (illegal_character)
n_multidigit_number_then_00.json REJECTED (trailing_content)
n_number_0.1.2.json REJECTED (illegal_character)
n_number_-01.json REJECTED (unexpected_octal)
n_number_0.3e+.json REJECTED (bad_exponent)
n_number_0.3e.json REJECTED (bad_exponent)
n_number_0_capital_E+.json REJECTED (bad_exponent)
n_number_0_capital_E.json REJECTED (bad_exponent)
n_number_0.e1.json REJECTED (bad_double)
n_number_0e+.json REJECTED (bad_exponent)
n_number_0e.json REJECTED (bad_exponent)
n_number_1_000.json REJECTED (missing_comma)
n_number_1.0e+.json REJECTED (bad_exponent)
n_number_1.0e-.json REJECTED (bad_exponent)
n_number_1.0e.json REJECTED (bad_exponent)
n_number_-1.0..json REJECTED (illegal_character)
n_number_1eE2.json REJECTED (bad_exponent)
n_number_+1.json REJECTED (illegal_character)
n_number_.-1.json REJECTED (illegal_character)
n_number_2.e+3.json REJECTED (bad_double)
n_number_2.e-3.json REJECTED (bad_double)
n_number_2.e3.json REJECTED (bad_double)
n_number_.2e-3.json REJECTED (illegal_character)
n_number_-2..json REJECTED (bad_double)
n_number_9.e+.json REJECTED (bad_double)
n_number_expression.json REJECTED (illegal_character)
n_number_hex_1_digit.json REJECTED (illegal_character)
n_number_hex_2_digits.json REJECTED (illegal_character)
n_number_infinity.json REJECTED (illegal_character)
n_number_+Inf.json REJECTED (illegal_character)
n_number_Inf.json REJECTED (illegal_character)
n_number_invalid+-.json REJECTED (bad_exponent)
n_number_invalid-negative-real.json REJECTED (missing_comma)
n_number_invalid-utf-8-in-bigger-int.json REJECTED (illegal_character)
n_number_invalid-utf-8-in-exponent.json REJECTED (illegal_character)
n_number_invalid-utf-8-in-int.json REJECTED (illegal_character)
n_number_++.json REJECTED (illegal_character)
n_number_minus_infinity.json REJECTED (bad_negative)
n_number_minus_sign_with_trailing_garbage.json REJECTED (bad_negative)
n_number_minus_space_1.json REJECTED (bad_negative)
n_number_-NaN.json REJECTED (bad_negative)
n_number_NaN.json REJECTED (illegal_character)
n_number_neg_int_starting_with_zero.json REJECTED (unexpected_octal)
n_number_neg_real_without_int_part.json REJECTED (bad_negative)
n_number_neg_with_garbage_at_end.json REJECTED (illegal_character)
n_number_real_garbage_after_e.json REJECTED (bad_exponent)
n_number_real_with_invalid_utf8_after_e.json REJECTED (bad_exponent)
n_number_real_without_fractional_part.json REJECTED (bad_double)
n_number_starting_with_dot.json REJECTED (illegal_character)
n_number_U+FF11_fullwidth_digit_one.json REJECTED (illegal_character)
n_number_with_alpha_char.json REJECTED (illegal_character)
n_number_with_alpha.json REJECTED (illegal_character)
n_number_with_leading_zero.json REJECTED (unexpected_octal)
n_object_bad_value.json REJECTED (illegal_character)
n_object_bracket_key.json REJECTED (object_key_must_be_string)
n_object_comma_instead_of_colon.json REJECTED (unexpected_comma)
n_object_double_colon.json REJECTED (unexpected_colon)
n_object_emoji.json REJECTED (illegal_character)
n_object_garbage_at_end.json REJECTED (object_key_must_be_string)
n_object_key_with_single_quotes.json REJECTED (illegal_character)
n_object_lone_continuation_byte_in_key_and_trailing_comma.json REJECTED (illegal_utf8_character)
n_object_missing_colon.json REJECTED (illegal_character)
n_object_missing_key.json REJECTED (unexpected_colon)
n_object_missing_semicolon.json REJECTED (missing_colon)
n_object_missing_value.json REJECTED (unexpected_eof)
n_object_no-colon.json REJECTED (unexpected_eof)
n_object_non_string_key_but_huge_number_instead.json REJECTED (object_key_must_be_string)
n_object_non_string_key.json REJECTED (object_key_must_be_string)
n_object_repeated_null_null.json REJECTED (object_key_must_be_string)
n_object_several_trailing_commas.json REJECTED (unexpected_comma)
n_object_single_quote.json REJECTED (illegal_character)
n_object_trailing_comma.json REJECTED (unexpected_end_of_object)
n_object_trailing_comment.json REJECTED (trailing_content)
n_object_trailing_comment_open.json REJECTED (trailing_content)
n_object_trailing_comment_slash_open_incomplete.json REJECTED (trailing_content)
n_object_trailing_comment_slash_open.json REJECTED (trailing_content)
n_object_two_commas_in_a_row.json REJECTED (unexpected_comma)
n_object_unquoted_key.json REJECTED (illegal_character)
n_object_unterminated-value.json REJECTED (unexpected_end_of_string)
n_object_with_single_string.json REJECTED (unexpected_end_of_object)
n_object_with_trailing_garbage.json REJECTED (trailing_content)
n_single_space.json REJECTED (absent_value)
n_string_1_surrogate_then_escape.json REJECTED (unexpected_end_of_string)
n_string_1_surrogate_then_escape_u1.json REJECTED (invalid_unicode_escape)
n_string_1_surrogate_then_escape_u1x.json REJECTED (invalid_unicode_escape)
n_string_1_surrogate_then_escape_u.json REJECTED (invalid_unicode_escape)
n_string_accentuated_char_no_quotes.json REJECTED (illegal_character)
n_string_backslash_00.json REJECTED (invalid_escape_character)
n_string_escaped_backslash_bad.json REJECTED (unexpected_end_of_string)
n_string_escaped_ctrl_char_tab.json REJECTED (invalid_escape_character)
n_string_escaped_emoji.json REJECTED (invalid_escape_character)
n_string_escape_x.json REJECTED (hex_escape_not_printable)
n_string_incomplete_escaped_character.json REJECTED (invalid_unicode_escape)
n_string_incomplete_escape.json REJECTED (unexpected_end_of_string)
n_string_incomplete_surrogate_escape_invalid.json REJECTED (invalid_hex_escape)
n_string_incomplete_surrogate.json REJECTED (invalid_unicode_escape)
n_string_invalid_backslash_esc.json REJECTED (invalid_escape_character)
n_string_invalid_unicode_escape.json REJECTED (invalid_unicode_escape)
n_string_invalid_utf8_after_escape.json REJECTED (invalid_escape_character)
n_string_invalid-utf-8-in-escape.json REJECTED (invalid_unicode_escape)
n_string_leading_uescaped_thinspace.json REJECTED (illegal_character)
n_string_no_quotes_with_bad_escape.json REJECTED (illegal_character)
n_string_single_doublequote.json REJECTED (unexpected_end_of_string)
n_string_single_quote.json REJECTED (illegal_character)
n_string_single_string_no_double_quotes.json REJECTED (illegal_character)
n_string_start_escape_unclosed.json REJECTED (unexpected_end_of_string)
n_string_unescaped_ctrl_char.json REJECTED (non_del_c0_control_code_in_string)
n_string_unescaped_newline.json REJECTED (non_del_c0_control_code_in_string)
n_string_unescaped_tab.json REJECTED (non_del_c0_control_code_in_string)
n_string_unicode_CapitalU.json REJECTED (invalid_escape_character)
n_string_with_trailing_garbage.json REJECTED (trailing_content)
n_structure_100000_opening_arrays.json REJECTED (depth_exceeded)
n_structure_angle_bracket_..json REJECTED (illegal_character)
n_structure_angle_bracket_null.json REJECTED (illegal_character)
n_structure_array_trailing_garbage.json REJECTED (trailing_content)
n_structure_array_with_extra_array_close.json REJECTED (trailing_content)
n_structure_array_with_unclosed_string.json REJECTED (unexpected_end_of_string)
n_structure_ascii-unicode-identifier.json REJECTED (illegal_character)
n_structure_capitalized_True.json REJECTED (illegal_character)
n_structure_close_unopened_array.json REJECTED (trailing_content)
n_structure_comma_instead_of_closing_brace.json REJECTED (unexpected_eof)
n_structure_double_array.json REJECTED (trailing_content)
n_structure_end_array.json REJECTED (unexpected_end_of_array)
n_structure_incomplete_UTF8_BOM.json REJECTED (illegal_character)
n_structure_lone-invalid-utf-8.json REJECTED (illegal_character)
n_structure_lone-open-bracket.json REJECTED (unexpected_eof)
n_structure_no_data.json REJECTED (absent_value)
n_structure_null-byte-outside-string.json REJECTED (illegal_character)
n_structure_number_with_trailing_garbage.json REJECTED (trailing_content)
n_structure_object_followed_by_closing_object.json REJECTED (trailing_content)
n_structure_object_unclosed_no_value.json REJECTED (unexpected_eof)
n_structure_object_with_comment.json REJECTED (illegal_character)
n_structure_object_with_trailing_garbage.json REJECTED (trailing_content)
n_structure_open_array_apostrophe.json REJECTED (illegal_character)
n_structure_open_array_comma.json REJECTED (unexpected_comma)
n_structure_open_array_object.json REJECTED (depth_exceeded)
n_structure_open_array_open_object.json REJECTED (unexpected_eof)
n_structure_open_array_open_string.json REJECTED (unexpected_end_of_string)
n_structure_open_array_string.json REJECTED (unexpected_eof)
n_structure_open_object_close_array.json REJECTED (unexpected_end_of_array)
n_structure_open_object_comma.json REJECTED (unexpected_comma)
n_structure_open_object.json REJECTED (unexpected_eof)
n_structure_open_object_open_array.json REJECTED (object_key_must_be_string)
n_structure_open_object_open_string.json REJECTED (unexpected_end_of_string)
n_structure_open_object_string_with_apostrophes.json REJECTED (illegal_character)
n_structure_open_open.json REJECTED (invalid_escape_character)
n_structure_single_eacute.json REJECTED (illegal_character)
n_structure_single_star.json REJECTED (illegal_character)
n_structure_trailing_#.json REJECTED (trailing_content)
n_structure_U+2060_word_joined.json REJECTED (illegal_character)
n_structure_uescaped_LF_before_string.json REJECTED (illegal_character)
n_structure_unclosed_array.json REJECTED (unexpected_eof)
n_structure_unclosed_array_partial_null.json REJECTED (illegal_character)
n_structure_unclosed_array_unfinished_false.json REJECTED (illegal_character)
n_structure_unclosed_array_unfinished_true.json REJECTED (illegal_character)
n_structure_unclosed_object.json REJECTED (unexpected_eof)
n_structure_unicode-identifier.json REJECTED (illegal_character)
n_structure_UTF8_BOM_no_data.json REJECTED (illegal_character)
n_structure_whitespace_formfeed.json REJECTED (illegal_character)
n_structure_whitespace_U+2060_word_joiner.json REJECTED (illegal_character)
The parser must accept this JSON as valid.
y_array_arraysWithSpaces.json PASSED
y_array_empty.json PASSED
y_array_empty-string.json PASSED
y_array_ending_with_newline.json PASSED
y_array_false.json PASSED
y_array_heterogeneous.json PASSED
y_array_null.json PASSED
y_array_with_1_and_newline.json PASSED
y_array_with_leading_space.json PASSED
y_array_with_several_null.json PASSED
y_array_with_trailing_space.json PASSED
y_number_0e+1.json PASSED
y_number_0e1.json PASSED
y_number_after_space.json PASSED
y_number_double_close_to_zero.json PASSED
y_number_int_with_exp.json PASSED
y_number.json PASSED
y_number_minus_zero.json PASSED
y_number_negative_int.json PASSED
y_number_negative_one.json PASSED
y_number_negative_zero.json PASSED
y_number_real_capital_e.json PASSED
y_number_real_capital_e_neg_exp.json PASSED
y_number_real_capital_e_pos_exp.json PASSED
y_number_real_exponent.json PASSED
y_number_real_fraction_exponent.json PASSED
y_number_real_neg_exp.json PASSED
y_number_real_pos_exponent.json PASSED
y_number_simple_int.json PASSED
y_number_simple_real.json PASSED
y_object_basic.json PASSED
y_object_duplicated_key_and_value.json PASSED
y_object_duplicated_key.json PASSED
y_object_empty.json PASSED
y_object_empty_key.json PASSED
y_object_escaped_null_in_key.json PASSED
y_object_extreme_numbers.json PASSED
y_object.json PASSED
y_object_long_strings.json PASSED
y_object_simple.json PASSED
y_object_string_unicode.json PASSED
y_object_with_newlines.json PASSED
y_string_1_2_3_bytes_UTF-8_sequences.json PASSED
y_string_accepted_surrogate_pair.json PASSED
y_string_accepted_surrogate_pairs.json PASSED
y_string_allowed_escapes.json PASSED
y_string_backslash_and_u_escaped_zero.json PASSED
y_string_backslash_doublequotes.json PASSED
y_string_comments.json PASSED
y_string_double_escape_a.json PASSED
y_string_double_escape_n.json PASSED
y_string_escaped_control_character.json PASSED
y_string_escaped_noncharacter.json PASSED
y_string_in_array.json PASSED
y_string_in_array_with_leading_space.json PASSED
y_string_last_surrogates_1_and_2.json PASSED
y_string_nbsp_uescaped.json PASSED
y_string_nonCharacterInUTF-8_U+10FFFF.json PASSED
y_string_nonCharacterInUTF-8_U+FFFF.json PASSED
y_string_null_escape.json PASSED
y_string_one-byte-utf-8.json PASSED
y_string_pi.json PASSED
y_string_reservedCharacterInUTF-8_U+1BFFF.json PASSED
y_string_simple_ascii.json PASSED
y_string_space.json PASSED
y_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF.json PASSED
y_string_three-byte-utf-8.json PASSED
y_string_two-byte-utf-8.json PASSED
y_string_u+2028_line_sep.json PASSED
y_string_u+2029_par_sep.json PASSED
y_string_uescaped_newline.json PASSED
y_string_uEscape.json PASSED
y_string_unescaped_char_delete.json PASSED
y_string_unicode_2.json PASSED
y_string_unicodeEscapedBackslash.json PASSED
y_string_unicode_escaped_double_quote.json PASSED
y_string_unicode.json PASSED
y_string_unicode_U+10FFFE_nonchar.json PASSED
y_string_unicode_U+1FFFE_nonchar.json PASSED
y_string_unicode_U+200B_ZERO_WIDTH_SPACE.json PASSED
y_string_unicode_U+2064_invisible_plus.json PASSED
y_string_unicode_U+FDD0_nonchar.json PASSED
y_string_unicode_U+FFFE_nonchar.json PASSED
y_string_utf8.json PASSED
y_string_with_del_character.json PASSED
y_structure_lonely_false.json PASSED
y_structure_lonely_int.json PASSED
y_structure_lonely_negative_real.json PASSED
y_structure_lonely_null.json PASSED
y_structure_lonely_string.json PASSED
y_structure_lonely_true.json PASSED
y_structure_string_empty.json PASSED
y_structure_trailing_newline.json PASSED
y_structure_true_in_array.json PASSED
y_structure_whitespace_array.json PASSED
This JSON parser was coded in 2022 by Justine Tunney and Gautham Venkatasubramanian. It was originally written in C for Lua in Redbean. See https://github.com/jart/cosmopolitan/blob/master/tool/net/ljson.c for the original source code. In 2024 Mozilla sponsored converting the Redbean JSON library to C++ for llamafile.