Просмотр исходного кода

Further simplify the decoding, reduce indirections

Julius Pfrommer лет назад: 9
Родитель
Сommit
39eb69ee7f
3 измененных файлов с 61 добавлено и 51 удалено
  1. 14 14
      src/ua_types.c
  2. 46 36
      src/ua_types_encoding_binary.c
  3. 1 1
      tests/check_services_attributes.c

+ 14 - 14
src/ua_types.c

@@ -65,7 +65,7 @@ struct timezone {
 #endif
 #endif
 
 
 #ifdef _WIN32
 #ifdef _WIN32
-static const unsigned __int64 epoch = 116444736000000000;
+static const UA_UInt64 epoch = 116444736000000000;
 int gettimeofday(struct timeval *tp, struct timezone *tzp);
 int gettimeofday(struct timeval *tp, struct timezone *tzp);
 int gettimeofday(struct timeval *tp, struct timezone *tzp) {
 int gettimeofday(struct timeval *tp, struct timezone *tzp) {
     FILETIME       ft;
     FILETIME       ft;
@@ -177,7 +177,7 @@ UA_StatusCode UA_ByteString_allocBuffer(UA_ByteString *bs, size_t length) {
 }
 }
 
 
 /* NodeId */
 /* NodeId */
-static void NodeId_deleteMembers(UA_NodeId *p, const UA_DataType *dummy) {
+static void NodeId_deleteMembers(UA_NodeId *p, const UA_DataType *_) {
     switch(p->identifierType) {
     switch(p->identifierType) {
     case UA_NODEIDTYPE_STRING:
     case UA_NODEIDTYPE_STRING:
     case UA_NODEIDTYPE_BYTESTRING:
     case UA_NODEIDTYPE_BYTESTRING:
@@ -188,7 +188,7 @@ static void NodeId_deleteMembers(UA_NodeId *p, const UA_DataType *dummy) {
     }
     }
 }
 }
 
 
-static UA_StatusCode NodeId_copy(UA_NodeId const *src, UA_NodeId *dst, const UA_DataType *dummy) {
+static UA_StatusCode NodeId_copy(UA_NodeId const *src, UA_NodeId *dst, const UA_DataType *_) {
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     switch(src->identifierType) {
     switch(src->identifierType) {
     case UA_NODEIDTYPE_NUMERIC:
     case UA_NODEIDTYPE_NUMERIC:
@@ -233,7 +233,7 @@ UA_Boolean UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
 }
 }
 
 
 /* ExtensionObject */
 /* ExtensionObject */
-static void ExtensionObject_deleteMembers(UA_ExtensionObject *p, const UA_DataType *dummy) {
+static void ExtensionObject_deleteMembers(UA_ExtensionObject *p, const UA_DataType *_) {
     switch(p->encoding) {
     switch(p->encoding) {
     case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
     case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
     case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
     case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
@@ -257,8 +257,7 @@ static void ExtensionObject_deleteMembers(UA_ExtensionObject *p, const UA_DataTy
 }
 }
 
 
 static UA_StatusCode
 static UA_StatusCode
-ExtensionObject_copy(UA_ExtensionObject const *src, UA_ExtensionObject *dst,
-                     const UA_DataType *dummy) {
+ExtensionObject_copy(UA_ExtensionObject const *src, UA_ExtensionObject *dst, const UA_DataType *_) {
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     switch(src->encoding) {
     switch(src->encoding) {
     case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
     case UA_EXTENSIONOBJECT_ENCODED_NOBODY:
@@ -284,7 +283,7 @@ ExtensionObject_copy(UA_ExtensionObject const *src, UA_ExtensionObject *dst,
 }
 }
 
 
 /* Variant */
 /* Variant */
-static void Variant_deletemembers(UA_Variant *p, const UA_DataType *dummy) {
+static void Variant_deletemembers(UA_Variant *p, const UA_DataType *_) {
     if(p->storageType != UA_VARIANT_DATA)
     if(p->storageType != UA_VARIANT_DATA)
         return;
         return;
     if(p->data >= UA_EMPTY_ARRAY_SENTINEL) {
     if(p->data >= UA_EMPTY_ARRAY_SENTINEL) {
@@ -302,7 +301,7 @@ static void Variant_deletemembers(UA_Variant *p, const UA_DataType *dummy) {
 }
 }
 
 
 static UA_StatusCode
 static UA_StatusCode
-Variant_copy(UA_Variant const *src, UA_Variant *dst, const UA_DataType *dummy) {
+Variant_copy(UA_Variant const *src, UA_Variant *dst, const UA_DataType *_) {
     size_t length = src->arrayLength;
     size_t length = src->arrayLength;
     if(UA_Variant_isScalar(src))
     if(UA_Variant_isScalar(src))
         length = 1;
         length = 1;
@@ -323,7 +322,7 @@ Variant_copy(UA_Variant const *src, UA_Variant *dst, const UA_DataType *dummy) {
 }
 }
 
 
 /**
 /**
- * Tests if a range is compatible with a variant. If yes, the following values are set:
+ * Test if a range is compatible with a variant. If yes, the following values are set:
  * - total: how many elements are in the range
  * - total: how many elements are in the range
  * - block: how big is each contiguous block of elements in the variant that maps into the range
  * - block: how big is each contiguous block of elements in the variant that maps into the range
  * - stride: how many elements are between the blocks (beginning to beginning)
  * - stride: how many elements are between the blocks (beginning to beginning)
@@ -537,12 +536,12 @@ UA_Variant_setArrayCopy(UA_Variant *v, const void *array, size_t arraySize, cons
 }
 }
 
 
 /* DataValue */
 /* DataValue */
-static void DataValue_deleteMembers(UA_DataValue *p, const UA_DataType *dummy) {
+static void DataValue_deleteMembers(UA_DataValue *p, const UA_DataType *_) {
     Variant_deletemembers(&p->value, NULL);
     Variant_deletemembers(&p->value, NULL);
 }
 }
 
 
 static UA_StatusCode
 static UA_StatusCode
-DataValue_copy(UA_DataValue const *src, UA_DataValue *dst, const UA_DataType *dummy) {
+DataValue_copy(UA_DataValue const *src, UA_DataValue *dst, const UA_DataType *_) {
     memcpy(dst, src, sizeof(UA_DataValue));
     memcpy(dst, src, sizeof(UA_DataValue));
     UA_Variant_init(&dst->value);
     UA_Variant_init(&dst->value);
     UA_StatusCode retval = Variant_copy(&src->value, &dst->value, NULL);
     UA_StatusCode retval = Variant_copy(&src->value, &dst->value, NULL);
@@ -552,16 +551,17 @@ DataValue_copy(UA_DataValue const *src, UA_DataValue *dst, const UA_DataType *du
 }
 }
 
 
 /* DiagnosticInfo */
 /* DiagnosticInfo */
-static void DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p, const UA_DataType *dummy) {
+static void DiagnosticInfo_deleteMembers(UA_DiagnosticInfo *p, const UA_DataType *_) {
     UA_String_deleteMembers(&p->additionalInfo);
     UA_String_deleteMembers(&p->additionalInfo);
     if(p->hasInnerDiagnosticInfo && p->innerDiagnosticInfo) {
     if(p->hasInnerDiagnosticInfo && p->innerDiagnosticInfo) {
-        UA_DiagnosticInfo_delete(p->innerDiagnosticInfo);
+        DiagnosticInfo_deleteMembers(p->innerDiagnosticInfo, _);
+        UA_free(p->innerDiagnosticInfo);
         p->innerDiagnosticInfo = NULL;
         p->innerDiagnosticInfo = NULL;
     }
     }
 }
 }
 
 
 static UA_StatusCode
 static UA_StatusCode
-DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo *dst, const UA_DataType *dummy) {
+DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo *dst, const UA_DataType *_) {
     memcpy(dst, src, sizeof(UA_DiagnosticInfo));
     memcpy(dst, src, sizeof(UA_DiagnosticInfo));
     UA_String_init(&dst->additionalInfo);
     UA_String_init(&dst->additionalInfo);
     dst->innerDiagnosticInfo = NULL;
     dst->innerDiagnosticInfo = NULL;

+ 46 - 36
src/ua_types_encoding_binary.c

@@ -13,6 +13,10 @@ typedef UA_StatusCode (*UA_encodeBinarySignature)(const void *src, const UA_Data
 typedef UA_StatusCode (*UA_decodeBinarySignature) (const UA_ByteString *src, size_t *UA_RESTRICT offset,
 typedef UA_StatusCode (*UA_decodeBinarySignature) (const UA_ByteString *src, size_t *UA_RESTRICT offset,
                                                    void *dst, const UA_DataType*);
                                                    void *dst, const UA_DataType*);
 
 
+static UA_StatusCode
+UA_decodeBinaryNoInit(const UA_ByteString *src, size_t *UA_RESTRICT offset,
+                      void *dst, const UA_DataType *type);
+
 /*****************/
 /*****************/
 /* Integer Types */
 /* Integer Types */
 /*****************/
 /*****************/
@@ -405,7 +409,7 @@ Array_decodeBinary(const UA_ByteString *src, size_t *UA_RESTRICT offset,
 
 
     uintptr_t ptr = (uintptr_t)*dst;
     uintptr_t ptr = (uintptr_t)*dst;
     for(size_t i = 0; i < length; i++) {
     for(size_t i = 0; i < length; i++) {
-        UA_StatusCode retval = UA_decodeBinary(src, offset, (void*)ptr, type);
+        UA_StatusCode retval = UA_decodeBinaryNoInit(src, offset, (void*)ptr, type);
         if(retval != UA_STATUSCODE_GOOD) {
         if(retval != UA_STATUSCODE_GOOD) {
             UA_Array_delete(*dst, i, type);
             UA_Array_delete(*dst, i, type);
             *dst = NULL;
             *dst = NULL;
@@ -441,6 +445,11 @@ String_encodeBinary(UA_String const *src, const UA_DataType *_,
     return retval;
     return retval;
 }
 }
 
 
+static UA_INLINE UA_StatusCode
+ByteString_encodeBinary(UA_ByteString const *src, const UA_DataType *_,
+                        UA_ByteString *dst, size_t *UA_RESTRICT offset) {
+    return String_encodeBinary((const UA_String*)src, _, dst, offset); }
+
 static UA_StatusCode
 static UA_StatusCode
 String_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
 String_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
                     UA_String *dst, const UA_DataType *_) {
                     UA_String *dst, const UA_DataType *_) {
@@ -465,6 +474,11 @@ String_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
     return UA_STATUSCODE_GOOD;
     return UA_STATUSCODE_GOOD;
 }
 }
 
 
+static UA_INLINE UA_StatusCode
+ByteString_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
+                        UA_ByteString *dst, const UA_DataType *_) {
+    return String_decodeBinary(src, offset, (UA_ByteString*)dst, _); }
+
 /* Guid */
 /* Guid */
 static UA_StatusCode
 static UA_StatusCode
 Guid_encodeBinary(UA_Guid const *src, const UA_DataType *_,
 Guid_encodeBinary(UA_Guid const *src, const UA_DataType *_,
@@ -480,8 +494,6 @@ Guid_encodeBinary(UA_Guid const *src, const UA_DataType *_,
 static UA_StatusCode
 static UA_StatusCode
 Guid_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
 Guid_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
                   UA_Guid *dst, const UA_DataType *_) {
                   UA_Guid *dst, const UA_DataType *_) {
-    // This could be done with a single memcpy (if the compiler does no fancy
-    // realigning of structs)
     UA_StatusCode retval = UInt32_decodeBinary(src, offset, &dst->data1, NULL);
     UA_StatusCode retval = UInt32_decodeBinary(src, offset, &dst->data1, NULL);
     retval |= UInt16_decodeBinary(src, offset, &dst->data2, NULL);
     retval |= UInt16_decodeBinary(src, offset, &dst->data2, NULL);
     retval |= UInt16_decodeBinary(src, offset, &dst->data3, NULL);
     retval |= UInt16_decodeBinary(src, offset, &dst->data3, NULL);
@@ -531,7 +543,7 @@ NodeId_encodeBinary(UA_NodeId const *src, const UA_DataType *_,
         srcByte = UA_NODEIDTYPE_STRING;
         srcByte = UA_NODEIDTYPE_STRING;
         retval |= Byte_encodeBinary(&srcByte, NULL, dst, offset);
         retval |= Byte_encodeBinary(&srcByte, NULL, dst, offset);
         retval |= UInt16_encodeBinary(&src->namespaceIndex, NULL, dst, offset);
         retval |= UInt16_encodeBinary(&src->namespaceIndex, NULL, dst, offset);
-        retval |= UA_encodeBinary(&src->identifier.string, &UA_TYPES[UA_TYPES_STRING], dst, offset);
+        retval |= String_encodeBinary(&src->identifier.string, NULL, dst, offset);
         break;
         break;
     case UA_NODEIDTYPE_GUID:
     case UA_NODEIDTYPE_GUID:
         srcByte = UA_NODEIDTYPE_GUID;
         srcByte = UA_NODEIDTYPE_GUID;
@@ -543,7 +555,7 @@ NodeId_encodeBinary(UA_NodeId const *src, const UA_DataType *_,
         srcByte = UA_NODEIDTYPE_BYTESTRING;
         srcByte = UA_NODEIDTYPE_BYTESTRING;
         retval |= Byte_encodeBinary(&srcByte, NULL, dst, offset);
         retval |= Byte_encodeBinary(&srcByte, NULL, dst, offset);
         retval |= UInt16_encodeBinary(&src->namespaceIndex, NULL, dst, offset);
         retval |= UInt16_encodeBinary(&src->namespaceIndex, NULL, dst, offset);
-        retval |= UA_encodeBinary(&src->identifier.byteString, &UA_TYPES[UA_TYPES_BYTESTRING], dst, offset);
+        retval |= ByteString_encodeBinary(&src->identifier.byteString, NULL, dst, offset);
         break;
         break;
     default:
     default:
         return UA_STATUSCODE_BADINTERNALERROR;
         return UA_STATUSCODE_BADINTERNALERROR;
@@ -559,7 +571,6 @@ NodeId_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
     UA_StatusCode retval = Byte_decodeBinary(src, offset, &encodingByte, NULL);
     UA_StatusCode retval = Byte_decodeBinary(src, offset, &encodingByte, NULL);
     if(retval != UA_STATUSCODE_GOOD)
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
         return retval;
-
     switch (encodingByte) {
     switch (encodingByte) {
     case UA_NODEIDTYPE_NUMERIC_TWOBYTE:
     case UA_NODEIDTYPE_NUMERIC_TWOBYTE:
         dst->identifierType = UA_NODEIDTYPE_NUMERIC;
         dst->identifierType = UA_NODEIDTYPE_NUMERIC;
@@ -582,7 +593,7 @@ NodeId_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
     case UA_NODEIDTYPE_STRING:
     case UA_NODEIDTYPE_STRING:
         dst->identifierType = UA_NODEIDTYPE_STRING;
         dst->identifierType = UA_NODEIDTYPE_STRING;
         retval |= UInt16_decodeBinary(src, offset, &dst->namespaceIndex, NULL);
         retval |= UInt16_decodeBinary(src, offset, &dst->namespaceIndex, NULL);
-        retval |= UA_decodeBinary(src, offset, &dst->identifier.string, &UA_TYPES[UA_TYPES_STRING]);
+        retval |= String_decodeBinary(src, offset, &dst->identifier.string, NULL);
         break;
         break;
     case UA_NODEIDTYPE_GUID:
     case UA_NODEIDTYPE_GUID:
         dst->identifierType = UA_NODEIDTYPE_GUID;
         dst->identifierType = UA_NODEIDTYPE_GUID;
@@ -592,7 +603,7 @@ NodeId_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
     case UA_NODEIDTYPE_BYTESTRING:
     case UA_NODEIDTYPE_BYTESTRING:
         dst->identifierType = UA_NODEIDTYPE_BYTESTRING;
         dst->identifierType = UA_NODEIDTYPE_BYTESTRING;
         retval |= UInt16_decodeBinary(src, offset, &dst->namespaceIndex, NULL);
         retval |= UInt16_decodeBinary(src, offset, &dst->namespaceIndex, NULL);
-        retval |= UA_decodeBinary(src, offset, &dst->identifier.byteString, &UA_TYPES[UA_TYPES_BYTESTRING]);
+        retval |= ByteString_decodeBinary(src, offset, &dst->identifier.byteString, NULL);
         break;
         break;
     default:
     default:
         retval |= UA_STATUSCODE_BADINTERNALERROR; // the client sends an encodingByte we do not recognize
         retval |= UA_STATUSCODE_BADINTERNALERROR; // the client sends an encodingByte we do not recognize
@@ -613,7 +624,7 @@ ExpandedNodeId_encodeBinary(UA_ExpandedNodeId const *src, const UA_DataType *_,
     UA_UInt32 start = *offset;
     UA_UInt32 start = *offset;
     UA_StatusCode retval = NodeId_encodeBinary(&src->nodeId, NULL, dst, offset);
     UA_StatusCode retval = NodeId_encodeBinary(&src->nodeId, NULL, dst, offset);
     if(src->namespaceUri.length > 0) {
     if(src->namespaceUri.length > 0) {
-        retval |= UA_encodeBinary(&src->namespaceUri, &UA_TYPES[UA_TYPES_STRING], dst, offset);
+        retval |= String_encodeBinary(&src->namespaceUri, NULL, dst, offset);
         dst->data[start] |= UA_EXPANDEDNODEID_NAMESPACEURI_FLAG;
         dst->data[start] |= UA_EXPANDEDNODEID_NAMESPACEURI_FLAG;
     }
     }
     if(src->serverIndex > 0) {
     if(src->serverIndex > 0) {
@@ -634,7 +645,7 @@ ExpandedNodeId_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset
     UA_StatusCode retval = NodeId_decodeBinary(src, offset, &dst->nodeId, NULL);
     UA_StatusCode retval = NodeId_decodeBinary(src, offset, &dst->nodeId, NULL);
     if(encodingByte & UA_EXPANDEDNODEID_NAMESPACEURI_FLAG) {
     if(encodingByte & UA_EXPANDEDNODEID_NAMESPACEURI_FLAG) {
         dst->nodeId.namespaceIndex = 0;
         dst->nodeId.namespaceIndex = 0;
-        retval |= UA_decodeBinary(src, offset, &dst->namespaceUri, &UA_TYPES[UA_TYPES_STRING]);
+        retval |= String_decodeBinary(src, offset, &dst->namespaceUri, NULL);
     }
     }
     if(encodingByte & UA_EXPANDEDNODEID_SERVERINDEX_FLAG)
     if(encodingByte & UA_EXPANDEDNODEID_SERVERINDEX_FLAG)
         retval |= UInt32_decodeBinary(src, offset, &dst->serverIndex, NULL);
         retval |= UInt32_decodeBinary(src, offset, &dst->serverIndex, NULL);
@@ -657,9 +668,9 @@ LocalizedText_encodeBinary(UA_LocalizedText const *src, const UA_DataType *_,
         encodingMask |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
         encodingMask |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT;
     UA_StatusCode retval = Byte_encodeBinary(&encodingMask, NULL, dst, offset);
     UA_StatusCode retval = Byte_encodeBinary(&encodingMask, NULL, dst, offset);
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE)
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE)
-        retval |= UA_encodeBinary(&src->locale, &UA_TYPES[UA_TYPES_STRING], dst, offset);
+        retval |= String_encodeBinary(&src->locale, NULL, dst, offset);
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
-        retval |= UA_encodeBinary(&src->text, &UA_TYPES[UA_TYPES_STRING], dst, offset);
+        retval |= String_encodeBinary(&src->text, NULL, dst, offset);
     return retval;
     return retval;
 }
 }
 
 
@@ -669,9 +680,9 @@ LocalizedText_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
     UA_Byte encodingMask = 0;
     UA_Byte encodingMask = 0;
     UA_StatusCode retval = Byte_decodeBinary(src, offset, &encodingMask, NULL);
     UA_StatusCode retval = Byte_decodeBinary(src, offset, &encodingMask, NULL);
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE)
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE)
-        retval |= UA_decodeBinary(src, offset, &dst->locale, &UA_TYPES[UA_TYPES_STRING]);
+        retval |= String_decodeBinary(src, offset, &dst->locale, NULL);
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
     if(encodingMask & UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_TEXT)
-        retval |= UA_decodeBinary(src, offset, &dst->text, &UA_TYPES[UA_TYPES_STRING]);
+        retval |= String_decodeBinary(src, offset, &dst->text, NULL);
     if(retval != UA_STATUSCODE_GOOD)
     if(retval != UA_STATUSCODE_GOOD)
         UA_LocalizedText_deleteMembers(dst);
         UA_LocalizedText_deleteMembers(dst);
     return retval;
     return retval;
@@ -698,7 +709,7 @@ ExtensionObject_encodeBinary(UA_ExtensionObject const *src, const UA_DataType *_
         retval |= UA_encodeBinary(src->content.decoded.data, src->content.decoded.type, dst, offset);
         retval |= UA_encodeBinary(src->content.decoded.data, src->content.decoded.type, dst, offset);
         UA_Int32 length = *offset - old_offset - 4;
         UA_Int32 length = *offset - old_offset - 4;
         retval |= Int32_encodeBinary(&length, NULL, dst, &old_offset);
         retval |= Int32_encodeBinary(&length, NULL, dst, &old_offset);
-    } else  {
+    } else {
         retval = NodeId_encodeBinary(&src->content.encoded.typeId, NULL, dst, offset);
         retval = NodeId_encodeBinary(&src->content.encoded.typeId, NULL, dst, offset);
         retval |= Byte_encodeBinary(&encoding, NULL, dst, offset);
         retval |= Byte_encodeBinary(&encoding, NULL, dst, offset);
         switch (src->encoding) {
         switch (src->encoding) {
@@ -706,7 +717,7 @@ ExtensionObject_encodeBinary(UA_ExtensionObject const *src, const UA_DataType *_
             break;
             break;
         case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
         case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
         case UA_EXTENSIONOBJECT_ENCODED_XML:
         case UA_EXTENSIONOBJECT_ENCODED_XML:
-            retval |= UA_encodeBinary(&src->content.encoded.body, &UA_TYPES[UA_TYPES_BYTESTRING], dst, offset);
+            retval |= ByteString_encodeBinary(&src->content.encoded.body, NULL, dst, offset);
             break;
             break;
         default:
         default:
             return UA_STATUSCODE_BADINTERNALERROR;
             return UA_STATUSCODE_BADINTERNALERROR;
@@ -747,7 +758,7 @@ ExtensionObject_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offse
     } else if(encoding == UA_EXTENSIONOBJECT_ENCODED_XML) {
     } else if(encoding == UA_EXTENSIONOBJECT_ENCODED_XML) {
         dst->encoding = encoding;
         dst->encoding = encoding;
         dst->content.encoded.typeId = typeId;
         dst->content.encoded.typeId = typeId;
-        retval = UA_decodeBinary(src, offset, &dst->content.encoded.body, &UA_TYPES[UA_TYPES_BYTESTRING]);
+        retval = ByteString_decodeBinary(src, offset, &dst->content.encoded.body, NULL);
     } else {
     } else {
         /* try to decode the content */
         /* try to decode the content */
         size_t oldoffset = *offset;
         size_t oldoffset = *offset;
@@ -762,7 +773,7 @@ ExtensionObject_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offse
         if(type) {
         if(type) {
             dst->content.decoded.data = UA_new(type);
             dst->content.decoded.data = UA_new(type);
             if(dst->content.decoded.data) {
             if(dst->content.decoded.data) {
-                retval = UA_decodeBinary(src, offset, dst->content.decoded.data, type);
+                retval = UA_decodeBinaryNoInit(src, offset, dst->content.decoded.data, type);
                 dst->content.decoded.type = type;
                 dst->content.decoded.type = type;
                 dst->encoding = UA_EXTENSIONOBJECT_DECODED;
                 dst->encoding = UA_EXTENSIONOBJECT_DECODED;
             } else
             } else
@@ -772,7 +783,7 @@ ExtensionObject_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offse
                 retval = UA_STATUSCODE_BADDECODINGERROR;
                 retval = UA_STATUSCODE_BADDECODINGERROR;
         } else {
         } else {
             *offset = oldoffset;
             *offset = oldoffset;
-            retval = UA_decodeBinary(src, offset, &dst->content.encoded.body, &UA_TYPES[UA_TYPES_BYTESTRING]);
+            retval = ByteString_decodeBinary(src, offset, &dst->content.encoded.body, NULL);
             dst->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING;
             dst->encoding = UA_EXTENSIONOBJECT_ENCODED_BYTESTRING;
             dst->content.encoded.typeId = typeId;
             dst->content.encoded.typeId = typeId;
         }
         }
@@ -870,7 +881,6 @@ Variant_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
     UA_StatusCode retval = Byte_decodeBinary(src, offset, &encodingByte, NULL);
     UA_StatusCode retval = Byte_decodeBinary(src, offset, &encodingByte, NULL);
     if(retval != UA_STATUSCODE_GOOD)
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
         return retval;
-
     UA_Boolean isArray = encodingByte & UA_VARIANT_ENCODINGMASKTYPE_ARRAY;
     UA_Boolean isArray = encodingByte & UA_VARIANT_ENCODINGMASKTYPE_ARRAY;
     size_t typeIndex = (encodingByte & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK) - 1;
     size_t typeIndex = (encodingByte & UA_VARIANT_ENCODINGMASKTYPE_TYPEID_MASK) - 1;
     if(typeIndex > 24) /* must be builtin */
     if(typeIndex > 24) /* must be builtin */
@@ -912,12 +922,15 @@ Variant_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
         UA_NodeId_deleteMembers(&typeId);
         UA_NodeId_deleteMembers(&typeId);
 
 
         /* decode the type */
         /* decode the type */
-        dst->data = UA_malloc(dst->type->memSize);
-        retval = UA_decodeBinary(src, offset, dst->data, dst->type);
-        if(retval != UA_STATUSCODE_GOOD) {
-            UA_free(dst->data);
-            dst->data = NULL;
-        }
+        dst->data = UA_calloc(1,dst->type->memSize);
+        if(dst->data) {
+            retval = UA_decodeBinaryNoInit(src, offset, dst->data, dst->type);
+            if(retval != UA_STATUSCODE_GOOD) {
+                UA_free(dst->data);
+                dst->data = NULL;
+            }
+        } else
+            retval = UA_STATUSCODE_BADOUTOFMEMORY;
     }
     }
 
 
     /* array dimensions */
     /* array dimensions */
@@ -953,7 +966,7 @@ DataValue_encodeBinary(UA_DataValue const *src, const UA_DataType *_,
     return retval;
     return retval;
 }
 }
 
 
-#define MAX_PICO_SECONDS 1000
+#define MAX_PICO_SECONDS 999
 static UA_StatusCode
 static UA_StatusCode
 DataValue_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
 DataValue_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
                        UA_DataValue *dst, const UA_DataType *_) {
                        UA_DataValue *dst, const UA_DataType *_) {
@@ -961,7 +974,7 @@ DataValue_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
     if(retval != UA_STATUSCODE_GOOD)
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
         return retval;
     if(dst->hasValue)
     if(dst->hasValue)
-        retval |= UA_decodeBinary(src, offset, &dst->value, &UA_TYPES[UA_TYPES_VARIANT]);
+        retval |= Variant_decodeBinary(src, offset, &dst->value, NULL);
     if(dst->hasStatus)
     if(dst->hasStatus)
         retval |= StatusCode_decodeBinary(src, offset, &dst->status, NULL);
         retval |= StatusCode_decodeBinary(src, offset, &dst->status, NULL);
     if(dst->hasSourceTimestamp)
     if(dst->hasSourceTimestamp)
@@ -997,7 +1010,7 @@ DiagnosticInfo_encodeBinary(const UA_DiagnosticInfo *src, const UA_DataType *_,
     if(src->hasLocale)
     if(src->hasLocale)
         retval |= Int32_encodeBinary(&src->locale, NULL, dst, offset);
         retval |= Int32_encodeBinary(&src->locale, NULL, dst, offset);
     if(src->hasAdditionalInfo)
     if(src->hasAdditionalInfo)
-        retval |= UA_encodeBinary(&src->additionalInfo, &UA_TYPES[UA_TYPES_STRING], dst, offset);
+        retval |= String_encodeBinary(&src->additionalInfo, NULL, dst, offset);
     if(src->hasInnerStatusCode)
     if(src->hasInnerStatusCode)
         retval |= StatusCode_encodeBinary(&src->innerStatusCode, NULL, dst, offset);
         retval |= StatusCode_encodeBinary(&src->innerStatusCode, NULL, dst, offset);
     if(src->hasInnerDiagnosticInfo)
     if(src->hasInnerDiagnosticInfo)
@@ -1020,17 +1033,17 @@ DiagnosticInfo_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset
     if(dst->hasLocale)
     if(dst->hasLocale)
         retval |= Int32_decodeBinary(src, offset, &dst->locale, NULL);
         retval |= Int32_decodeBinary(src, offset, &dst->locale, NULL);
     if(dst->hasAdditionalInfo)
     if(dst->hasAdditionalInfo)
-        retval |= UA_decodeBinary(src, offset, &dst->additionalInfo, &UA_TYPES[UA_TYPES_STRING]);
+        retval |= String_decodeBinary(src, offset, &dst->additionalInfo, NULL);
     if(dst->hasInnerStatusCode)
     if(dst->hasInnerStatusCode)
         retval |= StatusCode_decodeBinary(src, offset, &dst->innerStatusCode, NULL);
         retval |= StatusCode_decodeBinary(src, offset, &dst->innerStatusCode, NULL);
     if(dst->hasInnerDiagnosticInfo) {
     if(dst->hasInnerDiagnosticInfo) {
         // innerDiagnosticInfo is a pointer to struct, therefore allocate
         // innerDiagnosticInfo is a pointer to struct, therefore allocate
-        dst->innerDiagnosticInfo = UA_malloc(sizeof(UA_DiagnosticInfo));
+        dst->innerDiagnosticInfo = UA_calloc(1, sizeof(UA_DiagnosticInfo));
         if(dst->innerDiagnosticInfo) {
         if(dst->innerDiagnosticInfo) {
-            if(DiagnosticInfo_decodeBinary(src, offset, dst->innerDiagnosticInfo, NULL) != UA_STATUSCODE_GOOD) {
+            retval |= DiagnosticInfo_decodeBinary(src, offset, dst->innerDiagnosticInfo, NULL);
+            if(retval != UA_STATUSCODE_GOOD) {
                 UA_free(dst->innerDiagnosticInfo);
                 UA_free(dst->innerDiagnosticInfo);
                 dst->innerDiagnosticInfo = NULL;
                 dst->innerDiagnosticInfo = NULL;
-                retval |= UA_STATUSCODE_BADINTERNALERROR;
             }
             }
         } else
         } else
             retval |= UA_STATUSCODE_BADOUTOFMEMORY;
             retval |= UA_STATUSCODE_BADOUTOFMEMORY;
@@ -1097,9 +1110,6 @@ UA_encodeBinary(const void *src, const UA_DataType *type, UA_ByteString *dst, si
     return retval;
     return retval;
 }
 }
 
 
-static UA_StatusCode
-UA_decodeBinaryNoInit(const UA_ByteString *src, size_t *UA_RESTRICT offset, void *dst, const UA_DataType *type);
-
 static const UA_decodeBinarySignature decodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
 static const UA_decodeBinarySignature decodeBinaryJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
     (UA_decodeBinarySignature)Boolean_decodeBinary, 
     (UA_decodeBinarySignature)Boolean_decodeBinary, 
     (UA_decodeBinarySignature)Byte_decodeBinary, // SByte
     (UA_decodeBinarySignature)Byte_decodeBinary, // SByte

+ 1 - 1
tests/check_services_attributes.c

@@ -40,7 +40,7 @@ static UA_Server* makeTestSequence(void) {
     UA_VariableAttributes_init(&vattr);
     UA_VariableAttributes_init(&vattr);
     UA_Int32 myIntegerArray[9] = {1,2,3,4,5,6,7,8,9};
     UA_Int32 myIntegerArray[9] = {1,2,3,4,5,6,7,8,9};
     UA_Variant_setArray(&vattr.value, &myIntegerArray, 9, &UA_TYPES[UA_TYPES_INT32]);
     UA_Variant_setArray(&vattr.value, &myIntegerArray, 9, &UA_TYPES[UA_TYPES_INT32]);
-    UA_Int32 myIntegerDimensions[2] = {3,3};
+    UA_UInt32 myIntegerDimensions[2] = {3,3};
     vattr.value.arrayDimensions = myIntegerDimensions;
     vattr.value.arrayDimensions = myIntegerDimensions;
     vattr.value.arrayDimensionsSize = 2;
     vattr.value.arrayDimensionsSize = 2;
     vattr.displayName = UA_LOCALIZEDTEXT("locale","myarray");
     vattr.displayName = UA_LOCALIZEDTEXT("locale","myarray");