]> granicus.if.org Git - json-c/commitdiff
modify partial functions and testcase, in order to support automatic conversion for...
authordota17 <chenguopingdota@163.com>
Thu, 27 Feb 2020 07:01:06 +0000 (15:01 +0800)
committerdota17 <chenguopingdota@163.com>
Fri, 28 Feb 2020 01:25:02 +0000 (09:25 +0800)
json_object.c
json_object.h
json_object_private.h
tests/test_compare.c
tests/test_compare.expected
tests/test_int_add.c
tests/test_int_add.expected

index b8209cc44c3d7f3c18f15159a10e2ef9fcbf30e0..bd820d2fe20e12a717a5533155e0f1b640a3f374 100644 (file)
@@ -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 &&
index 2fa9b3b6b1fd3ac37711d9932f398fe48dad44f1..297a2e80199e6e32c9c7a5a853c70df013aae9f7 100644 (file)
@@ -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 */
 
 /**
index cf7867eb20e834da2e173960b046e70944956deb..3bda3df05ae381556f5a5880dbfd9cc456e9a3e3 100644 (file)
@@ -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;
index 13ad3ea061393a97b888b94922e367d593b3d663..cbb7cccd2529766d8ab454162c29d40e1d7096f7 100644 (file)
@@ -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");
index a183aabe0709aa1e3eba567ad5c51fce26ff5b8f..a08fab9cae95eb942330fef1a4507020a3a08dc8 100644 (file)
@@ -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
index 8b02e7935b70e6432089bca2d06b1d13c4349288..bd76ac53208848b51a01757fdd7e6c6bedd6c937 100644 (file)
@@ -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;
index 144233ab4fc75bcf0664992e16731382cf3c1163..f9348d4b097a085cd38dd99b8d411b4952dbbf3a 100644 (file)
@@ -6,4 +6,5 @@ INT64 ADD OVERFLOW PASSED
 INT64 ADD UNDERFLOW PASSED
 UINT64 ADD PASSED
 UINT64 ADD OVERFLOW PASSED
+UINT64 ADD UNDERFLOW PASSED
 PASSED