Browse Source

simplify binary encoding

Julius Pfrommer 10 years ago
parent
commit
c43506b271
3 changed files with 79 additions and 94 deletions
  1. 19 37
      src/ua_types.c
  2. 11 42
      src/ua_types_encoding_binary.c
  3. 49 15
      tools/generate_datatypes.py

+ 19 - 37
src/ua_types.c

@@ -771,12 +771,6 @@ void UA_init(void *p, const UA_DataType *dataType) {
         case UA_TYPES_EXPANDEDNODEID:
             UA_ExpandedNodeId_init((UA_ExpandedNodeId*)ptr);
             break;
-        case UA_TYPES_QUALIFIEDNAME:
-            UA_QualifiedName_init((UA_QualifiedName*)ptr);
-            break;
-        case UA_TYPES_LOCALIZEDTEXT:
-            UA_LocalizedText_init((UA_LocalizedText*)ptr);
-            break;
         case UA_TYPES_EXTENSIONOBJECT:
             UA_ExtensionObject_init((UA_ExtensionObject*)ptr);
             break;
@@ -789,12 +783,8 @@ void UA_init(void *p, const UA_DataType *dataType) {
         case UA_TYPES_DIAGNOSTICINFO:
             UA_DiagnosticInfo_init((UA_DiagnosticInfo*)ptr);
             break;
-        case UA_TYPES_STRING:
-        case UA_TYPES_BYTESTRING:
-        case UA_TYPES_XMLELEMENT:
-            UA_String_init((UA_String*)ptr);
-            break;
         default:
+            // QualifiedName, LocalizedText and strings are treated as structures, also
             UA_init((void*)ptr, &UA_TYPES[member->memberTypeIndex]);
         }
         ptr += UA_TYPES[member->memberTypeIndex].memSize;
@@ -890,12 +880,6 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
         case UA_TYPES_EXPANDEDNODEID:
             retval |= UA_ExpandedNodeId_copy((const UA_ExpandedNodeId*)ptrs, (UA_ExpandedNodeId*)ptrd);
             break;
-        case UA_TYPES_QUALIFIEDNAME:
-            retval |= UA_QualifiedName_copy((const UA_QualifiedName*)ptrs, (UA_QualifiedName*)ptrd);
-            break;
-        case UA_TYPES_LOCALIZEDTEXT:
-            retval |= UA_LocalizedText_copy((const UA_LocalizedText*)ptrs, (UA_LocalizedText*)ptrd);
-            break;
         case UA_TYPES_EXTENSIONOBJECT:
             retval |= UA_ExtensionObject_copy((const UA_ExtensionObject*)ptrs, (UA_ExtensionObject*)ptrd);
             break;
@@ -908,12 +892,8 @@ UA_StatusCode UA_copy(const void *src, void *dst, const UA_DataType *dataType) {
         case UA_TYPES_DIAGNOSTICINFO:
             retval |= UA_DiagnosticInfo_copy((const UA_DiagnosticInfo*)ptrs, (UA_DiagnosticInfo*)ptrd);
             break;
-        case UA_TYPES_STRING:
-        case UA_TYPES_BYTESTRING:
-        case UA_TYPES_XMLELEMENT:
-            retval |= UA_String_copy((const UA_String*)ptrs, (UA_String*)ptrd);
-            break;
         default:
+            // QualifiedName, LocalizedText and strings are treated as structures, also
             retval |= UA_copy((const void *)ptrs, (void*)ptrd, memberType);
         }
         ptrs += memberType->memSize;
@@ -954,23 +934,29 @@ void UA_deleteMembers(void *p, const UA_DataType *dataType) {
             ptr += memberType->memSize;
             continue;
         }
-        
+
         switch(member->memberTypeIndex) {
-            // the following types have a fixed size.
-            /* UA_BOOLEAN, UA_SBYTE, UA_BYTE, UA_INT16, UA_UINT16, UA_INT32, UA_UINT32, */
-            /* UA_STATUSCODE, UA_FLOAT, UA_INT64, UA_UINT64, UA_DOUBLE, UA_DATETIME, UA_GUID */
+        case UA_TYPES_BOOLEAN:
+        case UA_TYPES_SBYTE:
+        case UA_TYPES_BYTE:
+        case UA_TYPES_INT16:
+        case UA_TYPES_UINT16:
+        case UA_TYPES_INT32:
+        case UA_TYPES_UINT32:
+        case UA_TYPES_STATUSCODE:
+        case UA_TYPES_FLOAT:
+        case UA_TYPES_INT64:
+        case UA_TYPES_UINT64:
+        case UA_TYPES_DOUBLE:
+        case UA_TYPES_DATETIME:
+        case UA_TYPES_GUID:
+            break;
         case UA_TYPES_NODEID:
             UA_NodeId_deleteMembers((UA_NodeId*)ptr);
             break;
         case UA_TYPES_EXPANDEDNODEID:
             UA_ExpandedNodeId_deleteMembers((UA_ExpandedNodeId*)ptr);
             break;
-        case UA_TYPES_QUALIFIEDNAME:
-            UA_QualifiedName_deleteMembers((UA_QualifiedName*)ptr);
-            break;
-        case UA_TYPES_LOCALIZEDTEXT:
-            UA_LocalizedText_deleteMembers((UA_LocalizedText*)ptr);
-            break;
         case UA_TYPES_EXTENSIONOBJECT:
             UA_ExtensionObject_deleteMembers((UA_ExtensionObject*)ptr);
             break;
@@ -983,12 +969,8 @@ void UA_deleteMembers(void *p, const UA_DataType *dataType) {
         case UA_TYPES_DIAGNOSTICINFO:
             UA_DiagnosticInfo_deleteMembers((UA_DiagnosticInfo*)ptr);
             break;
-        case UA_TYPES_STRING:
-        case UA_TYPES_BYTESTRING:
-        case UA_TYPES_XMLELEMENT:
-            UA_String_deleteMembers((UA_String*)ptr);
-            break;
         default:
+            // QualifiedName, LocalizedText and strings are treated as structures, also
             UA_deleteMembers((void*)ptr, memberType);
         }
         ptr += memberType->memSize;

+ 11 - 42
src/ua_types_encoding_binary.c

@@ -960,9 +960,6 @@ size_t UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
         case UA_TYPES_EXPANDEDNODEID:
             size += UA_ExpandedNodeId_calcSizeBinary((const UA_ExpandedNodeId*)ptr);
             break;
-        case UA_TYPES_QUALIFIEDNAME:
-            size += UA_QualifiedName_calcSizeBinary((const UA_QualifiedName*)ptr);
-            break;
         case UA_TYPES_LOCALIZEDTEXT:
             size += UA_LocalizedText_calcSizeBinary((const UA_LocalizedText*)ptr);
             break;
@@ -978,12 +975,8 @@ size_t UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
         case UA_TYPES_DIAGNOSTICINFO:
             size += UA_DiagnosticInfo_calcSizeBinary((const UA_DiagnosticInfo*)ptr);
             break;
-        case UA_TYPES_STRING:
-        case UA_TYPES_BYTESTRING:
-        case UA_TYPES_XMLELEMENT:
-            size += UA_String_calcSizeBinary((const UA_String*)ptr);
-            break;
         default:
+            // UA_TYPES_QUALIFIEDNAME, UA_TYPES_STRING, UA_TYPES_BYTESTRING, UA_TYPES_XMLELEMENT:
             size += UA_calcSizeBinary((const void*)ptr, memberType);
         }
         ptr += memberType->memSize;
@@ -1026,26 +1019,20 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
             retval = UA_Byte_encodeBinary((const UA_Byte*)ptr, dst, offset);
             break;
         case UA_TYPES_INT16:
-            retval = UA_Int16_encodeBinary((const UA_Int16*)ptr, dst, offset);
-            break;
         case UA_TYPES_UINT16:
             retval = UA_UInt16_encodeBinary((const UA_UInt16*)ptr, dst, offset);
             break;
         case UA_TYPES_INT32:
         case UA_TYPES_UINT32:
-        case UA_TYPES_STATUSCODE:
-            retval = UA_Int32_encodeBinary((const UA_Int32*)ptr, dst, offset);
-            break;
         case UA_TYPES_FLOAT:
-            retval = UA_Float_encodeBinary((const UA_Float*)ptr, dst, offset);
+        case UA_TYPES_STATUSCODE:
+            retval = UA_UInt32_encodeBinary((const UA_UInt32*)ptr, dst, offset);
             break;
         case UA_TYPES_INT64:
         case UA_TYPES_UINT64:
-        case UA_TYPES_DATETIME:
-            retval = UA_Int64_encodeBinary((const UA_Int64*)ptr, dst, offset);
-            break;
         case UA_TYPES_DOUBLE:
-            retval = UA_Double_encodeBinary((const UA_Double*)ptr, dst, offset);
+        case UA_TYPES_DATETIME:
+            retval = UA_UInt64_encodeBinary((const UA_UInt64*)ptr, dst, offset);
             break;
         case UA_TYPES_GUID:
             retval = UA_Guid_encodeBinary((const UA_Guid*)ptr, dst, offset);
@@ -1056,9 +1043,6 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
         case UA_TYPES_EXPANDEDNODEID:
             retval = UA_ExpandedNodeId_encodeBinary((const UA_ExpandedNodeId*)ptr, dst, offset);
             break;
-        case UA_TYPES_QUALIFIEDNAME:
-            retval = UA_QualifiedName_encodeBinary((const UA_QualifiedName*)ptr, dst, offset);
-            break;
         case UA_TYPES_LOCALIZEDTEXT:
             retval = UA_LocalizedText_encodeBinary((const UA_LocalizedText*)ptr, dst, offset);
             break;
@@ -1074,12 +1058,8 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
         case UA_TYPES_DIAGNOSTICINFO:
             retval = UA_DiagnosticInfo_encodeBinary((const UA_DiagnosticInfo*)ptr, dst, offset);
             break;
-        case UA_TYPES_STRING:
-        case UA_TYPES_BYTESTRING:
-        case UA_TYPES_XMLELEMENT:
-            retval = UA_String_encodeBinary((const UA_String*)ptr, dst, offset);
-            break;
         default:
+            // UA_TYPES_QUALIFIEDNAME, UA_TYPES_STRING, UA_TYPES_BYTESTRING, UA_TYPES_XMLELEMENT:
             retval = UA_encodeBinary((const void*)ptr, memberType, dst, offset);
         }
         ptr += memberType->memSize;
