Browse Source

JSON: encode UInt64 and Int64 as string

According to the OPC UA specification 1.04 part 6 paragraph 5.4.2.3:
"Int64 and UInt64 values shall be formatted as a decimal number encoded
as a JSON string."
Patrick Gansterer 5 years ago
parent
commit
b9bc3469c2
2 changed files with 33 additions and 26 deletions
  1. 19 12
      src/ua_types_encoding_json.c
  2. 14 14
      tests/check_types_builtin_json.c

+ 19 - 12
src/ua_types_encoding_json.c

@@ -368,29 +368,36 @@ ENCODE_JSON(Int32) {
 
 /* UInt64 */
 ENCODE_JSON(UInt64) {
-    char buf[21];
-    UA_UInt16 digits = itoaUnsigned(*src, buf, 10);
+    char buf[23];
+    buf[0] = '\"';
+    UA_UInt16 digits = itoaUnsigned(*src, buf + 1, 10);
+    buf[digits + 1] = '\"';
+    UA_UInt16 length = (UA_UInt16)(digits + 2);
 
-    if(ctx->pos + digits > ctx->end)
+    if(ctx->pos + length > ctx->end)
         return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
 
     if(!ctx->calcOnly)
-        memcpy(ctx->pos, buf, digits);
-    ctx->pos += digits;
+        memcpy(ctx->pos, buf, length);
+
+    ctx->pos += length;
     return UA_STATUSCODE_GOOD;
 }
 
 /* Int64 */
 ENCODE_JSON(Int64) {
-    char buf[21];
-    UA_UInt16 digits = itoaSigned(*src, buf);
+    char buf[23];
+    buf[0] = '\"';
+    UA_UInt16 digits = itoaSigned(*src, buf + 1);
+    buf[digits + 1] = '\"';
+    UA_UInt16 length = (UA_UInt16)(digits + 2);
 
-    if(ctx->pos + digits > ctx->end)
+    if(ctx->pos + length > ctx->end)
         return UA_STATUSCODE_BADENCODINGLIMITSEXCEEDED;
 
     if(!ctx->calcOnly)
-        memcpy(ctx->pos, buf, digits);
-    ctx->pos += digits;
+        memcpy(ctx->pos, buf, length);
+    ctx->pos += length;
     return UA_STATUSCODE_GOOD;
 }
 
@@ -1787,7 +1794,7 @@ DECODE_JSON(UInt32) {
 
 DECODE_JSON(UInt64) {
     CHECK_TOKEN_BOUNDS;
-    CHECK_PRIMITIVE;
+    CHECK_STRING;
     GET_TOKEN;
 
     UA_UInt64 out = 0;
@@ -1843,7 +1850,7 @@ DECODE_JSON(Int32) {
 
 DECODE_JSON(Int64) {
     CHECK_TOKEN_BOUNDS;
-    CHECK_PRIMITIVE;
+    CHECK_STRING;
     GET_TOKEN;
 
     UA_Int64 out = 0;

+ 14 - 14
tests/check_types_builtin_json.c

@@ -780,7 +780,7 @@ START_TEST(UA_UInt64_Max_Number_json_encode) {
     *bufPos = 0;
     // then
     ck_assert_int_eq(s, UA_STATUSCODE_GOOD);
-    char* result = "18446744073709551615";
+    char* result = "\"18446744073709551615\"";
     ck_assert_str_eq(result, (char*)buf.data);
     UA_ByteString_deleteMembers(&buf);
     UA_UInt64_delete(src);
@@ -805,7 +805,7 @@ START_TEST(UA_UInt64_Min_Number_json_encode) {
     *bufPos = 0;
     // then
     ck_assert_int_eq(s, UA_STATUSCODE_GOOD);
-    char* result = "0";
+    char* result = "\"0\"";
     ck_assert_str_eq(result, (char*)buf.data);
     UA_ByteString_deleteMembers(&buf);
     UA_UInt64_delete(src);
@@ -871,7 +871,7 @@ START_TEST(UA_Int64_Max_Number_json_encode) {
     *bufPos = 0;
     // then
     ck_assert_int_eq(s, UA_STATUSCODE_GOOD);
-    char* result = "9223372036854775807";
+    char* result = "\"9223372036854775807\"";
     ck_assert_str_eq(result, (char*)buf.data);
     UA_ByteString_deleteMembers(&buf); 
     UA_Int64_delete(src);
@@ -909,7 +909,7 @@ START_TEST(UA_Int64_Min_Number_json_encode) {
     *bufPos = 0;
     // then
     ck_assert_int_eq(s, UA_STATUSCODE_GOOD);
-    char* result = "-9223372036854775808";
+    char* result = "\"-9223372036854775808\"";
     ck_assert_str_eq(result, (char*)buf.data);
     UA_ByteString_deleteMembers(&buf); 
     UA_Int64_delete(src);
@@ -934,7 +934,7 @@ START_TEST(UA_Int64_Zero_Number_json_encode) {
     *bufPos = 0;
     // then
     ck_assert_int_eq(s, UA_STATUSCODE_GOOD);
-    char* result = "0";
+    char* result = "\"0\"";
     ck_assert_str_eq(result, (char*)buf.data);
     UA_ByteString_deleteMembers(&buf); 
     UA_Int64_delete(src);
@@ -2113,7 +2113,7 @@ START_TEST(UA_Variant_Number_json_encode) {
     *bufPos = 0;
     // then
     ck_assert_int_eq(s, UA_STATUSCODE_GOOD);
-    char* result = "{\"Type\":9,\"Body\":345634563456}";
+    char* result = "{\"Type\":9,\"Body\":\"345634563456\"}";
     ck_assert_str_eq(result, (char*)buf.data);
     UA_ByteString_deleteMembers(&buf); 
     UA_Variant_delete(src);
@@ -3577,7 +3577,7 @@ END_TEST
 START_TEST(UA_UInt64_Min_json_decode) {
     UA_Variant out;
     UA_Variant_init(&out);
-    UA_ByteString buf = UA_STRING("{\"Type\":9,\"Body\":0}");
+    UA_ByteString buf = UA_STRING("{\"Type\":9,\"Body\":\"0\"}");
     // when
     
     UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);
@@ -3600,7 +3600,7 @@ END_TEST
 START_TEST(UA_UInt64_Max_json_decode) {
     UA_Variant out;
     UA_Variant_init(&out);
-    UA_ByteString buf = UA_STRING("{\"Type\":9,\"Body\":18446744073709551615}");
+    UA_ByteString buf = UA_STRING("{\"Type\":9,\"Body\":\"18446744073709551615\"}");
     // when
     
     UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);
@@ -3623,7 +3623,7 @@ END_TEST
 START_TEST(UA_UInt64_Overflow_json_decode) {
     UA_Variant out;
     UA_Variant_init(&out);
-    UA_ByteString buf = UA_STRING("{\"Type\":9,\"Body\":18446744073709551616}");
+    UA_ByteString buf = UA_STRING("{\"Type\":9,\"Body\":\"18446744073709551616\"}");
     // when
 
     UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);
@@ -3736,7 +3736,7 @@ END_TEST
 START_TEST(UA_Int64_Min_json_decode) {
     UA_Variant out;
     UA_Variant_init(&out);
-    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":-9223372036854775808}");
+    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":\"-9223372036854775808\"}");
     // when
     
     UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);
@@ -3760,7 +3760,7 @@ END_TEST
 START_TEST(UA_Int64_Max_json_decode) {
     UA_Variant out;
     UA_Variant_init(&out);
-    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":9223372036854775807}");
+    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":\"9223372036854775807\"}");
     // when
     
     UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);
@@ -3784,7 +3784,7 @@ END_TEST
 START_TEST(UA_Int64_Overflow_json_decode) {
     UA_Variant out;
     UA_Variant_init(&out);
-    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":9223372036854775808}");
+    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":\"9223372036854775808\"}");
     // when
 
     UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);
@@ -3798,7 +3798,7 @@ END_TEST
 START_TEST(UA_Int64_TooBig_json_decode) {
     UA_Variant out;
     UA_Variant_init(&out);
-    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":111111111111111111111111111111}");
+    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":\"111111111111111111111111111111\"}");
     // when
 
     UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);
@@ -3812,7 +3812,7 @@ END_TEST
 START_TEST(UA_Int64_NoDigit_json_decode) {
     UA_Variant out;
     UA_Variant_init(&out);
-    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":a}");
+    UA_ByteString buf = UA_STRING("{\"Type\":8,\"Body\":\"a\"}");
     // when
 
     UA_StatusCode retval = UA_decodeJson(&buf, &out, &UA_TYPES[UA_TYPES_VARIANT]);