소스 검색

Add UA_NodeId_toString method

Stefan Profanter 5 년 전
부모
커밋
52795849ea
2개의 변경된 파일230개의 추가작업 그리고 0개의 파일을 삭제
  1. 91 0
      include/ua_plugin_log.h
  2. 139 0
      tests/check_utils.c

+ 91 - 0
include/ua_plugin_log.h

@@ -16,6 +16,9 @@ extern "C" {
 #include <stdarg.h>
 #include "ua_config.h"
 
+#include "ua_types.h"
+#include "ua_types_generated_handling.h"
+
 /**
  * Logging Plugin API
  * ==================
@@ -118,6 +121,94 @@ UA_LOG_FATAL(UA_Logger logger, UA_LogCategory category, const char *msg, ...) {
 #define UA_PRINTF_STRING_FORMAT "\"%.*s\""
 #define UA_PRINTF_STRING_DATA(STRING) (int)(STRING).length, (STRING).data
 
+//TODO remove when we merge architectures pull request
+#ifndef UA_snprintf
+# include <stdio.h>
+# if defined(_WIN32)
+#  define UA_snprintf(source, size, string, ...) _snprintf_s(source, size, _TRUNCATE, string, __VA_ARGS__)
+# else
+#  define UA_snprintf snprintf
+# endif
+#endif
+
+static UA_INLINE UA_StatusCode
+UA_ByteString_toString(const UA_ByteString *byteString, UA_String *str) {
+    if (str->length != 0) {
+        UA_free(str->data);
+        str->data = NULL;
+        str->length = 0;
+    }
+    if (byteString == NULL || byteString->data == NULL)
+        return UA_STATUSCODE_GOOD;
+    if (byteString == str)
+        return UA_STATUSCODE_BADINVALIDARGUMENT;
+
+    str->length = byteString->length*2;
+    str->data = (UA_Byte*)UA_malloc(str->length+1);
+    if (str->data == NULL)
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+
+    for (size_t i=0; i<byteString->length; i++)
+        UA_snprintf((char*)&str->data[i*2], 2+1, "%02x", byteString->data[i]);
+    return UA_STATUSCODE_GOOD;
+}
+
+static UA_INLINE UA_StatusCode
+UA_NodeId_toString(const UA_NodeId *nodeId, UA_String *nodeIdStr) {
+    if (nodeIdStr->length != 0) {
+        UA_free(nodeIdStr->data);
+        nodeIdStr->data = NULL;
+        nodeIdStr->length = 0;
+    }
+    if (nodeId == NULL)
+        return UA_STATUSCODE_GOOD;
+
+
+    UA_ByteString byteStr = UA_BYTESTRING_NULL;
+    switch (nodeId->identifierType) {
+        /* for all the lengths below we add the constant for: */
+        /* strlen("ns=XXXXXX;i=")=11 */
+        case UA_NODEIDTYPE_NUMERIC:
+            /* ns (2 byte, 65535) = 5 chars, numeric (4 byte, 4294967295) = 10 chars, delim = 1 , nullbyte = 1-> 17 chars */
+            nodeIdStr->length = 11 + 10 + 1;
+            nodeIdStr->data = (UA_Byte*)UA_malloc(nodeIdStr->length);
+            if (nodeIdStr->data == NULL)
+                return UA_STATUSCODE_BADOUTOFMEMORY;
+            UA_snprintf((char*)nodeIdStr->data, nodeIdStr->length, "ns=%d;i=%lu",
+                        nodeId->namespaceIndex, (unsigned long )nodeId->identifier.numeric);
+            break;
+        case UA_NODEIDTYPE_STRING:
+            /* ns (16bit) = 5 chars, strlen + nullbyte */
+            nodeIdStr->length = 11 + nodeId->identifier.string.length + 1;
+            nodeIdStr->data = (UA_Byte*)UA_malloc(nodeIdStr->length);
+            if (nodeIdStr->data == NULL)
+                return UA_STATUSCODE_BADOUTOFMEMORY;
+            UA_snprintf((char*)nodeIdStr->data, nodeIdStr->length, "ns=%d;i=%.*s", nodeId->namespaceIndex,
+                        (int)nodeId->identifier.string.length, nodeId->identifier.string.data);
+            break;
+        case UA_NODEIDTYPE_GUID:
+            /* ns (16bit) = 5 chars + strlen(A123456C-0ABC-1A2B-815F-687212AAEE1B)=36 + nullbyte */
+            nodeIdStr->length = 11 + 36 + 1;
+            nodeIdStr->data = (UA_Byte*)UA_malloc(nodeIdStr->length);
+            if (nodeIdStr->data == NULL)
+                return UA_STATUSCODE_BADOUTOFMEMORY;
+            UA_snprintf((char*)nodeIdStr->data, nodeIdStr->length, "ns=%d;i=" UA_PRINTF_GUID_FORMAT,
+                        nodeId->namespaceIndex, UA_PRINTF_GUID_DATA(nodeId->identifier.guid));
+            break;
+        case UA_NODEIDTYPE_BYTESTRING:
+            UA_ByteString_toString(&nodeId->identifier.byteString, &byteStr);
+            /* ns (16bit) = 5 chars + LEN + nullbyte */
+            nodeIdStr->length = 11 + byteStr.length + 1;
+            nodeIdStr->data = (UA_Byte*)UA_malloc(nodeIdStr->length);
+            if (nodeIdStr->data == NULL)
+                return UA_STATUSCODE_BADOUTOFMEMORY;
+            UA_snprintf((char*)nodeIdStr->data, nodeIdStr->length, "ns=%d;i=%.*s", nodeId->namespaceIndex, (int)byteStr.length, byteStr.data);
+            UA_String_deleteMembers(&byteStr);
+            break;
+    }
+    return UA_STATUSCODE_GOOD;
+}
+
 
 #ifdef __cplusplus
 } // extern "C"