@@ -1134,19 +1114,15 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *ds
             break;
         case UA_TYPES_INT32:
         case UA_TYPES_UINT32:
-        case UA_TYPES_STATUSCODE:
-            retval = UA_Int32_decodeBinary(src, offset, (UA_Int32*)ptr);
-            break;
         case UA_TYPES_FLOAT:
-            retval = UA_Float_decodeBinary(src, offset, (UA_Float*)ptr);
+        case UA_TYPES_STATUSCODE:
+            retval = UA_UInt32_decodeBinary(src, offset, (UA_UInt32*)ptr);
             break;
         case UA_TYPES_INT64:
         case UA_TYPES_UINT64:
-        case UA_TYPES_DATETIME:
-            retval = UA_Int64_decodeBinary(src, offset, (UA_Int64*)ptr);
-            break;
         case UA_TYPES_DOUBLE:
-            retval = UA_Double_decodeBinary(src, offset, (UA_Double*)ptr);
+        case UA_TYPES_DATETIME:
+            retval = UA_UInt64_decodeBinary(src, offset, (UA_UInt64*)ptr);
             break;
         case UA_TYPES_GUID:
             retval = UA_Guid_decodeBinary(src, offset, (UA_Guid*)ptr);
@@ -1157,9 +1133,6 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *ds
         case UA_TYPES_EXPANDEDNODEID:
             retval = UA_ExpandedNodeId_decodeBinary(src, offset, (UA_ExpandedNodeId*)ptr);
             break;
