Преглед на файлове

types: use specialized functions for expandednodeid handling

before, the type description contained the members.
but then we did not use the specialized encoding function when UA_encodeBinary was directly called on the UA_TYPES[UA_TYPES_EXPANDEDNODEID].
Julius Pfrommer преди 9 години
родител
ревизия
e92940f219
променени са 3 файла, в които са добавени 84 реда и са изтрити 41 реда
  1. 61 25
      src/ua_types.c
  2. 23 0
      tests/check_builtin.c
  3. 0 16
      tools/generate_datatypes.py

+ 61 - 25
src/ua_types.c

@@ -229,6 +229,22 @@ UA_Boolean UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
     return UA_FALSE;
     return UA_FALSE;
 }
 }
 
 
+/* ExpandedNodeId */
+static void ExpandedNodeId_deleteMembers(UA_ExpandedNodeId *p, const UA_DataType *_) {
+    NodeId_deleteMembers(&p->nodeId, _);
+    UA_String_deleteMembers(&p->namespaceUri);
+}
+
+static UA_StatusCode
+ExpandedNodeId_copy(UA_ExpandedNodeId const *src, UA_ExpandedNodeId *dst, const UA_DataType *_) {
+    UA_StatusCode retval = NodeId_copy(&src->nodeId, &dst->nodeId, NULL);
+    retval |= UA_String_copy(&src->namespaceUri, &dst->namespaceUri);
+    dst->serverIndex = src->serverIndex;
+    if(retval != UA_STATUSCODE_GOOD)
+        ExpandedNodeId_deleteMembers(dst, NULL);
+    return retval;
+}
+
 /* ExtensionObject */
 /* ExtensionObject */
 static void ExtensionObject_deleteMembers(UA_ExtensionObject *p, const UA_DataType *_) {
 static void ExtensionObject_deleteMembers(UA_ExtensionObject *p, const UA_DataType *_) {
     switch(p->encoding) {
     switch(p->encoding) {
@@ -603,44 +619,64 @@ void * UA_new(const UA_DataType *type) {
     return p;
     return p;
 }
 }
 
 
-static UA_StatusCode UA_copyFixedSize(const void *src, void *dst, const UA_DataType *type) {
+static UA_StatusCode copyByte(const void *src, void *dst, const UA_DataType *_) {
+    memcpy(dst, src, sizeof(UA_Byte));
+    return UA_STATUSCODE_GOOD;
+}
+
+static UA_StatusCode copy2Byte(const void *src, void *dst, const UA_DataType *_) {
+    memcpy(dst, src, sizeof(UA_UInt16));
+    return UA_STATUSCODE_GOOD;
+}
+
+static UA_StatusCode copy4Byte(const void *src, void *dst, const UA_DataType *_) {
+    memcpy(dst, src, sizeof(UA_UInt32));
+    return UA_STATUSCODE_GOOD;
+}
+
+static UA_StatusCode copy8Byte(const void *src, void *dst, const UA_DataType *_) {
+    memcpy(dst, src, sizeof(UA_UInt64));
+    return UA_STATUSCODE_GOOD;
+}
+
+static UA_StatusCode copyFixedSize(const void *src, void *dst, const UA_DataType *type) {
     memcpy(dst, src, type->memSize);
     memcpy(dst, src, type->memSize);
     return UA_STATUSCODE_GOOD;
     return UA_STATUSCODE_GOOD;
 }
 }
 
 
-static UA_StatusCode UA_copyNoInit(const void *src, void *dst, const UA_DataType *type);
+static UA_StatusCode copyNoInit(const void *src, void *dst, const UA_DataType *type);
 
 
 typedef UA_StatusCode (*UA_copySignature)(const void *src, void *dst, const UA_DataType *type);
 typedef UA_StatusCode (*UA_copySignature)(const void *src, void *dst, const UA_DataType *type);
 static const UA_copySignature copyJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
 static const UA_copySignature copyJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
-    (UA_copySignature)UA_copyFixedSize, // Boolean
-    (UA_copySignature)UA_copyFixedSize, // SByte
-    (UA_copySignature)UA_copyFixedSize, // Byte
-    (UA_copySignature)UA_copyFixedSize, // Int16
-    (UA_copySignature)UA_copyFixedSize, // UInt16 
-    (UA_copySignature)UA_copyFixedSize, // Int32 
-    (UA_copySignature)UA_copyFixedSize, // UInt32 
-    (UA_copySignature)UA_copyFixedSize, // Int64
-    (UA_copySignature)UA_copyFixedSize, // UInt64 
-    (UA_copySignature)UA_copyFixedSize, // Float 
-    (UA_copySignature)UA_copyFixedSize, // Double 
-    (UA_copySignature)UA_copyNoInit, // String
-    (UA_copySignature)UA_copyFixedSize, // DateTime
-    (UA_copySignature)UA_copyFixedSize, // Guid 
-    (UA_copySignature)UA_copyNoInit, // ByteString
-    (UA_copySignature)UA_copyNoInit, // XmlElement
+    (UA_copySignature)copyByte, // Boolean
+    (UA_copySignature)copyByte, // SByte
+    (UA_copySignature)copyByte, // Byte
+    (UA_copySignature)copy2Byte, // Int16
+    (UA_copySignature)copy2Byte, // UInt16 
+    (UA_copySignature)copy4Byte, // Int32 
+    (UA_copySignature)copy4Byte, // UInt32 
+    (UA_copySignature)copy8Byte, // Int64
+    (UA_copySignature)copy8Byte, // UInt64 
+    (UA_copySignature)copy4Byte, // Float 
+    (UA_copySignature)copy8Byte, // Double 
+    (UA_copySignature)copyNoInit, // String
+    (UA_copySignature)copy8Byte, // DateTime
+    (UA_copySignature)copyFixedSize, // Guid 
+    (UA_copySignature)copyNoInit, // ByteString
+    (UA_copySignature)copyNoInit, // XmlElement
     (UA_copySignature)NodeId_copy,
     (UA_copySignature)NodeId_copy,
-    (UA_copySignature)UA_copyNoInit, // ExpandedNodeId
-    (UA_copySignature)UA_copyFixedSize, // StatusCode
-    (UA_copySignature)UA_copyNoInit, // QualifiedName
+    (UA_copySignature)ExpandedNodeId_copy,
+    (UA_copySignature)copy4Byte, // StatusCode
+    (UA_copySignature)copyNoInit, // QualifiedName
     (UA_copySignature)LocalizedText_copy, // LocalizedText
     (UA_copySignature)LocalizedText_copy, // LocalizedText
     (UA_copySignature)ExtensionObject_copy,
     (UA_copySignature)ExtensionObject_copy,
     (UA_copySignature)DataValue_copy,
     (UA_copySignature)DataValue_copy,
     (UA_copySignature)Variant_copy,
     (UA_copySignature)Variant_copy,
     (UA_copySignature)DiagnosticInfo_copy,
     (UA_copySignature)DiagnosticInfo_copy,
-    (UA_copySignature)UA_copyNoInit,
+    (UA_copySignature)copyNoInit // all others
 };
 };
 
 
-static UA_StatusCode UA_copyNoInit(const void *src, void *dst, const UA_DataType *type) {
+static UA_StatusCode copyNoInit(const void *src, void *dst, const UA_DataType *type) {
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     uintptr_t ptrs = (uintptr_t)src;
     uintptr_t ptrs = (uintptr_t)src;
     uintptr_t ptrd = (uintptr_t)dst;
     uintptr_t ptrd = (uintptr_t)dst;
@@ -678,7 +714,7 @@ static UA_StatusCode UA_copyNoInit(const void *src, void *dst, const UA_DataType
 
 
 UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *type) {
 UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *type) {
     memset(dst, 0, type->memSize);
     memset(dst, 0, type->memSize);
-    return UA_copyNoInit(src, dst, type);
+    return copyNoInit(src, dst, type);
 }
 }
 
 
 typedef void (*UA_deleteMembersSignature)(void *p, const UA_DataType *type);
 typedef void (*UA_deleteMembersSignature)(void *p, const UA_DataType *type);
@@ -702,7 +738,7 @@ static const UA_deleteMembersSignature deleteMembersJumpTable[UA_BUILTIN_TYPES_C
     (UA_deleteMembersSignature)UA_deleteMembers, // ByteString
     (UA_deleteMembersSignature)UA_deleteMembers, // ByteString
     (UA_deleteMembersSignature)UA_deleteMembers, // XmlElement
     (UA_deleteMembersSignature)UA_deleteMembers, // XmlElement
     (UA_deleteMembersSignature)NodeId_deleteMembers,
     (UA_deleteMembersSignature)NodeId_deleteMembers,
-    (UA_deleteMembersSignature)UA_deleteMembers, // ExpandedNodeId
+    (UA_deleteMembersSignature)ExpandedNodeId_deleteMembers, // ExpandedNodeId
     (UA_deleteMembersSignature)nopDeleteMembers, // StatusCode
     (UA_deleteMembersSignature)nopDeleteMembers, // StatusCode
     (UA_deleteMembersSignature)UA_deleteMembers, // QualifiedName
     (UA_deleteMembersSignature)UA_deleteMembers, // QualifiedName
     (UA_deleteMembersSignature)LocalizedText_deleteMembers, // LocalizedText
     (UA_deleteMembersSignature)LocalizedText_deleteMembers, // LocalizedText

+ 23 - 0
tests/check_builtin.c

@@ -873,6 +873,28 @@ START_TEST(UA_String_encodeShallWorkOnExample) {
 }
 }
 END_TEST
 END_TEST
 
 
+START_TEST(UA_ExpandedNodeId_encodeShallWorkOnExample) {
+    // given
+    UA_ExpandedNodeId src = UA_EXPANDEDNODEID_NUMERIC(0, 15);
+    src.namespaceUri = UA_STRING("testUri");
+
+    UA_Byte data[] = { 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+                       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+                       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+                       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 };
+    UA_ByteString dst = { 32, data };
+    UA_Int32  retval = 0;
+    size_t pos = 0;
+
+    // when
+    retval = UA_ExpandedNodeId_encodeBinary(&src, &dst, &pos);
+    // then
+    ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
+    ck_assert_int_eq(pos, 13);
+    ck_assert_int_eq(dst.data[0], 0x80); // namespaceuri flag
+}
+END_TEST
+
 START_TEST(UA_DataValue_encodeShallWorkOnExampleWithoutVariant) {
 START_TEST(UA_DataValue_encodeShallWorkOnExampleWithoutVariant) {
     // given
     // given
     UA_DataValue src;
     UA_DataValue src;
@@ -1470,6 +1492,7 @@ static Suite *testSuite_builtin(void) {
     tcase_add_test(tc_encode, UA_Float_encodeShallWorkOnExample);
     tcase_add_test(tc_encode, UA_Float_encodeShallWorkOnExample);
     tcase_add_test(tc_encode, UA_Double_encodeShallWorkOnExample);
     tcase_add_test(tc_encode, UA_Double_encodeShallWorkOnExample);
     tcase_add_test(tc_encode, UA_String_encodeShallWorkOnExample);
     tcase_add_test(tc_encode, UA_String_encodeShallWorkOnExample);
+    tcase_add_test(tc_encode, UA_ExpandedNodeId_encodeShallWorkOnExample);
     tcase_add_test(tc_encode, UA_DataValue_encodeShallWorkOnExampleWithoutVariant);
     tcase_add_test(tc_encode, UA_DataValue_encodeShallWorkOnExampleWithoutVariant);
     tcase_add_test(tc_encode, UA_DataValue_encodeShallWorkOnExampleWithVariant);
     tcase_add_test(tc_encode, UA_DataValue_encodeShallWorkOnExampleWithVariant);
     tcase_add_test(tc_encode, UA_ExtensionObject_encodeDecodeShallWorkOnExtensionObject);
     tcase_add_test(tc_encode, UA_ExtensionObject_encodeDecodeShallWorkOnExtensionObject);

+ 0 - 16
tools/generate_datatypes.py

@@ -149,22 +149,6 @@ class BuiltinType(Type):
                 ".padding = 0, .isArray = UA_TRUE }}, " + \
                 ".padding = 0, .isArray = UA_TRUE }}, " + \
                 ".typeIndex = %s }" % (outname.upper() + "_" + self.name[3:].upper())
                 ".typeIndex = %s }" % (outname.upper() + "_" + self.name[3:].upper())
 
 
-        if self.name == "UA_ExpandedNodeId":
-            return (("{.typeName = \"" + self.name[3:] + "\", ") if typeintrospection else "{") + ".typeId = " + typeid + \
-                ".memSize = sizeof(UA_ExpandedNodeId), " + \
-                ".builtin = UA_TRUE, .fixedSize = UA_FALSE, .zeroCopyable = UA_FALSE, " + \
-                ".membersSize = 3, .members = {" + \
-                "\n\t{.memberTypeIndex = UA_TYPES_NODEID, .namespaceZero = UA_TRUE, " + \
-                (".memberName = \"nodeId\", " if typeintrospection else "") + \
-                ".padding = 0, .isArray = UA_FALSE }," + \
-                "\n\t{.memberTypeIndex = UA_TYPES_STRING, .namespaceZero = UA_TRUE, " + \
-                (".memberName = \"namespaceUri\", " if typeintrospection else "") + \
-                ".padding = offsetof(UA_ExpandedNodeId, namespaceUri) - sizeof(UA_NodeId), .isArray = UA_FALSE }," + \
-                "\n\t{.memberTypeIndex = UA_TYPES_UINT32, .namespaceZero = UA_TRUE, " + \
-                (".memberName = \"serverIndex\", " if typeintrospection else "") + \
-                ".padding = offsetof(UA_ExpandedNodeId, serverIndex) - offsetof(UA_ExpandedNodeId, namespaceUri) - sizeof(UA_String), .isArray = UA_FALSE }},\n" + \
-                ".typeIndex = UA_TYPES_EXPANDEDNODEID }"
-
         if self.name == "UA_QualifiedName":
         if self.name == "UA_QualifiedName":
             return (("{.typeName = \"" + self.name[3:] + "\", ") if typeintrospection else "{") + ".typeId = " + typeid + \
             return (("{.typeName = \"" + self.name[3:] + "\", ") if typeintrospection else "{") + ".typeId = " + typeid + \
                 ".memSize = sizeof(UA_QualifiedName), " + \
                 ".memSize = sizeof(UA_QualifiedName), " + \