Browse Source

Use specific encoding functions for all builtin types

This removes "hacks" for special cases that reduced the binary size a
bit. But this turned out to be problematic when adding JSON encoding.
Julius Pfrommer 6 years ago
parent
commit
a1d520317f
3 changed files with 53 additions and 21 deletions
  1. 33 12
      src/ua_types.c
  2. 19 3
      src/ua_types_encoding_binary.c
  3. 1 6
      tools/generate_datatypes.py

+ 33 - 12
src/ua_types.c

@@ -114,9 +114,30 @@ UA_String_equal(const UA_String *s1, const UA_String *s2) {
     return (is == 0) ? true : false;
 }
 
+static UA_StatusCode
+String_copy(UA_String const *src, UA_String *dst, const UA_DataType *_) {
+    UA_StatusCode retval = UA_Array_copy(src->data, src->length, (void**)&dst->data,
+                                         &UA_TYPES[UA_TYPES_BYTE]);
+    if(retval == UA_STATUSCODE_GOOD)
+        dst->length = src->length;
+    return retval;
+}
+
 static void
 String_deleteMembers(UA_String *s, const UA_DataType *_) {
-    UA_free((void*)((uintptr_t)s->data & ~(uintptr_t)UA_EMPTY_ARRAY_SENTINEL));
+    UA_Array_delete(s->data, s->length, &UA_TYPES[UA_TYPES_BYTE]);
+}
+
+/* QualifiedName */
+static UA_StatusCode
+QualifiedName_copy(const UA_QualifiedName *src, UA_QualifiedName *dst, const UA_DataType *_) {
+    dst->namespaceIndex = src->namespaceIndex;
+    return String_copy(&src->name, &dst->name, NULL);
+}
+
+static void
+QualifiedName_deleteMembers(UA_QualifiedName *p, const UA_DataType *_) {
+    String_deleteMembers(&p->name, NULL);
 }
 
 UA_Boolean
@@ -548,9 +569,9 @@ computeStrides(const UA_Variant *v, const UA_NumericRange range,
 /* Is the type string-like? */
 static bool
 isStringLike(const UA_DataType *type) {
-    if(type->membersSize == 1 && type->members[0].isArray &&
-       type->members[0].namespaceZero &&
-       type->members[0].memberTypeIndex == UA_TYPES_BYTE)
+    if(type == &UA_TYPES[UA_TYPES_STRING] ||
+       type == &UA_TYPES[UA_TYPES_BYTESTRING] ||
+       type == &UA_TYPES[UA_TYPES_XMLELEMENT])
         return true;
     return false;
 }
@@ -885,16 +906,16 @@ static const UA_copySignature copyJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
     (UA_copySignature)copy8Byte, // UInt64
     (UA_copySignature)copy4Byte, // Float
     (UA_copySignature)copy8Byte, // Double
-    (UA_copySignature)copy_noInit, // String
+    (UA_copySignature)String_copy,
     (UA_copySignature)copy8Byte, // DateTime
     (UA_copySignature)copyGuid, // Guid
-    (UA_copySignature)copy_noInit, // ByteString
-    (UA_copySignature)copy_noInit, // XmlElement
+    (UA_copySignature)String_copy, // ByteString
+    (UA_copySignature)String_copy, // XmlElement
     (UA_copySignature)NodeId_copy,
     (UA_copySignature)ExpandedNodeId_copy,
     (UA_copySignature)copy4Byte, // StatusCode
-    (UA_copySignature)copy_noInit, // QualifiedName
-    (UA_copySignature)LocalizedText_copy, // LocalizedText
+    (UA_copySignature)QualifiedName_copy,
+    (UA_copySignature)LocalizedText_copy,
     (UA_copySignature)ExtensionObject_copy,
     (UA_copySignature)DataValue_copy,
     (UA_copySignature)Variant_copy,
@@ -970,10 +991,10 @@ UA_deleteMembersSignature deleteMembersJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
     (UA_deleteMembersSignature)String_deleteMembers, // ByteString
     (UA_deleteMembersSignature)String_deleteMembers, // XmlElement
     (UA_deleteMembersSignature)NodeId_deleteMembers,
-    (UA_deleteMembersSignature)ExpandedNodeId_deleteMembers, // ExpandedNodeId
+    (UA_deleteMembersSignature)ExpandedNodeId_deleteMembers,
     (UA_deleteMembersSignature)nopDeleteMembers, // StatusCode
-    (UA_deleteMembersSignature)deleteMembers_noInit, // QualifiedName
-    (UA_deleteMembersSignature)LocalizedText_deleteMembers, // LocalizedText
+    (UA_deleteMembersSignature)QualifiedName_deleteMembers,
+    (UA_deleteMembersSignature)LocalizedText_deleteMembers,
     (UA_deleteMembersSignature)ExtensionObject_deleteMembers,
     (UA_deleteMembersSignature)DataValue_deleteMembers,
     (UA_deleteMembersSignature)Variant_deletemembers,

+ 19 - 3
src/ua_types_encoding_binary.c

@@ -753,6 +753,18 @@ DECODE_BINARY(ExpandedNodeId) {
     return ret;
 }
 
+/* QualifiedName */
+
+ENCODE_BINARY(QualifiedName) {
+    return ENCODE_DIRECT(&src->namespaceIndex, UInt16) |
+           ENCODE_DIRECT(&src->name, String);
+}
+
+DECODE_BINARY(QualifiedName) {
+    return DECODE_DIRECT(&dst->namespaceIndex, UInt16) |
+        DECODE_DIRECT(&dst->name, String);
+}
+
 /* LocalizedText */
 #define UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE 0x01
 #define UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT 0x02
@@ -1350,7 +1362,7 @@ const encodeBinarySignature encodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] =
     (encodeBinarySignature)NodeId_encodeBinary,
     (encodeBinarySignature)ExpandedNodeId_encodeBinary,
     (encodeBinarySignature)UInt32_encodeBinary, /* StatusCode */
