Implemented json_pack() format specifiers 's?', 'o?', and 'O?'.
This commit is contained in:
parent
e08101704c
commit
811965b475
@ -48,7 +48,6 @@ static const char * const type_names[] = {
|
|||||||
|
|
||||||
static const char unpack_value_starters[] = "{[siIbfFOon";
|
static const char unpack_value_starters[] = "{[siIbfFOon";
|
||||||
|
|
||||||
|
|
||||||
static void scanner_init(scanner_t *s, json_error_t *error,
|
static void scanner_init(scanner_t *s, json_error_t *error,
|
||||||
size_t flags, const char *fmt)
|
size_t flags, const char *fmt)
|
||||||
{
|
{
|
||||||
@ -291,6 +290,26 @@ error:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static json_t *pack_string(scanner_t *s, va_list *ap) {
|
||||||
|
char *str;
|
||||||
|
size_t len;
|
||||||
|
int ours;
|
||||||
|
int nullable;
|
||||||
|
|
||||||
|
nullable = s->start[1] == '?';
|
||||||
|
if (nullable)
|
||||||
|
next_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)
|
static json_t *pack(scanner_t *s, va_list *ap)
|
||||||
{
|
{
|
||||||
switch(token(s)) {
|
switch(token(s)) {
|
||||||
@ -301,20 +320,7 @@ static json_t *pack(scanner_t *s, va_list *ap)
|
|||||||
return pack_array(s, ap);
|
return pack_array(s, ap);
|
||||||
|
|
||||||
case 's': /* string */
|
case 's': /* string */
|
||||||
{
|
return pack_string(s, ap);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'n': /* null */
|
case 'n': /* null */
|
||||||
return json_null();
|
return json_null();
|
||||||
@ -332,10 +338,38 @@ static json_t *pack(scanner_t *s, va_list *ap)
|
|||||||
return json_real(va_arg(*ap, double));
|
return json_real(va_arg(*ap, double));
|
||||||
|
|
||||||
case 'O': /* a json_t object; increments refcount */
|
case 'O': /* a json_t object; increments refcount */
|
||||||
return json_incref(va_arg(*ap, json_t *));
|
{
|
||||||
|
int nullable;
|
||||||
|
json_t *json;
|
||||||
|
|
||||||
|
nullable = s->start[1] == '?';
|
||||||
|
if (nullable)
|
||||||
|
next_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 */
|
case 'o': /* a json_t object; doesn't increment refcount */
|
||||||
return va_arg(*ap, json_t *);
|
{
|
||||||
|
int nullable;
|
||||||
|
json_t *json;
|
||||||
|
|
||||||
|
nullable = s->start[1] == '?';
|
||||||
|
if (nullable)
|
||||||
|
next_token(s);
|
||||||
|
|
||||||
|
json = va_arg(*ap, json_t *);
|
||||||
|
if (!json && nullable) {
|
||||||
|
return json_null();
|
||||||
|
} else {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
set_error(s, "<format>", "Unexpected format character '%c'",
|
set_error(s, "<format>", "Unexpected format character '%c'",
|
||||||
|
@ -83,6 +83,22 @@ static void run_tests()
|
|||||||
fail("json_pack string refcount failed");
|
fail("json_pack string refcount failed");
|
||||||
json_decref(value);
|
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) */
|
/* string and length (int) */
|
||||||
value = json_pack("s#", "test asdf", 4);
|
value = json_pack("s#", "test asdf", 4);
|
||||||
if(!json_is_string(value) || strcmp("test", json_string_value(value)))
|
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");
|
fail("json_pack integer refcount failed");
|
||||||
json_decref(value);
|
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 */
|
/* incref'd object */
|
||||||
value = json_pack("O", json_integer(1));
|
value = json_pack("O", json_integer(1));
|
||||||
if(!json_is_integer(value) || json_integer_value(value) != 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);
|
||||||
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 */
|
/* simple object */
|
||||||
value = json_pack("{s:[]}", "foo");
|
value = json_pack("{s:[]}", "foo");
|
||||||
if(!json_is_object(value) || json_object_size(value) != 1)
|
if(!json_is_object(value) || json_object_size(value) != 1)
|
||||||
|
Loading…
Reference in New Issue
Block a user