+ 139 - 0
tests/check_utils.c

@@ -155,6 +155,136 @@ START_TEST(StatusCode_msg) {
 }
 END_TEST
 
+
+static void assertNodeIdString(const UA_String *gotStr, const char* expectedStr) {
+    size_t expectedStringLength = strlen(expectedStr);
+    ck_assert_uint_ge(gotStr->length, expectedStringLength);
+    char *gotChars = (char*)UA_malloc(gotStr->length+1);
+    memcpy(gotChars, gotStr->data, gotStr->length);
+    gotChars[gotStr->length] = 0;
+    ck_assert_str_eq(gotChars, expectedStr);
+    UA_free(gotChars);
+}
+
+START_TEST(idToStringNumeric) {
+    UA_NodeId n;
+    UA_String str = UA_STRING_NULL;
+
+    n = UA_NODEID_NUMERIC(0,0);
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=0;i=0");
+
+    n = UA_NODEID_NUMERIC(12345,1234567890);
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=12345;i=1234567890");
+
+    n = UA_NODEID_NUMERIC(0xFFFF,0xFFFFFFFF);
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=65535;i=4294967295");
+
+    UA_String_deleteMembers(&str);
+} END_TEST
+
+START_TEST(idToStringString) {
+    UA_NodeId n;
+    UA_String str = UA_STRING_NULL;
+
+    n = UA_NODEID_STRING(0,"");
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=0;i=");
+
+    n = UA_NODEID_STRING(54321,"Some String");
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=54321;i=Some String");
+
+    UA_String_deleteMembers(&str);
+} END_TEST
+
+START_TEST(idToStringGuid) {
+    UA_NodeId n;
+    UA_String str = UA_STRING_NULL;
+
+    UA_Guid g = UA_GUID_NULL;
+
+    n = UA_NODEID_GUID(0,UA_GUID_NULL);
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=0;i=00000000-0000-0000-0000-000000000000");
+
+    g.data1 = 0xA123456C;
+    g.data2 = 0x0ABC;
+    g.data3 = 0x1A2B;
+    g.data4[0] = 0x81;
+    g.data4[1] = 0x5F;
+    g.data4[2] = 0x68;
+    g.data4[3] = 0x72;
+    g.data4[4] = 0x12;
+    g.data4[5] = 0xAA;
+    g.data4[6] = 0xEE;
+    g.data4[7] = 0x1B;
+
+    n = UA_NODEID_GUID(65535,g);
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=65535;i=a123456c-0abc-1a2b-815f-687212aaee1b");
+
+    g.data1 = 0xFFFFFFFF;
+    g.data2 = 0xFFFF;
+    g.data3 = 0xFFFF;
+    g.data4[0] = 0xFF;
+    g.data4[1] = 0xFF;
+    g.data4[2] = 0xFF;
+    g.data4[3] = 0xFF;
+    g.data4[4] = 0xFF;
+    g.data4[5] = 0xFF;
+    g.data4[6] = 0xFF;
+    g.data4[7] = 0xFF;
+
+    n = UA_NODEID_GUID(65535,g);
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=65535;i=ffffffff-ffff-ffff-ffff-ffffffffffff");
+
+    UA_String_deleteMembers(&str);
+} END_TEST
+
+START_TEST(idToStringByte) {
+    UA_NodeId n;
+    UA_String str = UA_STRING_NULL;
+
+    n.namespaceIndex = 0;
+    n.identifierType = UA_NODEIDTYPE_BYTESTRING;
+    n.identifier.byteString.data = NULL;
+    n.identifier.byteString.length = 0;
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=0;i=");
+
+    UA_ByteString bs = UA_BYTESTRING_NULL;
+
+    bs.length = 1;
+    bs.data = (UA_Byte*)UA_malloc(bs.length);
+    bs.data[0] = 0x2C;
+    n.identifier.byteString = bs;
+    n.namespaceIndex = 123;
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=123;i=2c");
+    UA_free(bs.data);
+
+    bs.length = 5;
+    bs.data = (UA_Byte*)UA_malloc(bs.length);
+    bs.data[0] = 0x21;
+    bs.data[1] = 0x83;
+    bs.data[2] = 0xE0;
+    bs.data[3] = 0x54;
+    bs.data[4] = 0x78;
+    n.identifier.byteString = bs;
+    n.namespaceIndex = 599;
+    UA_NodeId_toString(&n, &str);
+    assertNodeIdString(&str, "ns=599;i=2183e05478");
+    UA_free(bs.data);
+
+    UA_String_deleteMembers(&str);
+} END_TEST
+
+
+
 static Suite* testSuite_Utils(void) {
     Suite *s = suite_create("Utils");
     TCase *tc_endpointUrl_split = tcase_create("EndpointUrl_split");
@@ -164,6 +294,15 @@ static Suite* testSuite_Utils(void) {
     tcase_add_test(tc_utils, readNumber);
     tcase_add_test(tc_utils, StatusCode_msg);
     suite_add_tcase(s,tc_utils);
+
+
+    TCase *tc1 = tcase_create("test nodeid string");
+    tcase_add_test(tc1, idToStringNumeric);
+    tcase_add_test(tc1, idToStringString);
+    tcase_add_test(tc1, idToStringGuid);
+    tcase_add_test(tc1, idToStringByte);
+    suite_add_tcase(s, tc1);
+
     return s;
 }