New JSON encoder (bug#70007)
It is in general at least 2x faster than the old encoder and does not depend on any external library. Using our own code also gives us control over translation details: for example, we now have full bignum support and tighter float formatting. * src/json.c (json_delete, json_initialized, init_json_functions) (json_malloc, json_free, init_json, json_out_of_memory) (json_releae_object, check_string_without_embedded_nulls, json_check) (json_check_utf8, lisp_to_json_nonscalar_1, lisp_to_json_nonscalar) (lisp_to_json, json_available_p, ensure_json_available, json_insert) (json_handle_nonlocal_exit, json_insert_callback): Remove. Remaining uses updated. * src/json.c (json_out_t, symset_t, struct symset_tbl) (symset_size, make_symset_table, push_symset, pop_symset) (cleanup_symset_tables, symset_hash, symset_expand, symset_add) (json_out_grow_buf, cleanup_json_out, json_make_room, JSON_OUT_STR) (json_out_str, json_out_byte, json_out_fixnum, string_not_unicode) (json_plain_char, json_out_string, json_out_nest, json_out_unnest) (json_out_object_cons, json_out_object_hash), json_out_array) (json_out_float, json_out_bignum, json_out_something) (json_out_to_string, json_serialize): New. (Fjson_serialize, Fjson_insert): New JSON encoder implementation. * test/src/json-tests.el (json-serialize/object-with-duplicate-keys) (json-serialize/string): Update tests.
This commit is contained in:
parent
ab016657e7
commit
890edfd2bb
5 changed files with 589 additions and 545 deletions
|
@ -2013,10 +2013,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
init_random ();
|
||||
init_xfaces ();
|
||||
|
||||
#if defined HAVE_JSON && !defined WINDOWSNT
|
||||
init_json ();
|
||||
#endif
|
||||
|
||||
if (!initialized)
|
||||
syms_of_comp ();
|
||||
|
||||
|
|
1087
src/json.c
1087
src/json.c
File diff suppressed because it is too large
Load diff
|
@ -4327,7 +4327,6 @@ extern void syms_of_image (void);
|
|||
|
||||
#ifdef HAVE_JSON
|
||||
/* Defined in json.c. */
|
||||
extern void init_json (void);
|
||||
extern void syms_of_json (void);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2859,6 +2859,7 @@ decimal point. 0 is not allowed with `e' or `g'.
|
|||
A value of nil means to use the shortest notation
|
||||
that represents the number without losing information. */);
|
||||
Vfloat_output_format = Qnil;
|
||||
DEFSYM (Qfloat_output_format, "float-output-format");
|
||||
|
||||
DEFVAR_BOOL ("print-integers-as-characters", print_integers_as_characters,
|
||||
doc: /* Non-nil means integers are printed using characters syntax.
|
||||
|
|
|
@ -126,11 +126,38 @@
|
|||
|
||||
(ert-deftest json-serialize/object-with-duplicate-keys ()
|
||||
(skip-unless (fboundp 'json-serialize))
|
||||
(let ((table (make-hash-table :test #'eq)))
|
||||
(puthash (copy-sequence "abc") [1 2 t] table)
|
||||
(puthash (copy-sequence "abc") :null table)
|
||||
(should (equal (hash-table-count table) 2))
|
||||
(should-error (json-serialize table) :type 'wrong-type-argument)))
|
||||
|
||||
(dolist (n '(1 5 20 100))
|
||||
(let ((symbols (mapcar (lambda (i) (make-symbol (format "s%d" i)))
|
||||
(number-sequence 1 n)))
|
||||
(expected (concat "{"
|
||||
(mapconcat (lambda (i) (format "\"s%d\":%d" i i))
|
||||
(number-sequence 1 n) ",")
|
||||
"}")))
|
||||
;; alist
|
||||
(should (equal (json-serialize
|
||||
(append
|
||||
(cl-mapcar #'cons
|
||||
symbols (number-sequence 1 n))
|
||||
(cl-mapcar #'cons
|
||||
symbols (number-sequence 1001 (+ 1000 n)))))
|
||||
expected))
|
||||
;; plist
|
||||
(should (equal (json-serialize
|
||||
(append
|
||||
(cl-mapcan #'list
|
||||
symbols (number-sequence 1 n))
|
||||
(cl-mapcan #'list
|
||||
symbols (number-sequence 1001 (+ 1000 n)))))
|
||||
expected))))
|
||||
|
||||
;; We don't check for duplicated keys in hash tables.
|
||||
;; (let ((table (make-hash-table :test #'eq)))
|
||||
;; (puthash (copy-sequence "abc") [1 2 t] table)
|
||||
;; (puthash (copy-sequence "abc") :null table)
|
||||
;; (should (equal (hash-table-count table) 2))
|
||||
;; (should-error (json-serialize table) :type 'wrong-type-argument))
|
||||
)
|
||||
|
||||
(ert-deftest json-parse-string/object ()
|
||||
(skip-unless (fboundp 'json-parse-string))
|
||||
|
@ -173,8 +200,8 @@
|
|||
(should (equal (json-serialize ["\nasdфыв\u001f\u007ffgh\t"])
|
||||
"[\"\\nasdфыв\\u001F\u007ffgh\\t\"]"))
|
||||
(should (equal (json-serialize ["a\0b"]) "[\"a\\u0000b\"]"))
|
||||
;; FIXME: Is this the right behavior?
|
||||
(should (equal (json-serialize ["\u00C4\xC3\x84"]) "[\"\u00C4\u00C4\"]")))
|
||||
(should-error (json-serialize ["\xC3\x84"]))
|
||||
(should-error (json-serialize ["\u00C4\xC3\x84"])))
|
||||
|
||||
(ert-deftest json-serialize/invalid-unicode ()
|
||||
(skip-unless (fboundp 'json-serialize))
|
||||
|
|
Loading…
Add table
Reference in a new issue