Browse Source

modify partial functions and testcase, in order to support automatic conversion for int64/uint64

tags/json-c-0.14-20200419
dota17 5 years ago
parent
commit
9532f94fa4
7 changed files with 169 additions and 42 deletions
  1. +79
    -33
      json_object.c
  2. +0
    -6
      json_object.h
  3. +6
    -0
      json_object_private.h
  4. +44
    -0
      tests/test_compare.c
  5. +8
    -0
      tests/test_compare.expected
  6. +31
    -3
      tests/test_int_add.c
  7. +1
    -0
      tests/test_int_add.expected

+ 79
- 33
json_object.c View File

@@ -594,10 +594,8 @@ json_bool json_object_get_boolean(const struct json_object *jso)
switch(jso->o.c_int.cint_type) { switch(jso->o.c_int.cint_type) {
case json_object_int_type_int64: case json_object_int_type_int64:
return (jso->o.c_int.cint.c_int64 != 0); return (jso->o.c_int.cint.c_int64 != 0);
case json_object_int_type_uint64:
return (jso->o.c_int.cint.c_uint64 != 0);
default: default:
return 0;
return (jso->o.c_int.cint.c_uint64 != 0);
} }
case json_type_double: case json_type_double:
return (jso->o.c_double != 0); return (jso->o.c_double != 0);
@@ -629,6 +627,8 @@ static int json_object_int_to_json_string(struct json_object* jso,
snprintf(sbuf, sizeof(sbuf), "%" PRId64, jso->o.c_int.cint.c_int64); snprintf(sbuf, sizeof(sbuf), "%" PRId64, jso->o.c_int.cint.c_int64);
else if (jso->o.c_int.cint_type == json_object_int_type_uint64) else if (jso->o.c_int.cint_type == json_object_int_type_uint64)
snprintf(sbuf, sizeof(sbuf), "%" PRIu64, jso->o.c_int.cint.c_uint64); snprintf(sbuf, sizeof(sbuf), "%" PRIu64, jso->o.c_int.cint.c_uint64);
else
return 0;
return printbuf_memappend (pb, sbuf, strlen(sbuf)); return printbuf_memappend (pb, sbuf, strlen(sbuf));
} }


@@ -692,10 +692,7 @@ int32_t json_object_get_int(const struct json_object *jso)
} }


int json_object_set_int(struct json_object *jso,int new_value){ int json_object_set_int(struct json_object *jso,int new_value){
if (!jso || jso->o_type!=json_type_int || jso->o.c_int.cint_type != json_object_int_type_int64)
return 0;
jso->o.c_int.cint.c_int64=new_value;
return 1;
return json_object_set_int64(jso,(int64_t)new_value);
} }


struct json_object* json_object_new_int64(int64_t i) struct json_object* json_object_new_int64(int64_t i)
@@ -797,41 +794,77 @@ uint64_t json_object_get_uint64(const struct json_object *jso)
} }


int json_object_set_int64(struct json_object *jso,int64_t new_value){ int json_object_set_int64(struct json_object *jso,int64_t new_value){
if (!jso || jso->o_type!=json_type_int || jso->o.c_int.cint_type != json_object_int_type_int64)
if (!jso || jso->o_type!=json_type_int)
return 0; return 0;
jso->o.c_int.cint.c_int64=new_value; jso->o.c_int.cint.c_int64=new_value;
jso->o.c_int.cint_type = json_object_int_type_int64;
return 1; return 1;
} }


int json_object_set_uint64(struct json_object *jso,uint64_t new_value){ int json_object_set_uint64(struct json_object *jso,uint64_t new_value){
if (!jso || jso->o_type!=json_type_int || jso->o.c_int.cint_type != json_object_int_type_uint64)
if (!jso || jso->o_type!=json_type_int)
return 0; return 0;
jso->o.c_int.cint.c_uint64=new_value; jso->o.c_int.cint.c_uint64=new_value;
jso->o.c_int.cint_type = json_object_int_type_uint64;
return 1; return 1;
} }


