json.cpp is an anti-modern 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:
-
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'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