-        case UA_TYPES_QUALIFIEDNAME:
-            retval = UA_QualifiedName_decodeBinary(src, offset, (UA_QualifiedName*)ptr);
-            break;
         case UA_TYPES_LOCALIZEDTEXT:
             retval = UA_LocalizedText_decodeBinary(src, offset, (UA_LocalizedText*)ptr);
             break;
@@ -1175,12 +1148,8 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *ds
         case UA_TYPES_DIAGNOSTICINFO:
             retval = UA_DiagnosticInfo_decodeBinary(src, offset, (UA_DiagnosticInfo*)ptr);
             break;
-        case UA_TYPES_STRING:
-        case UA_TYPES_BYTESTRING:
-        case UA_TYPES_XMLELEMENT:
-            retval = UA_String_decodeBinary(src, offset, (UA_String*)ptr);
-            break;
         default:
+            // UA_TYPES_QUALIFIEDNAME, UA_TYPES_STRING, UA_TYPES_BYTESTRING, UA_TYPES_XMLELEMENT:
             retval = UA_decodeBinary(src, offset, (void*)ptr, memberType);
         }
         ptr += memberType->memSize;

+ 49 - 15
tools/generate_datatypes.py

@@ -39,20 +39,23 @@ minimal_types = ["InvalidType", "Node", "NodeClass", "ReferenceNode", "Applicati
                  "SecurityTokenRequestType", "MessageSecurityMode", "CloseSessionResponse", "CloseSessionRquest",
                  "ActivateSessionRequest", "ActivateSessionResponse", "SignatureData", "SignedSoftwareCertificate",
                  "CreateSessionResponse", "CreateSessionRequest", "EndpointDescription", "UserTokenPolicy", "UserTokenType",
-                 "GetEndpointsRequest", "GetEndpointsResponse", "PublishRequest", "PublishResponse", "SetPublishingModeResponse",
-                 "SubscriptionAcknowledgement", "NotificationMessage", "ExtensionObject", "Structure", "ReadRequest",
-                 "ReadResponse", "ReadValueId", "TimestampsToReturn", "WriteRequest", "WriteResponse", "WriteValue",
-                 "SetPublishingModeRequest", "CreateMonitoredItemsResponse", "MonitoredItemCreateResult", "CreateMonitoredItemsRequest",
-                 "MonitoredItemCreateRequest", "MonitoringMode", "MonitoringParameters", "TranslateBrowsePathsToNodeIdsRequest",
-                 "TranslateBrowsePathsToNodeIdsResponse", "BrowsePath", "BrowsePathResult", "RelativePath", "BrowsePathTarget",
-                 "RelativePathElement", "CreateSubscriptionRequest", "CreateSubscriptionResponse", "BrowseResponse",
-                 "BrowseResult", "ReferenceDescription", "BrowseRequest", "ViewDescription", "BrowseDescription",
-                 "BrowseDirection", "CloseSessionRequest", "AddNodesRequest", "AddNodesResponse", "AddNodesItem", "AddNodesResult",
-                 "DeleteNodesItem","AddReferencesRequest", "AddReferencesResponse", "AddReferencesItem","DeleteReferencesItem", "VariableNode",
-                 "MethodNode", "VariableTypeNode", "ViewNode", "ReferenceTypeNode", "BrowseResultMask", "ServerState", "ServerStatusDataType",
-                 "BuildInfo", "ObjectNode", "DataTypeNode", "ObjectTypeNode", "IdType", "VariableAttributes", "ObjectAttributes",
-                 "NodeAttributes","ReferenceTypeAttributes", "ViewAttributes", "ObjectTypeAttributes", "NodeAttributesMask","DeleteNodesItem",
-                 "DeleteNodesRequest", "DeleteNodesResponse", "DeleteReferencesItem", "DeleteReferencesRequest", "DeleteReferencesResponse"]
+                 "GetEndpointsRequest", "GetEndpointsResponse", "PublishRequest", "PublishResponse",
+                 "SetPublishingModeResponse", "SubscriptionAcknowledgement", "NotificationMessage", "ExtensionObject",
+                 "Structure", "ReadRequest", "ReadResponse", "ReadValueId", "TimestampsToReturn", "WriteRequest",
+                 "WriteResponse", "WriteValue", "SetPublishingModeRequest", "CreateMonitoredItemsResponse",
+                 "MonitoredItemCreateResult", "CreateMonitoredItemsRequest", "MonitoredItemCreateRequest",
+                 "MonitoringMode", "MonitoringParameters", "TranslateBrowsePathsToNodeIdsRequest",
+                 "TranslateBrowsePathsToNodeIdsResponse", "BrowsePath", "BrowsePathResult", "RelativePath",
+                 "BrowsePathTarget", "RelativePathElement", "CreateSubscriptionRequest", "CreateSubscriptionResponse",
+                 "BrowseResponse", "BrowseResult", "ReferenceDescription", "BrowseRequest", "ViewDescription",
+                 "BrowseDescription", "BrowseDirection", "CloseSessionRequest", "AddNodesRequest", "AddNodesResponse",
+                 "AddNodesItem", "AddNodesResult", "DeleteNodesItem","AddReferencesRequest", "AddReferencesResponse",
+                 "AddReferencesItem","DeleteReferencesItem", "VariableNode", "MethodNode", "VariableTypeNode",
+                 "ViewNode", "ReferenceTypeNode", "BrowseResultMask", "ServerState", "ServerStatusDataType", "BuildInfo",
+                 "ObjectNode", "DataTypeNode", "ObjectTypeNode", "IdType", "VariableAttributes", "ObjectAttributes",
+                 "NodeAttributes","ReferenceTypeAttributes", "ViewAttributes", "ObjectTypeAttributes",
+                 "NodeAttributesMask","DeleteNodesItem", "DeleteNodesRequest", "DeleteNodesResponse",
+                 "DeleteReferencesItem", "DeleteReferencesRequest", "DeleteReferencesResponse"]
 
 class TypeDescription(object):
     def __init__(self, name, nodeid, namespaceid):
