|
@@ -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;
|
|
|
-}
|