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:
Petri Lehtinen
2010-02-09 21:29:33 +02:00
parent 307167fb66
commit f18ef5144a
10 changed files with 115 additions and 20 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -0,0 +1 @@
export JSON_PRESERVE_ORDER=1

View File

@@ -0,0 +1 @@
{"foo": 1, "bar": 2, "asdf": 3, "deadbeef": 4, "badc0ffee": 5, "qwerty": 6}

View File

@@ -0,0 +1 @@
{"foo": 1, "bar": 2, "asdf": 3, "deadbeef": 4, "badc0ffee": 5, "qwerty": 6}