diff options
author | Petri Lehtinen <petri@digip.org> | 2016-02-25 07:13:04 +0200 |
---|---|---|
committer | Petri Lehtinen <petri@digip.org> | 2016-02-25 07:13:04 +0200 |
commit | 1927eeb4b4d96bde8e3bb70657e8b0dc7b98244e (patch) | |
tree | f1df72056e8a410ba38ad266b5442b067cc04e18 | |
parent | e08101704c46e7577f17942ce11990990131ff20 (diff) | |
parent | c8361441fe6b22cdab5201f5ab8d4e53d0417589 (diff) | |
download | jansson-1927eeb4b4d96bde8e3bb70657e8b0dc7b98244e.zip jansson-1927eeb4b4d96bde8e3bb70657e8b0dc7b98244e.tar.gz jansson-1927eeb4b4d96bde8e3bb70657e8b0dc7b98244e.tar.bz2 |
Merge pull request #270 from Alteous/master
Implemented json_pack() format specifiers 's?', 'o?', and 'O?'.
-rw-r--r-- | src/pack_unpack.c | 72 | ||||
-rw-r--r-- | test/suites/api/test_pack.c | 48 |
2 files changed, 103 insertions, 17 deletions
diff --git a/src/pack_unpack.c b/src/pack_unpack.c index 9b1ef9e..f6c700c 100644 --- a/src/pack_unpack.c +++ b/src/pack_unpack.c @@ -48,7 +48,6 @@ static const char * const type_names[] = { static const char unpack_value_starters[] = "{[siIbfFOon"; - static void scanner_init(scanner_t *s, json_error_t *error, size_t flags, const char *fmt) { @@ -291,6 +290,28 @@ error: return NULL; } +static json_t *pack_string(scanner_t *s, va_list *ap) +{ + char *str; + size_t len; + int ours; + int nullable; + + next_token(s); + nullable = token(s) == '?'; + if (!nullable) + prev_token(s); + + str = read_string(s, ap, "string", &len, &ours); + if (!str) { + return nullable ? json_null() : NULL; + } else if (ours) { + return jsonp_stringn_nocheck_own(str, len); + } else { + return json_stringn_nocheck(str, len); + } +} + static json_t *pack(scanner_t *s, va_list *ap) { switch(token(s)) { @@ -301,20 +322,7 @@ static json_t *pack(scanner_t *s, va_list *ap) return pack_array(s, ap); case 's': /* string */ - { - char *str; - size_t len; - int ours; - - str = read_string(s, ap, "string", &len, &ours); - if(!str) - return NULL; - - if (ours) - return jsonp_stringn_nocheck_own(str, len); - else - return json_stringn_nocheck(str, len); - } + return pack_string(s, ap); case 'n': /* null */ return json_null(); @@ -332,10 +340,40 @@ static json_t *pack(scanner_t *s, va_list *ap) return json_real(va_arg(*ap, double)); case 'O': /* a json_t object; increments refcount */ - return json_incref(va_arg(*ap, json_t *)); + { + int nullable; + json_t *json; + + next_token(s); + nullable = token(s) == '?'; + if (!nullable) + prev_token(s); + + json = va_arg(*ap, json_t *); + if (!json && nullable) { + return json_null(); + } else { + return json_incref(json); + } + } case 'o': /* a json_t object; doesn't increment refcount */ - return va_arg(*ap, json_t *); + { + int nullable; + json_t *json; + + next_token(s); + nullable = token(s) == '?'; + if (!nullable) + prev_token(s); + + json = va_arg(*ap, json_t *); + if (!json && nullable) { + return json_null(); + } else { + return json; + } + } default: set_error(s, "<format>", "Unexpected format character '%c'", diff --git a/test/suites/api/test_pack.c b/test/suites/api/test_pack.c index 9a8a62c..24c49a4 100644 --- a/test/suites/api/test_pack.c +++ b/test/suites/api/test_pack.c @@ -83,6 +83,22 @@ static void run_tests() fail("json_pack string refcount failed"); json_decref(value); + /* nullable string (defined case) */ + value = json_pack("s?", "test"); + if(!json_is_string(value) || strcmp("test", json_string_value(value))) + fail("json_pack nullable string (defined case) failed"); + if(value->refcount != (size_t)1) + fail("json_pack nullable string (defined case) refcount failed"); + json_decref(value); + + /* nullable string (NULL case) */ + value = json_pack("s?", NULL); + if(!json_is_null(value)) + fail("json_pack nullable string (NULL case) failed"); + if(value->refcount != (size_t)-1) + fail("json_pack nullable string (NULL case) refcount failed"); + json_decref(value); + /* string and length (int) */ value = json_pack("s#", "test asdf", 4); if(!json_is_string(value) || strcmp("test", json_string_value(value))) @@ -163,6 +179,22 @@ static void run_tests() fail("json_pack integer refcount failed"); json_decref(value); + /* non-incref'd nullable object (defined case) */ + value = json_pack("o?", json_integer(1)); + if(!json_is_integer(value) || json_integer_value(value) != 1) + fail("json_pack nullable object (defined case) failed"); + if(value->refcount != (size_t)1) + fail("json_pack nullable object (defined case) refcount failed"); + json_decref(value); + + /* non-incref'd nullable object (NULL case) */ + value = json_pack("o?", NULL); + if(!json_is_null(value)) + fail("json_pack nullable object (NULL case) failed"); + if(value->refcount != (size_t)-1) + fail("json_pack nullable object (NULL case) refcount failed"); + json_decref(value); + /* incref'd object */ value = json_pack("O", json_integer(1)); if(!json_is_integer(value) || json_integer_value(value) != 1) @@ -172,6 +204,22 @@ static void run_tests() json_decref(value); json_decref(value); + /* incref'd nullable object (defined case) */ + value = json_pack("O?", json_integer(1)); + if(!json_is_integer(value) || json_integer_value(value) != 1) + fail("json_pack incref'd nullable object (defined case) failed"); + if(value->refcount != (size_t)2) + fail("json_pack incref'd nullable object (defined case) refcount failed"); + json_decref(value); + json_decref(value); + + /* incref'd nullable object (NULL case) */ + value = json_pack("O?", NULL); + if(!json_is_null(value)) + fail("json_pack incref'd nullable object (NULL case) failed"); + if(value->refcount != (size_t)-1) + fail("json_pack incref'd nullable object (NULL case) refcount failed"); + /* simple object */ value = json_pack("{s:[]}", "foo"); if(!json_is_object(value) || json_object_size(value) != 1) |