int json_object_int_inc(struct json_object *jso, int64_t val) { int json_object_int_inc(struct json_object *jso, int64_t val) {
if (!jso || jso->o_type != json_type_int || jso->o.c_int.cint_type != json_object_int_type_int64)
if (!jso || jso->o_type != json_type_int)
return 0;
switch(jso->o.c_int.cint_type) {
case json_object_int_type_int64:
if (val > 0 && jso->o.c_int.cint.c_int64 > INT64_MAX - val) {
jso->o.c_int.cint.c_uint64 = (uint64_t)jso->o.c_int.cint.c_int64 + (uint64_t)val;
jso->o.c_int.cint_type = json_object_int_type_uint64;
} else if (val < 0 && jso->o.c_int.cint.c_int64 < INT64_MIN - val) {
jso->o.c_int.cint.c_int64 = INT64_MIN;
} else {
jso->o.c_int.cint.c_int64 += val;
}
return 1;
case json_object_int_type_uint64:
if (val > 0 && jso->o.c_int.cint.c_uint64 > UINT64_MAX - (uint64_t)val) {
jso->o.c_int.cint.c_uint64 = UINT64_MAX;
} else if (val < 0 && jso->o.c_int.cint.c_uint64 < (uint64_t)(-val)) {
jso->o.c_int.cint.c_int64 = (int64_t)jso->o.c_int.cint.c_uint64 + val;
jso->o.c_int.cint_type = json_object_int_type_int64;
} else if (val < 0 && jso->o.c_int.cint.c_uint64 >= (uint64_t)(-val)) {
jso->o.c_int.cint.c_uint64 = jso->o.c_int.cint.c_uint64 - (uint64_t)(-val);
} else {
jso->o.c_int.cint.c_uint64 += val;
}
return 1;
default:
return 0; return 0;
if (val > 0 && jso->o.c_int.cint.c_int64 > INT64_MAX - val) {
jso->o.c_int.cint.c_int64 = INT64_MAX;
} else if (val < 0 && jso->o.c_int.cint.c_int64 < INT64_MIN - val) {
jso->o.c_int.cint.c_int64 = INT64_MIN;
} else {
jso->o.c_int.cint.c_int64 += val;
} }
return 1;
} }


int json_object_uint_inc(struct json_object *jso, uint64_t val) { int json_object_uint_inc(struct json_object *jso, uint64_t val) {
if (!jso || jso->o_type != json_type_int || jso->o.c_int.cint_type != json_object_int_type_uint64)
if (!jso || jso->o_type != json_type_int)
return 0;
switch(jso->o.c_int.cint_type) {
case json_object_int_type_int64:
if ((uint64_t)jso->o.c_int.cint.c_uint64 + val> UINT64_MAX) {
jso->o.c_int.cint.c_uint64 = UINT64_MAX;
jso->o.c_int.cint_type = json_object_int_type_uint64;
} else if ((uint64_t)jso->o.c_int.cint.c_uint64 + val < INT64_MAX) {
jso->o.c_int.cint.c_int64 += (int64_t)val;
} else {
jso->o.c_int.cint.c_uint64 =(uint64_t) jso->o.c_int.cint.c_uint64 + val;
jso->o.c_int.cint_type = json_object_int_type_uint64;
}
return 1;
case json_object_int_type_uint64:
if (jso->o.c_int.cint.c_uint64 > UINT64_MAX - val) {
jso->o.c_int.cint.c_uint64 = UINT64_MAX;
} else {
jso->o.c_int.cint.c_uint64 += val;
}
return 1;
default:
return 0; return 0;
if (jso->o.c_int.cint.c_uint64 > UINT64_MAX - val) {
jso->o.c_int.cint.c_uint64 = UINT64_MAX;
} else {
jso->o.c_int.cint.c_uint64 += val;
} }
return 1;
} }


