Browse Source

make array encoding static, start using the restrict keyword

Julius Pfrommer 10 years ago
parent
commit
c0ba839217
2 changed files with 132 additions and 117 deletions
  1. 126 106
      src/ua_types_encoding_binary.c
  2. 6 11
      src/ua_types_encoding_binary.h

+ 126 - 106
src/ua_types_encoding_binary.c

@@ -3,6 +3,76 @@
 #include "ua_statuscodes.h"
 #include "ua_types_generated.h"
 
+/******************/
+/* Array Handling */
+/******************/
+
+static size_t UA_Array_calcSizeBinary(const void *p, UA_Int32 noElements, const UA_DataType *dataType) {
+    if(noElements <= 0)
+        return 4;
+    size_t size = 4; // the array size encoding
+    if(dataType->fixedSize) {
+        size += noElements * UA_calcSizeBinary(p, dataType);
+        return size;
+    }
+    uintptr_t ptr = (uintptr_t)p;
+    for(int i=0;i<noElements;i++) {
+        size += UA_calcSizeBinary((void*)ptr, dataType);
+        ptr += dataType->memSize;
+    }
+    return size;
+}
+
+static UA_StatusCode UA_Array_encodeBinary(const void *src, UA_Int32 noElements, const UA_DataType *dataType,
+                                           UA_ByteString *dst, size_t *restrict offset) {
+    if(noElements <= -1)
+        noElements = -1;
+    UA_Int32_encodeBinary(&noElements, dst, offset);
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
+    uintptr_t ptr = (uintptr_t)src;
+    for(int i=0;i<noElements && retval == UA_STATUSCODE_GOOD;i++) {
+        retval = UA_encodeBinary((const void*)ptr, dataType, dst, offset);
+        ptr += dataType->memSize;
+    }
+    return retval;
+}
+
+static UA_StatusCode UA_Array_decodeBinary(const UA_ByteString *src, size_t *restrict offset,
+                                           UA_Int32 noElements, void **dst, const UA_DataType *dataType) {
+    if(noElements <= 0) {
+        *dst = UA_NULL;
+        return UA_STATUSCODE_GOOD;
+    }
+
+    if((UA_Int32)dataType->memSize * noElements < 0 || dataType->memSize * noElements > MAX_ARRAY_SIZE )
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+
+    // filter out arrays that can obviously not be parsed
+    if(*offset + ((dataType->memSize * noElements)/32) > (UA_UInt32)src->length)
+        return UA_STATUSCODE_BADDECODINGERROR;
+
+    *dst = UA_malloc(dataType->memSize * noElements);
+    if(!*dst)
+        return UA_STATUSCODE_BADOUTOFMEMORY;
+
+    uintptr_t ptr = (uintptr_t)*dst;
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
+    UA_Int32 i;
+    for(i=0;i<noElements && retval == UA_STATUSCODE_GOOD;i++) {
+        retval = UA_decodeBinary(src, offset, (void*)ptr, dataType);
+        ptr += dataType->memSize;
+    }
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_Array_delete(*dst, dataType, i);
+        *dst = UA_NULL;
+    }
+    return retval;
+}
+
+/*****************/
+/* Builtin Types */
+/*****************/
+
 #define UA_TYPE_CALCSIZEBINARY_MEMSIZE(TYPE) \
     size_t TYPE##_calcSizeBinary(TYPE const *p) { return sizeof(TYPE); }
 
@@ -10,16 +80,16 @@
     size_t TYPE##_calcSizeBinary(TYPE const *p) {                       \
         return TYPE_AS##_calcSizeBinary((const TYPE_AS *)p);            \
     }                                                                   \
-    UA_StatusCode TYPE##_encodeBinary(TYPE const *src, UA_ByteString *dst, size_t *offset) { \
+    UA_StatusCode TYPE##_encodeBinary(TYPE const *src, UA_ByteString *dst, size_t *restrict offset) { \
         return TYPE_AS##_encodeBinary((const TYPE_AS *)src, dst, offset); \
     }                                                                   \
