aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilipp Stephani2017-12-13 22:41:28 +0100
committerPhilipp Stephani2017-12-24 13:59:25 +0100
commitf552a957ada23a7ff182fc1ab94221ced3ed1713 (patch)
tree359c39cfc24e3c166984717f73884f6c221d1378 /src
parent3455192777459a08a38b0adb311a76202e29f48d (diff)
downloademacs-f552a957ada23a7ff182fc1ab94221ced3ed1713.tar.gz
emacs-f552a957ada23a7ff182fc1ab94221ced3ed1713.zip
Accept alists when serializing JSON
* src/json.c (lisp_to_json_toplevel_1): Also accept alists representing objects. * src/json.c (Fjson_serialize): Update docstring. * test/src/json-tests.el (json-serialize/object): Add unit tests for serializing alists. * doc/lispref/text.texi (Parsing JSON): Document that serialization functions accept alists.
Diffstat (limited to 'src')
-rw-r--r--src/json.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/src/json.c b/src/json.c
index c1daba199c3..f615c4269f1 100644
--- a/src/json.c
+++ b/src/json.c
@@ -367,12 +367,48 @@ lisp_to_json_toplevel_1 (Lisp_Object lisp, json_t **json)
367 clear_unwind_protect (count); 367 clear_unwind_protect (count);
368 return unbind_to (count, Qnil); 368 return unbind_to (count, Qnil);
369 } 369 }
370 else if (NILP (lisp))
371 {
372 *json = json_check (json_object ());
373 return Qnil;
374 }
375 else if (CONSP (lisp))
376 {
377 Lisp_Object tail = lisp;
378 *json = json_check (json_object ());
379 ptrdiff_t count = SPECPDL_INDEX ();
380 record_unwind_protect_ptr (json_release_object, *json);
381 FOR_EACH_TAIL (tail)
382 {
383 Lisp_Object pair = XCAR (tail);
384 CHECK_CONS (pair);
385 Lisp_Object key_symbol = XCAR (pair);
386 Lisp_Object value = XCDR (pair);
387 CHECK_SYMBOL (key_symbol);
388 Lisp_Object key = SYMBOL_NAME (key_symbol);
389 /* We can't specify the length, so the string must be
390 null-terminated. */
391 check_string_without_embedded_nulls (key);
392 const char *key_str = SSDATA (key);
393 /* Only add element if key is not already present. */
394 if (json_object_get (*json, key_str) == NULL)
395 {
396 int status
397 = json_object_set_new (*json, key_str, lisp_to_json (value));
398 if (status == -1)
399 json_out_of_memory ();
400 }
401 }
402 CHECK_LIST_END (tail, lisp);
403 clear_unwind_protect (count);
404 return unbind_to (count, Qnil);
405 }
370 wrong_type_argument (Qjson_value_p, lisp); 406 wrong_type_argument (Qjson_value_p, lisp);
371} 407}
372 408
373/* Convert LISP to a toplevel JSON object (array or object). Signal 409/* Convert LISP to a toplevel JSON object (array or object). Signal
374 an error of type `wrong-type-argument' if LISP is not a vector or 410 an error of type `wrong-type-argument' if LISP is not a vector,
375 hashtable. */ 411 hashtable, or alist. */
376 412
377static json_t * 413static json_t *
378lisp_to_json_toplevel (Lisp_Object lisp) 414lisp_to_json_toplevel (Lisp_Object lisp)
@@ -413,19 +449,20 @@ lisp_to_json (Lisp_Object lisp)
413 return json_check (json_stringn (SSDATA (encoded), SBYTES (encoded))); 449 return json_check (json_stringn (SSDATA (encoded), SBYTES (encoded)));
414 } 450 }
415 451
416 /* LISP now must be a vector or hashtable. */ 452 /* LISP now must be a vector, hashtable, or alist. */
417 return lisp_to_json_toplevel (lisp); 453 return lisp_to_json_toplevel (lisp);
418} 454}
419 455
420DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, 1, NULL, 456DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, 1, NULL,
421 doc: /* Return the JSON representation of OBJECT as a string. 457 doc: /* Return the JSON representation of OBJECT as a string.
422OBJECT must be a vector or hashtable, and its elements can recursively 458OBJECT must be a vector, hashtable, or alist, and its elements can
423contain `:null', `:false', t, numbers, strings, or other vectors and 459recursively contain `:null', `:false', t, numbers, strings, or other
424hashtables. `:null', `:false', and t will be converted to JSON null, 460vectors hashtables, and alist. `:null', `:false', and t will be
425false, and true values, respectively. Vectors will be converted to 461converted to JSON null, false, and true values, respectively. Vectors
426JSON arrays, and hashtables to JSON objects. Hashtable keys must be 462will be converted to JSON arrays, and hashtables and alists to JSON
427strings without embedded null characters and must be unique within 463objects. Hashtable keys must be strings without embedded null
428each object. */) 464characters and must be unique within each object. Alist keys must be
465symbols; if a key is duplicate, the first instance is used. */)
429 (Lisp_Object object) 466 (Lisp_Object object)
430{ 467{
431 ptrdiff_t count = SPECPDL_INDEX (); 468 ptrdiff_t count = SPECPDL_INDEX ();