-    (encodeBinarySignature)encodeBinaryInternal, /* QualifiedName */
+    (encodeBinarySignature)QualifiedName_encodeBinary,
     (encodeBinarySignature)LocalizedText_encodeBinary,
     (encodeBinarySignature)ExtensionObject_encodeBinary,
     (encodeBinarySignature)DataValue_encodeBinary,
@@ -1447,7 +1459,7 @@ const decodeBinarySignature decodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] =
     (decodeBinarySignature)NodeId_decodeBinary,
     (decodeBinarySignature)ExpandedNodeId_decodeBinary,
     (decodeBinarySignature)UInt32_decodeBinary, /* StatusCode */
-    (decodeBinarySignature)decodeBinaryInternal, /* QualifiedName */
+    (decodeBinarySignature)QualifiedName_decodeBinary,
     (decodeBinarySignature)LocalizedText_decodeBinary,
     (decodeBinarySignature)ExtensionObject_decodeBinary,
     (decodeBinarySignature)DataValue_decodeBinary,
@@ -1586,6 +1598,10 @@ CALCSIZE_BINARY(ExpandedNodeId) {
     return s;
 }
 
+CALCSIZE_BINARY(QualifiedName) {
+    return 2 + String_calcSizeBinary(&src->name, NULL);
+}
+
 CALCSIZE_BINARY(LocalizedText) {
     size_t s = 1; /* encoding byte */
     if(src->locale.data)
@@ -1715,7 +1731,7 @@ const calcSizeBinarySignature calcSizeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1
     (calcSizeBinarySignature)NodeId_calcSizeBinary,
     (calcSizeBinarySignature)ExpandedNodeId_calcSizeBinary,
     (calcSizeBinarySignature)calcSizeBinaryMemSize, /* StatusCode */
-    (calcSizeBinarySignature)UA_calcSizeBinary, /* QualifiedName */
+    (calcSizeBinarySignature)QualifiedName_calcSizeBinary,
     (calcSizeBinarySignature)LocalizedText_calcSizeBinary,
     (calcSizeBinarySignature)ExtensionObject_calcSizeBinary,
     (calcSizeBinarySignature)DataValue_calcSizeBinary,

+ 1 - 6
tools/generate_datatypes.py

@@ -175,12 +175,7 @@ class BuiltinType(Type):
         if name in builtin_overlayable:
             self.overlayable = builtin_overlayable[name]
         self.builtin = "true"
-        if self.name == "QualifiedName":
-            self.members = [StructMember("namespaceIndex", types["Int16"], False), StructMember("name", types["String"], False)]
-        elif self.name in ["String", "ByteString", "XmlElement"]:
-            self.members = [StructMember("", types["Byte"], True)]
-        else:
-            self.members = [StructMember("", self, False)]
+        self.members = [StructMember("", self, False)] # builtin types contain only one member: themselves (drops into the jumptable during processing)
 
 class EnumerationType(Type):
     def __init__(self, outname, xml, namespace):