From: dota17 Date: Thu, 27 Feb 2020 07:01:06 +0000 (+0800) Subject: modify partial functions and testcase, in order to support automatic conversion for... X-Git-Tag: json-c-0.14-20200419~52^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9532f94fa4a4a8d3fb5dbbd3ed797a2622de536b;p=json-c modify partial functions and testcase, in order to support automatic conversion for int64/uint64 --- diff --git a/json_object.c b/json_object.c index b8209cc..bd820d2 100644 --- a/json_object.c +++ b/json_object.c @@ -594,10 +594,8 @@ json_bool json_object_get_boolean(const struct json_object *jso) switch(jso->o.c_int.cint_type) { case json_object_int_type_int64: 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: - return 0; + return (jso->o.c_int.cint.c_uint64 != 0); } case json_type_double: 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); 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); + else + return 0; 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){ - 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) @@ -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){ - 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; jso->o.c_int.cint.c_int64=new_value; + jso->o.c_int.cint_type = json_object_int_type_int64; return 1; } 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; jso->o.c_int.cint.c_uint64=new_value; + jso->o.c_int.cint_type = json_object_int_type_uint64; return 1; } 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; - 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) { - 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; - 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 */ @@ -1056,12 +1089,12 @@ double json_object_get_double(const struct json_object *jso) return jso->o.c_double; case json_type_int: 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; case json_object_int_type_uint64: return jso->o.c_int.cint.c_uint64; - default: - return 0.0; + default: + return 0.0; } case json_type_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); 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; + } + 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: return (jso1->o.c_string.len == jso2->o.c_string.len && diff --git a/json_object.h b/json_object.h index 2fa9b3b..297a2e8 100644 --- a/json_object.h +++ b/json_object.h @@ -181,12 +181,6 @@ typedef enum json_type { json_type_string } 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 */ /** diff --git a/json_object_private.h b/json_object_private.h index cf7867e..3bda3df 100644 --- a/json_object_private.h +++ b/json_object_private.h @@ -24,6 +24,12 @@ extern "C" { 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 { enum json_type o_type; diff --git a/tests/test_compare.c b/tests/test_compare.c index 13ad3ea..cbb7ccc 100644 --- a/tests/test_compare.c +++ b/tests/test_compare.c @@ -15,9 +15,11 @@ int main() struct json_object *int1 = json_object_new_int(0); struct json_object *int2 = 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 *uint2 = 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)) printf("JSON integer comparison is correct\n"); @@ -49,12 +51,54 @@ int main() else 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(int2); json_object_put(int3); + json_object_put(int4); json_object_put(uint1); json_object_put(uint2); json_object_put(uint3); + json_object_put(uint4); /* string tests */ struct json_object *str1 = json_object_new_string("TESTSTRING"); diff --git a/tests/test_compare.expected b/tests/test_compare.expected index a183aab..a08fab9 100644 --- a/tests/test_compare.expected +++ b/tests/test_compare.expected @@ -4,6 +4,14 @@ JSON same integer comparison is correct JSON usigned integer comparison is correct JSON same usigned object 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 different strings is correct Comparing equal doubles is correct diff --git a/tests/test_int_add.c b/tests/test_int_add.c index 8b02e79..bd76ac5 100644 --- a/tests/test_int_add.c +++ b/tests/test_int_add.c @@ -25,13 +25,27 @@ int main(int argc, char **argv) tmp = json_object_new_int64(321321321); json_object_int_inc(tmp, 321321321); assert(json_object_get_int(tmp) == 642642642); + json_object_uint_inc(tmp, 321321321U); + assert(json_object_get_int(tmp) == 963963963); json_object_put(tmp); printf("INT64 ADD PASSED\n"); tmp = json_object_new_int64(INT64_MAX); json_object_int_inc(tmp, 100); 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); - 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); printf("INT64 ADD OVERFLOW PASSED\n"); tmp = json_object_new_int64(INT64_MIN); @@ -45,14 +59,28 @@ int main(int argc, char **argv) json_object_uint_inc(tmp, 321321321); assert(json_object_get_uint64(tmp) == 642642642); 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"); tmp = json_object_new_uint64(UINT64_MAX); json_object_uint_inc(tmp, 100); 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); 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"); return 0; diff --git a/tests/test_int_add.expected b/tests/test_int_add.expected index 144233a..f9348d4 100644 --- a/tests/test_int_add.expected +++ b/tests/test_int_add.expected @@ -6,4 +6,5 @@ INT64 ADD OVERFLOW PASSED INT64 ADD UNDERFLOW PASSED UINT64 ADD PASSED UINT64 ADD OVERFLOW PASSED +UINT64 ADD UNDERFLOW PASSED PASSED