Implement JSON_PRESERVE_ORDER encoding flag
With this encoding flag, the object key-value pairs in output are in the same order in which they were first inserted into the object. To make this possible, a key of an object is now a serial number plus a string. An object keeps an increasing counter which is used to assign serial number to the keys. Hashing, comparison and public API functions were changed to act only on the string part, i.e. the serial number is ignored everywhere else but in the encoder, where it's used to order object keys if JSON_PRESERVE_ORDER flag is used.
This commit is contained in:
@@ -53,6 +53,9 @@ int main(int argc, char *argv[])
|
||||
if(getenv_int("JSON_ENSURE_ASCII"))
|
||||
flags |= JSON_ENSURE_ASCII;
|
||||
|
||||
if(getenv_int("JSON_PRESERVE_ORDER"))
|
||||
flags |= JSON_PRESERVE_ORDER;
|
||||
|
||||
if(getenv_int("JSON_SORT_KEYS"))
|
||||
flags |= JSON_SORT_KEYS;
|
||||
|
||||
|
||||
@@ -402,6 +402,41 @@ static void test_misc()
|
||||
json_decref(object);
|
||||
}
|
||||
|
||||
static void test_preserve_order()
|
||||
{
|
||||
json_t *object;
|
||||
char *result;
|
||||
|
||||
const char *expected = "{\"foobar\": 1, \"bazquux\": 6, \"lorem ipsum\": 3, \"sit amet\": 5, \"helicopter\": 7}";
|
||||
|
||||
object = json_object();
|
||||
|
||||
json_object_set_new(object, "foobar", json_integer(1));
|
||||
json_object_set_new(object, "bazquux", json_integer(2));
|
||||
json_object_set_new(object, "lorem ipsum", json_integer(3));
|
||||
json_object_set_new(object, "dolor", json_integer(4));
|
||||
json_object_set_new(object, "sit amet", json_integer(5));
|
||||
|
||||
/* changing a value should preserve the order */
|
||||
json_object_set_new(object, "bazquux", json_integer(6));
|
||||
|
||||
/* deletion shouldn't change the order of others */
|
||||
json_object_del(object, "dolor");
|
||||
|
||||
/* add a new item just to make sure */
|
||||
json_object_set_new(object, "helicopter", json_integer(7));
|
||||
|
||||
result = json_dumps(object, JSON_PRESERVE_ORDER);
|
||||
|
||||
if(strcmp(expected, result) != 0) {
|
||||
fprintf(stderr, "%s != %s", expected, result);
|
||||
fail("JSON_PRESERVE_ORDER doesn't work");
|
||||
}
|
||||
|
||||
free(result);
|
||||
json_decref(object);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_misc();
|
||||
@@ -410,6 +445,7 @@ int main()
|
||||
test_circular();
|
||||
test_set_nocheck();
|
||||
test_iterators();
|
||||
test_preserve_order();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
1
test/suites/encoding-flags/preserve-order/env
Normal file
1
test/suites/encoding-flags/preserve-order/env
Normal file
@@ -0,0 +1 @@
|
||||
export JSON_PRESERVE_ORDER=1
|
||||
1
test/suites/encoding-flags/preserve-order/input
Normal file
1
test/suites/encoding-flags/preserve-order/input
Normal file
@@ -0,0 +1 @@
|
||||
{"foo": 1, "bar": 2, "asdf": 3, "deadbeef": 4, "badc0ffee": 5, "qwerty": 6}
|
||||
1
test/suites/encoding-flags/preserve-order/output
Normal file
1
test/suites/encoding-flags/preserve-order/output
Normal file
@@ -0,0 +1 @@
|
||||
{"foo": 1, "bar": 2, "asdf": 3, "deadbeef": 4, "badc0ffee": 5, "qwerty": 6}
|
||||
Reference in New Issue
Block a user