/* json_object_double */ /* json_object_double */
@@ -1056,12 +1089,12 @@ double json_object_get_double(const struct json_object *jso)
return jso->o.c_double; return jso->o.c_double;
case json_type_int: case json_type_int:
switch(jso->o.c_int.cint_type) { switch(jso->o.c_int.cint_type) {
case json_object_int_type_int64:
case json_object_int_type_int64:
return jso->o.c_int.cint.c_int64; return jso->o.c_int.cint.c_int64;
case json_object_int_type_uint64: case json_object_int_type_uint64:
return jso->o.c_int.cint.c_uint64; return jso->o.c_int.cint.c_uint64;
default:
return 0.0;
default:
return 0.0;
} }
case json_type_boolean: case json_type_boolean:
return jso->o.c_boolean; return jso->o.c_boolean;
@@ -1441,14 +1474,27 @@ int json_object_equal(struct json_object* jso1, struct json_object* jso2)
return (jso1->o.c_double == jso2->o.c_double); return (jso1->o.c_double == jso2->o.c_double);


case json_type_int: case json_type_int:
if ((jso1->o.c_int.cint_type == json_object_int_type_int64)
&& (jso2->o.c_int.cint_type == json_object_int_type_int64))
return (jso1->o.c_int.cint.c_int64 == jso2->o.c_int.cint.c_int64);
else if ((jso1->o.c_int.cint_type == json_object_int_type_uint64)
&& (jso2->o.c_int.cint_type == json_object_int_type_uint64))
return (jso1->o.c_int.cint.c_uint64 == jso2->o.c_int.cint.c_uint64);
else
if (jso1->o.c_int.cint_type == json_object_int_type_int64) {
if (jso2->o.c_int.cint_type == json_object_int_type_int64)
return (jso1->o.c_int.cint.c_int64 == jso2->o.c_int.cint.c_int64);
if (jso2->o.c_int.cint_type == json_object_int_type_uint64) {
if (jso1->o.c_int.cint.c_int64 < 0)
return 0;
return ((uint64_t)jso1->o.c_int.cint.c_int64 == jso2->o.c_int.cint.c_uint64);
}
return 0; return 0;
}
if (jso1->o.c_int.cint_type == json_object_int_type_uint64) {
if (jso2->o.c_int.cint_type == json_object_int_type_uint64)
return (jso1->o.c_int.cint.c_uint64 == jso2->o.c_int.cint.c_uint64);
if (jso2->o.c_int.cint_type == json_object_int_type_int64){
if (jso2->o.c_int.cint.c_int64 < 0)
return 0;
return (jso1->o.c_int.cint.c_uint64 == (uint64_t)jso2->o.c_int.cint.c_int64);
}
return 0;
}
return 0;