-    UA_StatusCode TYPE##_decodeBinary(UA_ByteString const *src, size_t *offset, TYPE *dst) { \
+    UA_StatusCode TYPE##_decodeBinary(UA_ByteString const *src, size_t *restrict offset, TYPE *dst) { \
         return TYPE_AS##_decodeBinary(src, offset, (TYPE_AS *)dst);     \
     }
 
 /* Boolean */
 UA_TYPE_CALCSIZEBINARY_MEMSIZE(UA_Boolean)
-UA_StatusCode UA_Boolean_encodeBinary(const UA_Boolean *src, UA_ByteString *dst, size_t *offset) {
+UA_StatusCode UA_Boolean_encodeBinary(const UA_Boolean *src, UA_ByteString *dst, size_t *restrict offset) {
     if((UA_Int32)(*offset + sizeof(UA_Boolean)) > dst->length)
         return UA_STATUSCODE_BADENCODINGERROR;
     dst->data[*offset] = (UA_Byte)*src;
@@ -27,7 +97,7 @@ UA_StatusCode UA_Boolean_encodeBinary(const UA_Boolean *src, UA_ByteString *dst,
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_Boolean_decodeBinary(UA_ByteString const *src, size_t *offset, UA_Boolean *dst) {
+UA_StatusCode UA_Boolean_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_Boolean *dst) {
     if((UA_Int32)(*offset + sizeof(UA_Boolean)) > src->length )
         return UA_STATUSCODE_BADDECODINGERROR;
     *dst = (src->data[*offset] > 0) ? UA_TRUE : UA_FALSE;
@@ -40,7 +110,7 @@ UA_TYPE_BINARY_ENCODING_AS(UA_SByte, UA_Byte)
 
 /* Byte */
 UA_TYPE_CALCSIZEBINARY_MEMSIZE(UA_Byte)
-UA_StatusCode UA_Byte_encodeBinary(const UA_Byte *src, UA_ByteString *dst, size_t *offset) {
+UA_StatusCode UA_Byte_encodeBinary(const UA_Byte *src, UA_ByteString *dst, size_t *restrict offset) {
     if((UA_Int32)(*offset + sizeof(UA_Byte)) > dst->length)
         return UA_STATUSCODE_BADENCODINGERROR;
     dst->data[*offset] = (UA_Byte)*src;
@@ -48,7 +118,7 @@ UA_StatusCode UA_Byte_encodeBinary(const UA_Byte *src, UA_ByteString *dst, size_
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_Byte_decodeBinary(UA_ByteString const *src, size_t *offset, UA_Byte *dst) {
+UA_StatusCode UA_Byte_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_Byte *dst) {
     if((UA_Int32)(*offset + sizeof(UA_Byte)) > src->length )
         return UA_STATUSCODE_BADDECODINGERROR;
     *dst = src->data[*offset];
@@ -61,7 +131,7 @@ UA_TYPE_BINARY_ENCODING_AS(UA_Int16, UA_UInt16)
 
 /* UInt16 */
 UA_TYPE_CALCSIZEBINARY_MEMSIZE(UA_UInt16)
-UA_StatusCode UA_UInt16_encodeBinary(UA_UInt16 const *src, UA_ByteString * dst, size_t *offset) {
+UA_StatusCode UA_UInt16_encodeBinary(UA_UInt16 const *src, UA_ByteString *dst, size_t *restrict offset) {
     if((UA_Int32)(*offset + sizeof(UA_UInt16)) > dst->length )
         return UA_STATUSCODE_BADENCODINGERROR;
     UA_UInt16 *dst_ptr = (UA_UInt16*)&dst->data[*offset];
@@ -74,7 +144,7 @@ UA_StatusCode UA_UInt16_encodeBinary(UA_UInt16 const *src, UA_ByteString * dst,
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_UInt16_decodeBinary(UA_ByteString const *src, size_t *offset, UA_UInt16 *dst) {
+UA_StatusCode UA_UInt16_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_UInt16 *dst) {
     if((UA_Int32)(*offset + sizeof(UA_UInt16)) > src->length)
         return UA_STATUSCODE_BADDECODINGERROR;
     UA_UInt16 value = *((UA_UInt16*)&src->data[*offset]);
@@ -91,7 +161,7 @@ UA_TYPE_BINARY_ENCODING_AS(UA_Int32, UA_UInt32)
 
 /* UInt32 */
 UA_TYPE_CALCSIZEBINARY_MEMSIZE(UA_UInt32)
-UA_StatusCode UA_UInt32_encodeBinary(UA_UInt32 const *src, UA_ByteString * dst, size_t *offset) {
+UA_StatusCode UA_UInt32_encodeBinary(UA_UInt32 const *src, UA_ByteString * dst, size_t *restrict offset) {
     if((UA_Int32)(*offset + sizeof(UA_UInt32)) > dst->length )
         return UA_STATUSCODE_BADENCODINGERROR;
     UA_UInt32 *dst_ptr = (UA_UInt32*)&dst->data[*offset];
@@ -104,7 +174,7 @@ UA_StatusCode UA_UInt32_encodeBinary(UA_UInt32 const *src, UA_ByteString * dst,
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_UInt32_decodeBinary(UA_ByteString const *src, size_t *offset, UA_UInt32 * dst) {
+UA_StatusCode UA_UInt32_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_UInt32 * dst) {
     if((UA_Int32)(*offset + sizeof(UA_UInt32)) > src->length)
         return UA_STATUSCODE_BADDECODINGERROR;
     UA_UInt32 value = *((UA_UInt32*)&src->data[*offset]);
@@ -121,7 +191,7 @@ UA_TYPE_BINARY_ENCODING_AS(UA_Int64, UA_UInt64)
 
 /* UInt64 */
 UA_TYPE_CALCSIZEBINARY_MEMSIZE(UA_UInt64)
-UA_StatusCode UA_UInt64_encodeBinary(UA_UInt64 const *src, UA_ByteString *dst, size_t *offset) {
+UA_StatusCode UA_UInt64_encodeBinary(UA_UInt64 const *src, UA_ByteString *dst, size_t *restrict offset) {
     if((UA_Int32)(*offset + sizeof(UA_UInt64)) > dst->length )
         return UA_STATUSCODE_BADENCODINGERROR;
     UA_UInt64 *dst_ptr = (UA_UInt64*)&dst->data[*offset];
@@ -134,7 +204,7 @@ UA_StatusCode UA_UInt64_encodeBinary(UA_UInt64 const *src, UA_ByteString *dst, s
     return UA_STATUSCODE_GOOD;
 }
 
-UA_StatusCode UA_UInt64_decodeBinary(UA_ByteString const *src, size_t *offset, UA_UInt64 * dst) {
+UA_StatusCode UA_UInt64_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_UInt64 * dst) {
     if((UA_Int32)(*offset + sizeof(UA_UInt64)) > src->length)
         return UA_STATUSCODE_BADDECODINGERROR;
     UA_UInt64 value = *((UA_UInt64*)&src->data[*offset]);
@@ -201,7 +271,7 @@ size_t UA_String_calcSizeBinary(UA_String const *string) {
         return sizeof(UA_Int32);
 }
 
-UA_StatusCode UA_String_encodeBinary(UA_String const *src, UA_ByteString *dst, size_t *offset) {
+UA_StatusCode UA_String_encodeBinary(UA_String const *src, UA_ByteString *dst, size_t *restrict offset) {
     if((UA_Int32)(*offset + UA_String_calcSizeBinary(src)) > dst->length)
         return UA_STATUSCODE_BADENCODINGERROR;
 
@@ -213,7 +283,7 @@ UA_StatusCode UA_String_encodeBinary(UA_String const *src, UA_ByteString *dst, s
     return retval;
 }
 
-UA_StatusCode UA_String_decodeBinary(UA_ByteString const *src, size_t *offset, UA_String *dst) {
+UA_StatusCode UA_String_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_String *dst) {
     UA_String_init(dst);
     UA_Int32 length;
     if(UA_Int32_decodeBinary(src, offset, &length))
@@ -246,7 +316,7 @@ size_t UA_Guid_calcSizeBinary(UA_Guid const *p) {
     return 16;
 }
 
-UA_StatusCode UA_Guid_encodeBinary(UA_Guid const *src, UA_ByteString * dst, size_t *offset) {
+UA_StatusCode UA_Guid_encodeBinary(UA_Guid const *src, UA_ByteString * dst, size_t *restrict offset) {
     UA_StatusCode retval = UA_UInt32_encodeBinary(&src->data1, dst, offset);
     retval |= UA_UInt16_encodeBinary(&src->data2, dst, offset);
     retval |= UA_UInt16_encodeBinary(&src->data3, dst, offset);
@@ -255,7 +325,7 @@ UA_StatusCode UA_Guid_encodeBinary(UA_Guid const *src, UA_ByteString * dst, size
     return retval;
 }
 
-UA_StatusCode UA_Guid_decodeBinary(UA_ByteString const *src, size_t *offset, UA_Guid * dst) {
+UA_StatusCode UA_Guid_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_Guid * dst) {
     // This could be done with a single memcpy (if the compiler does no fancy realigning of structs)
     UA_StatusCode retval = UA_UInt32_decodeBinary(src, offset, &dst->data1);
     retval |= UA_UInt16_decodeBinary(src, offset, &dst->data2);
@@ -306,7 +376,8 @@ size_t UA_NodeId_calcSizeBinary(UA_NodeId const *p) {
     return length;
 }
 
-static UA_StatusCode UA_NodeId_encodeBinary_nodeid_offset(UA_NodeId const *src, UA_ByteString * dst, size_t *offset, UA_Int32 nodeid_offset) {
+static UA_StatusCode UA_NodeId_encodeBinary_nodeid_offset(UA_NodeId const *src, UA_ByteString * dst,
+                                                          size_t *restrict offset, UA_Int32 nodeid_offset) {
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     // temporary variables for endian-save code
     UA_Byte srcByte;
@@ -358,11 +429,11 @@ static UA_StatusCode UA_NodeId_encodeBinary_nodeid_offset(UA_NodeId const *src,
     return retval;
 }
 
-UA_StatusCode UA_NodeId_encodeBinary(UA_NodeId const *src, UA_ByteString * dst, size_t *offset) {
+UA_StatusCode UA_NodeId_encodeBinary(UA_NodeId const *src, UA_ByteString * dst, size_t *restrict offset) {
 	return UA_NodeId_encodeBinary_nodeid_offset(src, dst, offset, 0);
 }
 
-UA_StatusCode UA_NodeId_decodeBinary(UA_ByteString const *src, size_t *offset, UA_NodeId *dst) {
+UA_StatusCode UA_NodeId_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_NodeId *dst) {
     // temporary variables to overcome decoder's non-endian-saveness for datatypes with different length
     UA_Byte   dstByte = 0;
     UA_UInt16 dstUInt16 = 0;
@@ -431,7 +502,8 @@ size_t UA_ExpandedNodeId_calcSizeBinary(UA_ExpandedNodeId const *p) {
 #define UA_EXPANDEDNODEID_NAMESPACEURI_FLAG 0x80
 #define UA_EXPANDEDNODEID_SERVERINDEX_FLAG 0x40
 
-UA_StatusCode UA_ExpandedNodeId_encodeBinary(UA_ExpandedNodeId const *src, UA_ByteString * dst, size_t *offset) {
+UA_StatusCode UA_ExpandedNodeId_encodeBinary(UA_ExpandedNodeId const *src, UA_ByteString *dst,
+                                             size_t *restrict offset) {
     UA_Byte flags = 0;
     UA_UInt32 start = *offset;
     UA_StatusCode retval = UA_NodeId_encodeBinary(&src->nodeId, dst, offset);
@@ -449,14 +521,15 @@ UA_StatusCode UA_ExpandedNodeId_encodeBinary(UA_ExpandedNodeId const *src, UA_By
     return retval;
 }
 
-UA_StatusCode UA_ExpandedNodeId_decodeBinary(UA_ByteString const *src, size_t *offset, UA_ExpandedNodeId *dst) {
+UA_StatusCode UA_ExpandedNodeId_decodeBinary(UA_ByteString const *src, size_t *restrict offset,
+                                             UA_ExpandedNodeId *dst) {
     UA_ExpandedNodeId_init(dst);
     // get encodingflags and leave a "clean" nodeidtype
     if((UA_Int32)*offset >= src->length)
         return UA_STATUSCODE_BADDECODINGERROR;
     UA_Byte encodingByte = src->data[*offset];
-    src->data[*offset] = encodingByte & ~(UA_EXPANDEDNODEID_NAMESPACEURI_FLAG | UA_EXPANDEDNODEID_SERVERINDEX_FLAG);
-
+    src->data[*offset] = encodingByte & ~(UA_EXPANDEDNODEID_NAMESPACEURI_FLAG |
+                                          UA_EXPANDEDNODEID_SERVERINDEX_FLAG);
     UA_StatusCode retval = UA_NodeId_decodeBinary(src, offset, &dst->nodeId);
     if(encodingByte & UA_EXPANDEDNODEID_NAMESPACEURI_FLAG) {
         dst->nodeId.namespaceIndex = 0;
@@ -480,7 +553,8 @@ size_t UA_QualifiedName_calcSizeBinary(UA_QualifiedName const *p) {
     return length;
 }
 
-UA_StatusCode UA_QualifiedName_decodeBinary(UA_ByteString const *src, size_t *offset, UA_QualifiedName *dst) {
+UA_StatusCode UA_QualifiedName_decodeBinary(UA_ByteString const *src, size_t *restrict offset,
+                                            UA_QualifiedName *dst) {
     UA_QualifiedName_init(dst);
     UA_StatusCode retval = UA_UInt16_decodeBinary(src, offset, &dst->namespaceIndex);
     retval |= UA_String_decodeBinary(src, offset, &dst->name);
@@ -489,7 +563,8 @@ UA_StatusCode UA_QualifiedName_decodeBinary(UA_ByteString const *src, size_t *of
     return retval;
 }
 
-UA_StatusCode UA_QualifiedName_encodeBinary(UA_QualifiedName const *src, UA_ByteString* dst, size_t *offset) {
+UA_StatusCode UA_QualifiedName_encodeBinary(UA_QualifiedName const *src, UA_ByteString* dst,
+                                            size_t *restrict offset) {
     UA_StatusCode retval = UA_UInt16_encodeBinary(&src->namespaceIndex, dst, offset);
     retval |= UA_String_encodeBinary(&src->name, dst, offset);
     return retval;
@@ -508,7 +583,8 @@ size_t UA_LocalizedText_calcSizeBinary(UA_LocalizedText const *p) {
     return length;
 }
 
-UA_StatusCode UA_LocalizedText_encodeBinary(UA_LocalizedText const *src, UA_ByteString * dst, size_t *offset) {
+UA_StatusCode UA_LocalizedText_encodeBinary(UA_LocalizedText const *src, UA_ByteString * dst,
+                                            size_t *restrict offset) {
     UA_Byte encodingMask = 0;
     if(src->locale.data != UA_NULL)
         encodingMask |= UA_LOCALIZEDTEXT_ENCODINGMASKTYPE_LOCALE;
@@ -522,7 +598,8 @@ UA_StatusCode UA_LocalizedText_encodeBinary(UA_LocalizedText const *src, UA_Byte
     return retval;
 }
 
-UA_StatusCode UA_LocalizedText_decodeBinary(UA_ByteString const *src, size_t *offset, UA_LocalizedText *dst) {
+UA_StatusCode UA_LocalizedText_decodeBinary(UA_ByteString const *src, size_t *restrict offset,
+                                            UA_LocalizedText *dst) {
     UA_LocalizedText_init(dst);
     UA_Byte encodingMask = 0;
     UA_StatusCode retval = UA_Byte_decodeBinary(src, offset, &encodingMask);
@@ -554,7 +631,8 @@ size_t UA_ExtensionObject_calcSizeBinary(UA_ExtensionObject const *p) {
     return length;
 }
 
-UA_StatusCode UA_ExtensionObject_encodeBinary(UA_ExtensionObject const *src, UA_ByteString * dst, size_t *offset) {
+UA_StatusCode UA_ExtensionObject_encodeBinary(UA_ExtensionObject const *src, UA_ByteString * dst,
+                                              size_t *restrict offset) {
     UA_StatusCode retval = UA_NodeId_encodeBinary(&src->typeId, dst, offset);
     retval |= UA_Byte_encodeBinary((const UA_Byte*)&src->encoding, dst, offset);
     switch(src->encoding) {
@@ -572,7 +650,8 @@ UA_StatusCode UA_ExtensionObject_encodeBinary(UA_ExtensionObject const *src, UA_
     return retval;
 }
 
-UA_StatusCode UA_ExtensionObject_decodeBinary(UA_ByteString const *src, size_t *offset, UA_ExtensionObject *dst) {
+UA_StatusCode UA_ExtensionObject_decodeBinary(UA_ByteString const *src, size_t *restrict offset,
+                                              UA_ExtensionObject *dst) {
     UA_ExtensionObject_init(dst);
     UA_Byte encoding = 0;
     UA_StatusCode retval = UA_NodeId_decodeBinary(src, offset, &dst->typeId);
@@ -617,7 +696,7 @@ size_t UA_DataValue_calcSizeBinary(UA_DataValue const *p) {
     return length;
 }
 
-UA_StatusCode UA_DataValue_encodeBinary(UA_DataValue const *src, UA_ByteString *dst, size_t *offset) {
+UA_StatusCode UA_DataValue_encodeBinary(UA_DataValue const *src, UA_ByteString *dst, size_t *restrict offset) {
     UA_StatusCode retval = UA_Byte_encodeBinary((const UA_Byte*)src, dst, offset);
     if(src->hasValue)
         retval |= UA_Variant_encodeBinary(&src->value, dst, offset);
@@ -635,7 +714,7 @@ UA_StatusCode UA_DataValue_encodeBinary(UA_DataValue const *src, UA_ByteString *
 }
 
 #define MAX_PICO_SECONDS 1000
-UA_StatusCode UA_DataValue_decodeBinary(UA_ByteString const *src, size_t *offset, UA_DataValue *dst) {
+UA_StatusCode UA_DataValue_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_DataValue *dst) {
     UA_DataValue_init(dst);
     UA_StatusCode retval = UA_Byte_decodeBinary(src, offset, (UA_Byte*)dst);
     if(retval != UA_STATUSCODE_GOOD)
@@ -702,7 +781,7 @@ size_t UA_Variant_calcSizeBinary(UA_Variant const *p) {
     return length;
 }
 
-UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst, size_t *offset) {
+UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst, size_t *restrict offset) {
     UA_Byte encodingByte = 0;
     UA_Boolean isArray = src->arrayLength != -1 || !src->data;  // a single element is not an array
     UA_Boolean hasDimensions = isArray && src->arrayDimensions != UA_NULL;
@@ -733,7 +812,8 @@ UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst,
         if(!isBuiltin) {
             /* The type is wrapped inside an extensionobject*/
             // todo: offest holds only for namespace 0
-            retval |= UA_NodeId_encodeBinary_nodeid_offset(&src->type->typeId, dst, offset, UA_ENCODINGOFFSET_BINARY);
+            retval |= UA_NodeId_encodeBinary_nodeid_offset(&src->type->typeId, dst, offset,
+                                                           UA_ENCODINGOFFSET_BINARY);
             UA_Byte eoEncoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
             retval |= UA_Byte_encodeBinary(&eoEncoding, dst, offset);
             UA_Int32 eoEncodingLength = UA_calcSizeBinary(src->data, src->type);
@@ -743,13 +823,14 @@ UA_StatusCode UA_Variant_encodeBinary(UA_Variant const *src, UA_ByteString *dst,
         ptr += memSize;
     }
     if(hasDimensions)
-        retval |= UA_Array_encodeBinary(src->arrayDimensions, src->arrayDimensionsSize, &UA_TYPES[UA_TYPES_INT32], dst, offset);
+        retval |= UA_Array_encodeBinary(src->arrayDimensions, src->arrayDimensionsSize,
+                                        &UA_TYPES[UA_TYPES_INT32], dst, offset);
     return retval;
 }
 
 /* The resulting variant always has the storagetype UA_VARIANT_DATA. Currently,
    we only support ns0 types (todo: attach typedescriptions to datatypenodes) */
-UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, size_t *offset, UA_Variant *dst) {
+UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, size_t *restrict offset, UA_Variant *dst) {
     UA_Variant_init(dst);
     UA_Byte encodingByte;
     UA_StatusCode retval = UA_Byte_decodeBinary(src, offset, &encodingByte);
@@ -770,7 +851,8 @@ UA_StatusCode UA_Variant_decodeBinary(UA_ByteString const *src, size_t *offset,
             if(retval != UA_STATUSCODE_GOOD)
                 return retval;
         }
-        retval |= UA_Array_decodeBinary(src, offset, (!isArray && arraySize==-1) ? 1: arraySize, &dst->data, dataType);
+        retval |= UA_Array_decodeBinary(src, offset, (!isArray && arraySize==-1) ? 1: arraySize,
+                                        &dst->data, dataType);
         if(retval != UA_STATUSCODE_GOOD)
             return retval;
         dst->arrayLength = arraySize; // for deleteMembers
@@ -841,7 +923,8 @@ size_t UA_DiagnosticInfo_calcSizeBinary(UA_DiagnosticInfo const *ptr) {
     return length;
 }
 
-UA_StatusCode UA_DiagnosticInfo_encodeBinary(const UA_DiagnosticInfo *src, UA_ByteString * dst, size_t *offset) {
+UA_StatusCode UA_DiagnosticInfo_encodeBinary(const UA_DiagnosticInfo *src, UA_ByteString * dst,
+                                             size_t *restrict offset) {
     UA_StatusCode retval = UA_Byte_encodeBinary((const UA_Byte *)src, dst, offset);
     if(src->hasSymbolicId)
         retval |= UA_Int32_encodeBinary(&src->symbolicId, dst, offset);
@@ -860,7 +943,8 @@ UA_StatusCode UA_DiagnosticInfo_encodeBinary(const UA_DiagnosticInfo *src, UA_By
     return retval;
 }
 
-UA_StatusCode UA_DiagnosticInfo_decodeBinary(UA_ByteString const *src, size_t *offset, UA_DiagnosticInfo *dst) {
+UA_StatusCode UA_DiagnosticInfo_decodeBinary(UA_ByteString const *src, size_t *restrict offset,
+                                             UA_DiagnosticInfo *dst) {
     UA_DiagnosticInfo_init(dst);
     UA_StatusCode retval = UA_Byte_decodeBinary(src, offset, (UA_Byte*)dst);
     if(!retval)
@@ -981,7 +1065,8 @@ size_t UA_calcSizeBinary(const void *p, const UA_DataType *dataType) {
     return size;
 }
 
-UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_ByteString *dst, size_t *offset) {
+UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_ByteString *dst,
+                              size_t *restrict offset) {
     uintptr_t ptr = (uintptr_t)src;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     UA_Byte membersSize = dataType->membersSize;
@@ -1064,7 +1149,8 @@ UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_B
     return retval;
 }
 
-UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, const UA_DataType *dataType) {
+UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *restrict offset, void *dst,
+                              const UA_DataType *dataType) {
     UA_init(dst, dataType);
     uintptr_t ptr = (uintptr_t)dst;
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
@@ -1155,69 +1241,3 @@ UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *ds
         UA_deleteMembers(dst, dataType);
     return retval;
 }
-
-/******************/
-/* Array Handling */
-/******************/
-
-size_t UA_Array_calcSizeBinary(const void *p, UA_Int32 noElements, const UA_DataType *dataType) {
-    if(noElements <= 0)
-        return 4;
-    size_t size = 4; // the array size encoding
-    if(dataType->fixedSize) {
-        size += noElements * UA_calcSizeBinary(p, dataType);
-        return size;
-    }
-    uintptr_t ptr = (uintptr_t)p;
-    for(int i=0;i<noElements;i++) {
-        size += UA_calcSizeBinary((void*)ptr, dataType);
-        ptr += dataType->memSize;
-    }
-    return size;
-}
-
-UA_StatusCode UA_Array_encodeBinary(const void *src, UA_Int32 noElements, const UA_DataType *dataType,
-                                    UA_ByteString *dst, size_t *offset) {
-    if(noElements <= -1)
-        noElements = -1;
-    UA_Int32_encodeBinary(&noElements, dst, offset);
-    UA_StatusCode retval = UA_STATUSCODE_GOOD;
-    uintptr_t ptr = (uintptr_t)src;
-    for(int i=0;i<noElements && retval == UA_STATUSCODE_GOOD;i++) {
-        retval = UA_encodeBinary((const void*)ptr, dataType, dst, offset);
-        ptr += dataType->memSize;
-    }
-    return retval;
-}
-
-UA_StatusCode UA_Array_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Int32 noElements,
-                                    void **dst, const UA_DataType *dataType) {
-    if(noElements <= 0) {
-        *dst = UA_NULL;
-        return UA_STATUSCODE_GOOD;
-    }
-
-    if((UA_Int32)dataType->memSize * noElements < 0 || dataType->memSize * noElements > MAX_ARRAY_SIZE )
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-
-    // filter out arrays that can obviously not be parsed
-    if(*offset + ((dataType->memSize * noElements)/32) > (UA_UInt32)src->length)
-        return UA_STATUSCODE_BADDECODINGERROR;
-
-    *dst = UA_malloc(dataType->memSize * noElements);
-    if(!*dst)
-        return UA_STATUSCODE_BADOUTOFMEMORY;
-
-    uintptr_t ptr = (uintptr_t)*dst;
-    UA_StatusCode retval = UA_STATUSCODE_GOOD;
-    UA_Int32 i;
-    for(i=0;i<noElements && retval == UA_STATUSCODE_GOOD;i++) {
-        retval = UA_decodeBinary(src, offset, (void*)ptr, dataType);
-        ptr += dataType->memSize;
-    }
-    if(retval != UA_STATUSCODE_GOOD) {
-        UA_Array_delete(*dst, dataType, i);
-        *dst = UA_NULL;
-    }
-    return retval;
-}

+ 6 - 11
src/ua_types_encoding_binary.h

@@ -32,8 +32,8 @@
 
 #define UA_TYPE_BINARY_ENCODING(TYPE)                                   \
     size_t TYPE##_calcSizeBinary(TYPE const *p);                        \
-    UA_StatusCode TYPE##_encodeBinary(TYPE const *src, UA_ByteString *dst, size_t *offset); \
-    UA_StatusCode TYPE##_decodeBinary(UA_ByteString const *src, size_t *offset, TYPE *dst);
+    UA_StatusCode TYPE##_encodeBinary(TYPE const *src, UA_ByteString *dst, size_t *restrict offset); \
+    UA_StatusCode TYPE##_decodeBinary(UA_ByteString const *src, size_t *restrict offset, TYPE *dst);
 
 UA_TYPE_BINARY_ENCODING(UA_Boolean)
 UA_TYPE_BINARY_ENCODING(UA_SByte)
@@ -62,15 +62,10 @@ UA_TYPE_BINARY_ENCODING(UA_Variant)
 UA_TYPE_BINARY_ENCODING(UA_DiagnosticInfo)
 
 size_t UA_calcSizeBinary(const void *p, const UA_DataType *dataType);
-UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_ByteString *dst, size_t *offset);
-UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *offset, void *dst, const UA_DataType *dataType);
-
-size_t UA_Array_calcSizeBinary(const void *p, UA_Int32 noElements, const UA_DataType *dataType);
-UA_StatusCode UA_Array_encodeBinary(const void *src, UA_Int32 noElements, const UA_DataType *dataType,
-                                    UA_ByteString *dst, size_t *offset);
-UA_StatusCode UA_Array_decodeBinary(const UA_ByteString *src, size_t *offset, UA_Int32 noElements,
-                                    void **dst, const UA_DataType *dataType);
-
+UA_StatusCode UA_encodeBinary(const void *src, const UA_DataType *dataType, UA_ByteString *dst,
+                              size_t *restrict offset);
+UA_StatusCode UA_decodeBinary(const UA_ByteString *src, size_t *restrict offset, void *dst,
+                              const UA_DataType *dataType);
 /// @} /* end of group */
 
 #endif /* UA_TYPES_ENCODING_BINARY_H_ */