@@ -102,7 +105,38 @@ class BuiltinType(object):
         if description == None:
             typeid = "{.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = 0}, "
         else:
-            typeid = "{.namespaceIndex = %s, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = %s}, " % (description.namespaceid, description.nodeid)
+            typeid = "{.namespaceIndex = %s, .identifierType = UA_NODEIDTYPE_NUMERIC, .identifier.numeric = %s}, " % \
+                     (description.namespaceid, description.nodeid)
+        if self.name in ["UA_String", "UA_ByteString", "UA_XmlElement"]:
+            return "{.typeId = " + typeid + \
+                ".memSize = sizeof(" + self.name + "), " + \
+                ".namespaceZero = UA_TRUE, .fixedSize = UA_FALSE, .zeroCopyable = UA_FALSE, " + \
+                ".membersSize = 1,\n\t.members = {{.memberTypeIndex = UA_TYPES_BYTE, .namespaceZero = UA_TRUE, " + \
+                ".padding = offsetof(UA_String, data) - sizeof(UA_Int32), .isArray = UA_TRUE }}, " + \
+                ".typeIndex = %s }" % (outname.upper() + "_" + self.name[3:].upper())
+
+        if self.name == "UA_QualifiedName":
+            return "{.typeId = " + typeid + \
+                ".memSize = sizeof(UA_QualifiedName), " + \
+                ".namespaceZero = UA_TRUE, .fixedSize = UA_FALSE, .zeroCopyable = UA_FALSE, " + \
+                ".membersSize = 2, .members = {" + \
+                "\n\t{.memberTypeIndex = UA_TYPES_UINT16, .namespaceZero = UA_TRUE, " + \
+                ".padding = 0, .isArray = UA_FALSE }," + \
+                "\n\t{.memberTypeIndex = UA_TYPES_STRING, .namespaceZero = UA_TRUE, " + \
+                ".padding = offsetof(UA_QualifiedName, name) - sizeof(UA_UInt16), .isArray = UA_FALSE }},\n" + \
+                ".typeIndex = UA_TYPES_QUALIFIEDNAME }"
+
+        if self.name == "UA_LocalizedText":
+            return "{.typeId = " + typeid + \
+                ".memSize = sizeof(UA_LocalizedText), " + \
+                ".namespaceZero = UA_TRUE, .fixedSize = UA_FALSE, .zeroCopyable = UA_FALSE, " + \
+                ".membersSize = 2, .members = {" + \
+                "\n\t{.memberTypeIndex = UA_TYPES_STRING, .namespaceZero = UA_TRUE, " + \
+                ".padding = 0, .isArray = UA_FALSE }," + \
+                "\n\t{.memberTypeIndex = UA_TYPES_STRING, .namespaceZero = UA_TRUE, " + \
+                ".padding = offsetof(UA_LocalizedText, text) - sizeof(UA_String), .isArray = UA_FALSE }},\n" + \
+                ".typeIndex = UA_TYPES_LOCALIZEDTEXT }"
+                
         return "{.typeId = " + typeid + \
             ".memSize = sizeof(" + self.name + "), " + \
             ".namespaceZero = UA_TRUE, " + \