case json_type_string: case json_type_string:
return (jso1->o.c_string.len == jso2->o.c_string.len && return (jso1->o.c_string.len == jso2->o.c_string.len &&


+ 0
- 6
json_object.h View File

@@ -181,12 +181,6 @@ typedef enum json_type {
json_type_string json_type_string
} json_type; } json_type;


/* json object int type, support extension*/
typedef enum json_object_int_type {
json_object_int_type_int64,
json_object_int_type_uint64
}json_object_int_type;

/* reference counting functions */ /* reference counting functions */


/** /**


+ 6
- 0
json_object_private.h View File

@@ -24,6 +24,12 @@ extern "C" {


typedef void (json_object_private_delete_fn)(struct json_object *o); typedef void (json_object_private_delete_fn)(struct json_object *o);


/* json object int type, support extension*/
typedef enum json_object_int_type {
json_object_int_type_int64,
json_object_int_type_uint64
}json_object_int_type;

struct json_object struct json_object
{ {
enum json_type o_type; enum json_type o_type;


+ 44
- 0
tests/test_compare.c View File

@@ -15,9 +15,11 @@ int main()
struct json_object *int1 = json_object_new_int(0); struct json_object *int1 = json_object_new_int(0);
struct json_object *int2 = json_object_new_int(1); struct json_object *int2 = json_object_new_int(1);
struct json_object *int3 = json_object_new_int(1); struct json_object *int3 = json_object_new_int(1);
struct json_object *int4 = json_object_new_int(-1);
struct json_object *uint1 = json_object_new_uint64(0); struct json_object *uint1 = json_object_new_uint64(0);
struct json_object *uint2 = json_object_new_uint64(1); struct json_object *uint2 = json_object_new_uint64(1);
struct json_object *uint3 = json_object_new_uint64(1); struct json_object *uint3 = json_object_new_uint64(1);
struct json_object *uint4 = json_object_new_uint64((uint64_t)INT64_MAX + 100);


if (!json_object_equal(int1, int2)) if (!json_object_equal(int1, int2))
printf("JSON integer comparison is correct\n"); printf("JSON integer comparison is correct\n");
@@ -49,12 +51,54 @@ int main()
else else
printf("JSON same usigned integer comparison failed\n"); printf("JSON same usigned integer comparison failed\n");


if (json_object_equal(int2, uint2))
printf("JSON integer & usigned integer comparison is correct\n");
else
printf("JSON integer & usigned integer comparison failed\n");

if (!json_object_equal(int2, uint4))
printf("JSON integer & usigned integer comparison is correct\n");
else
printf("JSON integer & usigned integer comparison failed\n");

if (!json_object_equal(int4, uint2))
printf("JSON integer & usigned integer comparison is correct\n");
else
printf("JSON integer & usigned integer comparison failed\n");

if (!json_object_equal(int4, uint4))
printf("JSON integer & usigned integer comparison is correct\n");
else
printf("JSON integer & usigned integer comparison failed\n");

if (json_object_equal(uint2, int2))
printf("JSON usigned integer & integer comparison is correct\n");
else
printf("JSON usigned integer & integer comparison failed\n");

if (!json_object_equal(uint2, int4))
printf("JSON usigned integer & integer comparison is correct\n");
else
printf("JSON usigned integer & integer comparison failed\n");

if (!json_object_equal(uint4, int2))
printf("JSON usigned integer & integer comparison is correct\n");
else
printf("JSON usigned integer & integer comparison failed\n");

if (!json_object_equal(uint4, int4))
printf("JSON usigned integer & integer comparison is correct\n");
else
printf("JSON usigned integer & integer comparison failed\n");

json_object_put(int1); json_object_put(int1);
json_object_put(int2); json_object_put(int2);
json_object_put(int3); json_object_put(int3);
json_object_put(int4);
json_object_put(uint1); json_object_put(uint1);
json_object_put(uint2); json_object_put(uint2);
json_object_put(uint3); json_object_put(uint3);
json_object_put(uint4);


/* string tests */ /* string tests */
struct json_object *str1 = json_object_new_string("TESTSTRING"); struct json_object *str1 = json_object_new_string("TESTSTRING");


+ 8
- 0
tests/test_compare.expected View File

@@ -4,6 +4,14 @@ JSON same integer comparison is correct
JSON usigned integer comparison is correct JSON usigned integer comparison is correct
JSON same usigned object comparison is correct JSON same usigned object comparison is correct
JSON same usigned integer comparison is correct JSON same usigned integer comparison is correct
JSON integer & usigned integer comparison is correct
JSON integer & usigned integer comparison is correct
JSON integer & usigned integer comparison is correct
JSON integer & usigned integer comparison is correct
JSON usigned integer & integer comparison is correct
JSON usigned integer & integer comparison is correct
JSON usigned integer & integer comparison is correct
JSON usigned integer & integer comparison is correct
Comparing equal strings is correct Comparing equal strings is correct
Comparing different strings is correct Comparing different strings is correct
Comparing equal doubles is correct Comparing equal doubles is correct


+ 31
- 3
tests/test_int_add.c View File

@@ -25,13 +25,27 @@ int main(int argc, char **argv)
tmp = json_object_new_int64(321321321); tmp = json_object_new_int64(321321321);
json_object_int_inc(tmp, 321321321); json_object_int_inc(tmp, 321321321);
assert(json_object_get_int(tmp) == 642642642); assert(json_object_get_int(tmp) == 642642642);
json_object_uint_inc(tmp, 321321321U);
assert(json_object_get_int(tmp) == 963963963);
json_object_put(tmp); json_object_put(tmp);
printf("INT64 ADD PASSED\n"); printf("INT64 ADD PASSED\n");
tmp = json_object_new_int64(INT64_MAX); tmp = json_object_new_int64(INT64_MAX);
json_object_int_inc(tmp, 100); json_object_int_inc(tmp, 100);
assert(json_object_get_int64(tmp) == INT64_MAX); assert(json_object_get_int64(tmp) == INT64_MAX);
assert(json_object_get_uint64(tmp) == (uint64_t)INT64_MAX + 100U);
json_object_int_inc(tmp, -100); json_object_int_inc(tmp, -100);
assert(json_object_get_int64(tmp) != INT64_MAX);
assert(json_object_get_int64(tmp) == INT64_MAX);
assert(json_object_get_uint64(tmp) == (uint64_t)INT64_MAX);
json_object_put(tmp);
tmp = json_object_new_int64(100);
json_object_uint_inc(tmp, 100);
assert(json_object_get_int64(tmp) == 200);
json_object_uint_inc(tmp, (uint64_t)INT64_MAX);
assert(json_object_get_int64(tmp) == INT64_MAX);
assert(json_object_get_uint64(tmp) == (uint64_t)INT64_MAX+200);
json_object_uint_inc(tmp, UINT64_MAX);
assert(json_object_get_int64(tmp) == INT64_MAX);
assert(json_object_get_uint64(tmp) == UINT64_MAX);
json_object_put(tmp); json_object_put(tmp);
printf("INT64 ADD OVERFLOW PASSED\n"); printf("INT64 ADD OVERFLOW PASSED\n");
tmp = json_object_new_int64(INT64_MIN); tmp = json_object_new_int64(INT64_MIN);
@@ -45,14 +59,28 @@ int main(int argc, char **argv)
json_object_uint_inc(tmp, 321321321); json_object_uint_inc(tmp, 321321321);
assert(json_object_get_uint64(tmp) == 642642642); assert(json_object_get_uint64(tmp) == 642642642);
json_object_put(tmp); json_object_put(tmp);
// uint64 + negative int64--> negative int64
tmp = json_object_new_uint64(400);
json_object_int_inc(tmp, -200);
assert(json_object_get_int64(tmp) == 200);
assert(json_object_get_uint64(tmp) == 200);
json_object_put(tmp);
printf("UINT64 ADD PASSED\n"); printf("UINT64 ADD PASSED\n");
tmp = json_object_new_uint64(UINT64_MAX); tmp = json_object_new_uint64(UINT64_MAX);
json_object_uint_inc(tmp, 100); json_object_uint_inc(tmp, 100);
assert(json_object_get_uint64(tmp) == UINT64_MAX); assert(json_object_get_uint64(tmp) == UINT64_MAX);
json_object_uint_inc(tmp, -100);
assert(json_object_get_uint64(tmp) != INT64_MAX);
json_object_put(tmp);
tmp = json_object_new_uint64(UINT64_MAX - 100);
json_object_uint_inc(tmp, 200);
assert(json_object_get_uint64(tmp) == UINT64_MAX);
json_object_put(tmp); json_object_put(tmp);
printf("UINT64 ADD OVERFLOW PASSED\n"); printf("UINT64 ADD OVERFLOW PASSED\n");
tmp = json_object_new_uint64(100);
json_object_int_inc(tmp, -200);
assert(json_object_get_int64(tmp) == -100);
assert(json_object_get_uint64(tmp) == 0);
json_object_put(tmp);
printf("UINT64 ADD UNDERFLOW PASSED\n");


printf("PASSED\n"); printf("PASSED\n");
return 0; return 0;


+ 1
- 0
tests/test_int_add.expected View File

@@ -6,4 +6,5 @@ INT64 ADD OVERFLOW PASSED
INT64 ADD UNDERFLOW PASSED INT64 ADD UNDERFLOW PASSED
UINT64 ADD PASSED UINT64 ADD PASSED
UINT64 ADD OVERFLOW PASSED UINT64 ADD OVERFLOW PASSED
UINT64 ADD UNDERFLOW PASSED
PASSED PASSED

Loading…
Cancel
Save