|
@@ -14,17 +14,15 @@
|
|
* datatypes are autogenerated. */
|
|
* datatypes are autogenerated. */
|
|
|
|
|
|
/* Static definition of NULL type instances */
|
|
/* Static definition of NULL type instances */
|
|
-UA_EXPORT const UA_String UA_STRING_NULL = {.length = 0, .data = NULL };
|
|
|
|
-UA_EXPORT const UA_ByteString UA_BYTESTRING_NULL = {.length = 0, .data = NULL };
|
|
|
|
-UA_EXPORT const UA_Guid UA_GUID_NULL = {.data1 = 0, .data2 = 0, .data3 = 0,
|
|
|
|
- .data4 = {0,0,0,0,0,0,0,0}};
|
|
|
|
-UA_EXPORT const UA_NodeId UA_NODEID_NULL = {0, UA_NODEIDTYPE_NUMERIC, {0}};
|
|
|
|
-UA_EXPORT const UA_ExpandedNodeId UA_EXPANDEDNODEID_NULL = {
|
|
|
|
- .nodeId = { .namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC,
|
|
|
|
- .identifier.numeric = 0 },
|
|
|
|
- .namespaceUri = {.length = 0, .data = NULL}, .serverIndex = 0 };
|
|
|
|
-
|
|
|
|
-static void UA_deleteMembers_noInit(void *p, const UA_DataType *type);
|
|
|
|
|
|
+const UA_String UA_STRING_NULL = {.length = 0, .data = NULL };
|
|
|
|
+const UA_ByteString UA_BYTESTRING_NULL = {.length = 0, .data = NULL };
|
|
|
|
+const UA_Guid UA_GUID_NULL = {.data1 = 0, .data2 = 0, .data3 = 0,
|
|
|
|
+ .data4 = {0,0,0,0,0,0,0,0}};
|
|
|
|
+const UA_NodeId UA_NODEID_NULL = {0, UA_NODEIDTYPE_NUMERIC, {0}};
|
|
|
|
+const UA_ExpandedNodeId UA_EXPANDEDNODEID_NULL = {
|
|
|
|
+ .nodeId = {.namespaceIndex = 0, .identifierType = UA_NODEIDTYPE_NUMERIC,
|
|
|
|
+ .identifier.numeric = 0 },
|
|
|
|
+ .namespaceUri = {.length = 0, .data = NULL}, .serverIndex = 0 };
|
|
|
|
|
|
/***************************/
|
|
/***************************/
|
|
/* Random Number Generator */
|
|
/* Random Number Generator */
|
|
@@ -46,6 +44,9 @@ UA_UInt32_random(void) {
|
|
/* Builtin Types */
|
|
/* Builtin Types */
|
|
/*****************/
|
|
/*****************/
|
|
|
|
|
|
|
|
+static void deleteMembers_noInit(void *, const UA_DataType *);
|
|
|
|
+static UA_StatusCode copy_noInit(const void *, void *, const UA_DataType *);
|
|
|
|
+
|
|
UA_String
|
|
UA_String
|
|
UA_String_fromChars(char const src[]) {
|
|
UA_String_fromChars(char const src[]) {
|
|
UA_String str = UA_STRING_NULL;
|
|
UA_String str = UA_STRING_NULL;
|
|
@@ -86,7 +87,8 @@ UA_DateTime_toStruct(UA_DateTime t) {
|
|
dateTimeStruct.milliSec = (UA_UInt16)((t % 10000000) / 10000);
|
|
dateTimeStruct.milliSec = (UA_UInt16)((t % 10000000) / 10000);
|
|
|
|
|
|
/* Calculating the unix time with #include <time.h> */
|
|
/* Calculating the unix time with #include <time.h> */
|
|
- time_t secSinceUnixEpoch = (time_t)((t - UA_DATETIME_UNIX_EPOCH) / UA_SEC_TO_DATETIME);
|
|
|
|
|
|
+ time_t secSinceUnixEpoch =
|
|
|
|
+ (time_t)((t - UA_DATETIME_UNIX_EPOCH) / UA_SEC_TO_DATETIME);
|
|
struct tm ts;
|
|
struct tm ts;
|
|
memset(&ts, 0, sizeof(struct tm));
|
|
memset(&ts, 0, sizeof(struct tm));
|
|
__secs_to_tm(secSinceUnixEpoch, &ts);
|
|
__secs_to_tm(secSinceUnixEpoch, &ts);
|
|
@@ -166,10 +168,9 @@ UA_Guid_random(void) {
|
|
/* ByteString */
|
|
/* ByteString */
|
|
UA_StatusCode
|
|
UA_StatusCode
|
|
UA_ByteString_allocBuffer(UA_ByteString *bs, size_t length) {
|
|
UA_ByteString_allocBuffer(UA_ByteString *bs, size_t length) {
|
|
- if(length == 0) {
|
|
|
|
- UA_ByteString_init(bs);
|
|
|
|
|
|
+ UA_ByteString_init(bs);
|
|
|
|
+ if(length == 0)
|
|
return UA_STATUSCODE_GOOD;
|
|
return UA_STATUSCODE_GOOD;
|
|
- }
|
|
|
|
if(!(bs->data = UA_malloc(length)))
|
|
if(!(bs->data = UA_malloc(length)))
|
|
return UA_STATUSCODE_BADOUTOFMEMORY;
|
|
return UA_STATUSCODE_BADOUTOFMEMORY;
|
|
bs->length = length;
|
|
bs->length = length;
|
|
@@ -196,13 +197,15 @@ NodeId_copy(UA_NodeId const *src, UA_NodeId *dst, const UA_DataType *_) {
|
|
*dst = *src;
|
|
*dst = *src;
|
|
return UA_STATUSCODE_GOOD;
|
|
return UA_STATUSCODE_GOOD;
|
|
case UA_NODEIDTYPE_STRING:
|
|
case UA_NODEIDTYPE_STRING:
|
|
- retval |= UA_String_copy(&src->identifier.string, &dst->identifier.string);
|
|
|
|
|
|
+ retval |= UA_String_copy(&src->identifier.string,
|
|
|
|
+ &dst->identifier.string);
|
|
break;
|
|
break;
|
|
case UA_NODEIDTYPE_GUID:
|
|
case UA_NODEIDTYPE_GUID:
|
|
retval |= UA_Guid_copy(&src->identifier.guid, &dst->identifier.guid);
|
|
retval |= UA_Guid_copy(&src->identifier.guid, &dst->identifier.guid);
|
|
break;
|
|
break;
|
|
case UA_NODEIDTYPE_BYTESTRING:
|
|
case UA_NODEIDTYPE_BYTESTRING:
|
|
- retval |= UA_ByteString_copy(&src->identifier.byteString, &dst->identifier.byteString);
|
|
|
|
|
|
+ retval |= UA_ByteString_copy(&src->identifier.byteString,
|
|
|
|
+ &dst->identifier.byteString);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
return UA_STATUSCODE_BADINTERNALERROR;
|
|
return UA_STATUSCODE_BADINTERNALERROR;
|
|
@@ -239,7 +242,8 @@ UA_NodeId_isNull(const UA_NodeId *p) {
|
|
|
|
|
|
UA_Boolean
|
|
UA_Boolean
|
|
UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
|
|
UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
|
|
- if(n1->namespaceIndex != n2->namespaceIndex || n1->identifierType!=n2->identifierType)
|
|
|
|
|
|
+ if(n1->namespaceIndex != n2->namespaceIndex ||
|
|
|
|
+ n1->identifierType!=n2->identifierType)
|
|
return false;
|
|
return false;
|
|
switch(n1->identifierType) {
|
|
switch(n1->identifierType) {
|
|
case UA_NODEIDTYPE_NUMERIC:
|
|
case UA_NODEIDTYPE_NUMERIC:
|
|
@@ -248,11 +252,14 @@ UA_NodeId_equal(const UA_NodeId *n1, const UA_NodeId *n2) {
|
|
else
|
|
else
|
|
return false;
|
|
return false;
|
|
case UA_NODEIDTYPE_STRING:
|
|
case UA_NODEIDTYPE_STRING:
|
|
- return UA_String_equal(&n1->identifier.string, &n2->identifier.string);
|
|
|
|
|
|
+ return UA_String_equal(&n1->identifier.string,
|
|
|
|
+ &n2->identifier.string);
|
|
case UA_NODEIDTYPE_GUID:
|
|
case UA_NODEIDTYPE_GUID:
|
|
- return UA_Guid_equal(&n1->identifier.guid, &n2->identifier.guid);
|
|
|
|
|
|
+ return UA_Guid_equal(&n1->identifier.guid,
|
|
|
|
+ &n2->identifier.guid);
|
|
case UA_NODEIDTYPE_BYTESTRING:
|
|
case UA_NODEIDTYPE_BYTESTRING:
|
|
- return UA_ByteString_equal(&n1->identifier.byteString, &n2->identifier.byteString);
|
|
|
|
|
|
+ return UA_ByteString_equal(&n1->identifier.byteString,
|
|
|
|
+ &n2->identifier.byteString);
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
@@ -301,8 +308,10 @@ ExtensionObject_copy(UA_ExtensionObject const *src, UA_ExtensionObject *dst,
|
|
case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
|
|
case UA_EXTENSIONOBJECT_ENCODED_BYTESTRING:
|
|
case UA_EXTENSIONOBJECT_ENCODED_XML:
|
|
case UA_EXTENSIONOBJECT_ENCODED_XML:
|
|
dst->encoding = src->encoding;
|
|
dst->encoding = src->encoding;
|
|
- retval = NodeId_copy(&src->content.encoded.typeId, &dst->content.encoded.typeId, NULL);
|
|
|
|
- retval |= UA_ByteString_copy(&src->content.encoded.body, &dst->content.encoded.body);
|
|
|
|
|
|
+ retval = NodeId_copy(&src->content.encoded.typeId,
|
|
|
|
+ &dst->content.encoded.typeId, NULL);
|
|
|
|
+ retval |= UA_ByteString_copy(&src->content.encoded.body,
|
|
|
|
+ &dst->content.encoded.body);
|
|
break;
|
|
break;
|
|
case UA_EXTENSIONOBJECT_DECODED:
|
|
case UA_EXTENSIONOBJECT_DECODED:
|
|
case UA_EXTENSIONOBJECT_DECODED_NODELETE:
|
|
case UA_EXTENSIONOBJECT_DECODED_NODELETE:
|
|
@@ -338,7 +347,8 @@ 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;
|
|
- UA_StatusCode retval = UA_Array_copy(src->data, length, &dst->data, src->type);
|
|
|
|
|
|
+ UA_StatusCode retval = UA_Array_copy(src->data, length,
|
|
|
|
+ &dst->data, src->type);
|
|
if(retval != UA_STATUSCODE_GOOD)
|
|
if(retval != UA_STATUSCODE_GOOD)
|
|
return retval;
|
|
return retval;
|
|
dst->arrayLength = src->arrayLength;
|
|
dst->arrayLength = src->arrayLength;
|
|
@@ -399,26 +409,29 @@ UA_Variant_setArrayCopy(UA_Variant *v, const void *array,
|
|
return UA_STATUSCODE_GOOD;
|
|
return UA_STATUSCODE_GOOD;
|
|
}
|
|
}
|
|
|
|
|
|
-/* Range-wise access to Variants */
|
|
|
|
-
|
|
|
|
-/* Test 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)
|
|
* - first: where does the first block begin */
|
|
* - first: where does the first block begin */
|
|
static UA_StatusCode
|
|
static UA_StatusCode
|
|
computeStrides(const UA_Variant *v, const UA_NumericRange range,
|
|
computeStrides(const UA_Variant *v, const UA_NumericRange range,
|
|
size_t *total, size_t *block, size_t *stride, size_t *first) {
|
|
size_t *total, size_t *block, size_t *stride, size_t *first) {
|
|
- /* Test the integrity of the source variant dimensions */
|
|
|
|
- size_t dims_count = 1;
|
|
|
|
- UA_UInt32 elements = 1;
|
|
|
|
|
|
+ /* Test for max array size */
|
|
#if(MAX_SIZE > 0xffffffff) /* 64bit only */
|
|
#if(MAX_SIZE > 0xffffffff) /* 64bit only */
|
|
if(v->arrayLength > UA_UINT32_MAX)
|
|
if(v->arrayLength > UA_UINT32_MAX)
|
|
return UA_STATUSCODE_BADINTERNALERROR;
|
|
return UA_STATUSCODE_BADINTERNALERROR;
|
|
#endif
|
|
#endif
|
|
|
|
+
|
|
|
|
+ /* Test the integrity of the source variant dimensions, make dimensions
|
|
|
|
+ vector of one dimension if none defined */
|
|
UA_UInt32 arrayLength = (UA_UInt32)v->arrayLength;
|
|
UA_UInt32 arrayLength = (UA_UInt32)v->arrayLength;
|
|
const UA_UInt32 *dims = &arrayLength;
|
|
const UA_UInt32 *dims = &arrayLength;
|
|
|
|
+ size_t dims_count = 1;
|
|
if(v->arrayDimensionsSize > 0) {
|
|
if(v->arrayDimensionsSize > 0) {
|
|
|
|
+ size_t elements = 1;
|
|
dims_count = v->arrayDimensionsSize;
|
|
dims_count = v->arrayDimensionsSize;
|
|
dims = (UA_UInt32*)v->arrayDimensions;
|
|
dims = (UA_UInt32*)v->arrayDimensions;
|
|
for(size_t i = 0; i < dims_count; i++)
|
|
for(size_t i = 0; i < dims_count; i++)
|
|
@@ -438,26 +451,26 @@ computeStrides(const UA_Variant *v, const UA_NumericRange range,
|
|
return UA_STATUSCODE_BADINDEXRANGENODATA;
|
|
return UA_STATUSCODE_BADINDEXRANGENODATA;
|
|
count *= (range.dimensions[i].max - range.dimensions[i].min) + 1;
|
|
count *= (range.dimensions[i].max - range.dimensions[i].min) + 1;
|
|
}
|
|
}
|
|
|
|
+ *total = count;
|
|
|
|
|
|
/* Compute the stride length and the position of the first element */
|
|
/* Compute the stride length and the position of the first element */
|
|
- size_t b = 1, s = elements, f = 0;
|
|
|
|
|
|
+ *block = count; /* Assume the range describes the entire array. */
|
|
|
|
+ *stride = v->arrayLength; /* So it can be copied as a contiguous block. */
|
|
|
|
+ *first = 0;
|
|
size_t running_dimssize = 1;
|
|
size_t running_dimssize = 1;
|
|
UA_Boolean found_contiguous = false;
|
|
UA_Boolean found_contiguous = false;
|
|
- for(size_t k = dims_count - 1; ; k--) {
|
|
|
|
- if(!found_contiguous && (range.dimensions[k].min != 0 || range.dimensions[k].max + 1 != dims[k])) {
|
|
|
|
|
|
+ for(size_t k = dims_count; k > 0;) {
|
|
|
|
+ k--;
|
|
|
|
+ size_t dimrange = 1 + range.dimensions[k].max - range.dimensions[k].min;
|
|
|
|
+ if(!found_contiguous && dimrange != dims[k]) {
|
|
|
|
+ /* Found the maximum block that can be copied contiguously */
|
|
found_contiguous = true;
|
|
found_contiguous = true;
|
|
- b = (range.dimensions[k].max - range.dimensions[k].min + 1) * running_dimssize;
|
|
|
|
- s = dims[k] * running_dimssize;
|
|
|
|
|
|
+ *block = running_dimssize * dimrange;
|
|
|
|
+ *stride = running_dimssize * dims[k];
|
|
}
|
|
}
|
|
- f += running_dimssize * range.dimensions[k].min;
|
|
|
|
|
|
+ *first += running_dimssize * range.dimensions[k].min;
|
|
running_dimssize *= dims[k];
|
|
running_dimssize *= dims[k];
|
|
- if(k == 0)
|
|
|
|
- break;
|
|
|
|
}
|
|
}
|
|
- *total = count;
|
|
|
|
- *block = b;
|
|
|
|
- *stride = s;
|
|
|
|
- *first = f;
|
|
|
|
return UA_STATUSCODE_GOOD;
|
|
return UA_STATUSCODE_GOOD;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -526,7 +539,8 @@ UA_Variant_copyRange(const UA_Variant *orig_src, UA_Variant *dst,
|
|
|
|
|
|
/* Compute the strides */
|
|
/* Compute the strides */
|
|
size_t count, block, stride, first;
|
|
size_t count, block, stride, first;
|
|
- UA_StatusCode retval = computeStrides(src, thisrange, &count, &block, &stride, &first);
|
|
|
|
|
|
+ UA_StatusCode retval = computeStrides(src, thisrange, &count,
|
|
|
|
+ &block, &stride, &first);
|
|
if(retval != UA_STATUSCODE_GOOD)
|
|
if(retval != UA_STATUSCODE_GOOD)
|
|
return retval;
|
|
return retval;
|
|
|
|
|
|
@@ -551,8 +565,9 @@ UA_Variant_copyRange(const UA_Variant *orig_src, UA_Variant *dst,
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
for(size_t i = 0; i < block_count; i++) {
|
|
for(size_t i = 0; i < block_count; i++) {
|
|
- for(size_t j = 0; j < block && retval == UA_STATUSCODE_GOOD; j++) {
|
|
|
|
- retval = UA_copy((const void*)nextsrc, (void*)nextdst, src->type);
|
|
|
|
|
|
+ for(size_t j = 0; j < block; j++) {
|
|
|
|
+ retval = UA_copy((const void*)nextsrc,
|
|
|
|
+ (void*)nextdst, src->type);
|
|
nextdst += elem_size;
|
|
nextdst += elem_size;
|
|
nextsrc += elem_size;
|
|
nextsrc += elem_size;
|
|
}
|
|
}
|
|
@@ -569,15 +584,17 @@ UA_Variant_copyRange(const UA_Variant *orig_src, UA_Variant *dst,
|
|
retval = UA_STATUSCODE_BADINDEXRANGENODATA;
|
|
retval = UA_STATUSCODE_BADINDEXRANGENODATA;
|
|
}
|
|
}
|
|
|
|
|
|
- /* copy the content */
|
|
|
|
|
|
+ /* Copy the content */
|
|
for(size_t i = 0; i < block_count; i++) {
|
|
for(size_t i = 0; i < block_count; i++) {
|
|
for(size_t j = 0; j < block && retval == UA_STATUSCODE_GOOD; j++) {
|
|
for(size_t j = 0; j < block && retval == UA_STATUSCODE_GOOD; j++) {
|
|
if(stringLike)
|
|
if(stringLike)
|
|
retval = copySubString((const UA_String*)nextsrc,
|
|
retval = copySubString((const UA_String*)nextsrc,
|
|
- (UA_String*)nextdst, nextrange.dimensions);
|
|
|
|
|
|
+ (UA_String*)nextdst,
|
|
|
|
+ nextrange.dimensions);
|
|
else
|
|
else
|
|
retval = UA_Variant_copyRange((const UA_Variant*)nextsrc,
|
|
retval = UA_Variant_copyRange((const UA_Variant*)nextsrc,
|
|
- (UA_Variant*)nextdst, nextrange);
|
|
|
|
|
|
+ (UA_Variant*)nextdst,
|
|
|
|
+ nextrange);
|
|
nextdst += elem_size;
|
|
nextdst += elem_size;
|
|
nextsrc += elem_size;
|
|
nextsrc += elem_size;
|
|
}
|
|
}
|
|
@@ -587,8 +604,7 @@ UA_Variant_copyRange(const UA_Variant *orig_src, UA_Variant *dst,
|
|
|
|
|
|
/* Clean up if copying failed */
|
|
/* Clean up if copying failed */
|
|
if(retval != UA_STATUSCODE_GOOD) {
|
|
if(retval != UA_STATUSCODE_GOOD) {
|
|
- size_t copied = ((nextdst - elem_size) - (uintptr_t)dst->data) / elem_size;
|
|
|
|
- UA_Array_delete(dst->data, copied, src->type);
|
|
|
|
|
|
+ UA_Array_delete(dst->data, count, src->type);
|
|
dst->data = NULL;
|
|
dst->data = NULL;
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
@@ -598,10 +614,11 @@ UA_Variant_copyRange(const UA_Variant *orig_src, UA_Variant *dst,
|
|
if(isScalar)
|
|
if(isScalar)
|
|
return retval;
|
|
return retval;
|
|
|
|
|
|
- /* Finish the array */
|
|
|
|
|
|
+ /* Copy array dimensions */
|
|
dst->arrayLength = count;
|
|
dst->arrayLength = count;
|
|
if(src->arrayDimensionsSize > 0) {
|
|
if(src->arrayDimensionsSize > 0) {
|
|
- dst->arrayDimensions = UA_Array_new(thisrange.dimensionsSize, &UA_TYPES[UA_TYPES_UINT32]);
|
|
|
|
|
|
+ dst->arrayDimensions =
|
|
|
|
+ UA_Array_new(thisrange.dimensionsSize, &UA_TYPES[UA_TYPES_UINT32]);
|
|
if(!dst->arrayDimensions) {
|
|
if(!dst->arrayDimensions) {
|
|
Variant_deletemembers(dst, NULL);
|
|
Variant_deletemembers(dst, NULL);
|
|
return UA_STATUSCODE_BADOUTOFMEMORY;
|
|
return UA_STATUSCODE_BADOUTOFMEMORY;
|
|
@@ -615,19 +632,20 @@ UA_Variant_copyRange(const UA_Variant *orig_src, UA_Variant *dst,
|
|
}
|
|
}
|
|
|
|
|
|
/* TODO: Allow ranges to reach inside a scalars that are array-like, e.g.
|
|
/* TODO: Allow ranges to reach inside a scalars that are array-like, e.g.
|
|
- variant and strings. This is already possible for reading... */
|
|
|
|
|
|
+ * variant and strings. This is already possible for reading... */
|
|
static UA_StatusCode
|
|
static UA_StatusCode
|
|
Variant_setRange(UA_Variant *v, void *array, size_t arraySize,
|
|
Variant_setRange(UA_Variant *v, void *array, size_t arraySize,
|
|
const UA_NumericRange range, UA_Boolean copy) {
|
|
const UA_NumericRange range, UA_Boolean copy) {
|
|
/* Compute the strides */
|
|
/* Compute the strides */
|
|
size_t count, block, stride, first;
|
|
size_t count, block, stride, first;
|
|
- UA_StatusCode retval = computeStrides(v, range, &count, &block, &stride, &first);
|
|
|
|
|
|
+ UA_StatusCode retval = computeStrides(v, range, &count,
|
|
|
|
+ &block, &stride, &first);
|
|
if(retval != UA_STATUSCODE_GOOD)
|
|
if(retval != UA_STATUSCODE_GOOD)
|
|
return retval;
|
|
return retval;
|
|
if(count != arraySize)
|
|
if(count != arraySize)
|
|
return UA_STATUSCODE_BADINDEXRANGEINVALID;
|
|
return UA_STATUSCODE_BADINDEXRANGEINVALID;
|
|
|
|
|
|
- /* Transfer the content */
|
|
|
|
|
|
+ /* Move/copy the elements */
|
|
size_t block_count = count / block;
|
|
size_t block_count = count / block;
|
|
size_t elem_size = v->type->memSize;
|
|
size_t elem_size = v->type->memSize;
|
|
uintptr_t nextdst = (uintptr_t)v->data + (first * elem_size);
|
|
uintptr_t nextdst = (uintptr_t)v->data + (first * elem_size);
|
|
@@ -641,7 +659,7 @@ Variant_setRange(UA_Variant *v, void *array, size_t arraySize,
|
|
} else {
|
|
} else {
|
|
for(size_t i = 0; i < block_count; i++) {
|
|
for(size_t i = 0; i < block_count; i++) {
|
|
for(size_t j = 0; j < block; j++) {
|
|
for(size_t j = 0; j < block; j++) {
|
|
- UA_deleteMembers_noInit((void*)nextdst, v->type);
|
|
|
|
|
|
+ deleteMembers_noInit((void*)nextdst, v->type);
|
|
retval |= UA_copy((void*)nextsrc, (void*)nextdst, v->type);
|
|
retval |= UA_copy((void*)nextsrc, (void*)nextdst, v->type);
|
|
nextdst += elem_size;
|
|
nextdst += elem_size;
|
|
nextsrc += elem_size;
|
|
nextsrc += elem_size;
|
|
@@ -650,8 +668,7 @@ Variant_setRange(UA_Variant *v, void *array, size_t arraySize,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- /* If pointers were transferred, initialize original array to prevent
|
|
|
|
- * reuse */
|
|
|
|
|
|
+ /* If members were moved, initialize original array to prevent reuse */
|
|
if(!copy && !v->type->fixedSize)
|
|
if(!copy && !v->type->fixedSize)
|
|
memset(array, 0, sizeof(elem_size)*arraySize);
|
|
memset(array, 0, sizeof(elem_size)*arraySize);
|
|
|
|
|
|
@@ -659,15 +676,16 @@ Variant_setRange(UA_Variant *v, void *array, size_t arraySize,
|
|
}
|
|
}
|
|
|
|
|
|
UA_StatusCode
|
|
UA_StatusCode
|
|
-UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array, size_t arraySize,
|
|
|
|
- const UA_NumericRange range) {
|
|
|
|
|
|
+UA_Variant_setRange(UA_Variant *v, void * UA_RESTRICT array,
|
|
|
|
+ size_t arraySize, const UA_NumericRange range) {
|
|
return Variant_setRange(v, array, arraySize, range, false);
|
|
return Variant_setRange(v, array, arraySize, range, false);
|
|
}
|
|
}
|
|
|
|
|
|
UA_StatusCode
|
|
UA_StatusCode
|
|
-UA_Variant_setRangeCopy(UA_Variant *v, const void *array, size_t arraySize,
|
|
|
|
- const UA_NumericRange range) {
|
|
|
|
- return Variant_setRange(v, (void*)(uintptr_t)array, arraySize, range, true);
|
|
|
|
|
|
+UA_Variant_setRangeCopy(UA_Variant *v, const void *array,
|
|
|
|
+ size_t arraySize, const UA_NumericRange range) {
|
|
|
|
+ return Variant_setRange(v, (void*)(uintptr_t)array,
|
|
|
|
+ arraySize, range, true);
|
|
}
|
|
}
|
|
|
|
|
|
/* LocalizedText */
|
|
/* LocalizedText */
|
|
@@ -722,7 +740,8 @@ DiagnosticInfo_copy(UA_DiagnosticInfo const *src, UA_DiagnosticInfo *dst,
|
|
if(src->hasAdditionalInfo)
|
|
if(src->hasAdditionalInfo)
|
|
retval = UA_String_copy(&src->additionalInfo, &dst->additionalInfo);
|
|
retval = UA_String_copy(&src->additionalInfo, &dst->additionalInfo);
|
|
if(src->hasInnerDiagnosticInfo && src->innerDiagnosticInfo) {
|
|
if(src->hasInnerDiagnosticInfo && src->innerDiagnosticInfo) {
|
|
- if((dst->innerDiagnosticInfo = UA_malloc(sizeof(UA_DiagnosticInfo)))) {
|
|
|
|
|
|
+ dst->innerDiagnosticInfo = UA_malloc(sizeof(UA_DiagnosticInfo));
|
|
|
|
+ if(dst->innerDiagnosticInfo) {
|
|
retval |= DiagnosticInfo_copy(src->innerDiagnosticInfo,
|
|
retval |= DiagnosticInfo_copy(src->innerDiagnosticInfo,
|
|
dst->innerDiagnosticInfo, NULL);
|
|
dst->innerDiagnosticInfo, NULL);
|
|
dst->hasInnerDiagnosticInfo = true;
|
|
dst->hasInnerDiagnosticInfo = true;
|
|
@@ -774,8 +793,6 @@ copyGuid(const UA_Guid *src, UA_Guid *dst, const UA_DataType *_) {
|
|
return UA_STATUSCODE_GOOD;
|
|
return UA_STATUSCODE_GOOD;
|
|
}
|
|
}
|
|
|
|
|
|
-static UA_StatusCode copyNoInit(const void *src, void *dst, const UA_DataType *type);
|
|
|
|
-
|
|
|
|
typedef UA_StatusCode
|
|
typedef UA_StatusCode
|
|
(*UA_copySignature)(const void *src, void *dst, const UA_DataType *type);
|
|
(*UA_copySignature)(const void *src, void *dst, const UA_DataType *type);
|
|
|
|
|
|
@@ -791,48 +808,48 @@ static const UA_copySignature copyJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
|
|
(UA_copySignature)copy8Byte, // UInt64
|
|
(UA_copySignature)copy8Byte, // UInt64
|
|
(UA_copySignature)copy4Byte, // Float
|
|
(UA_copySignature)copy4Byte, // Float
|
|
(UA_copySignature)copy8Byte, // Double
|
|
(UA_copySignature)copy8Byte, // Double
|
|
- (UA_copySignature)copyNoInit, // String
|
|
|
|
|
|
+ (UA_copySignature)copy_noInit, // String
|
|
(UA_copySignature)copy8Byte, // DateTime
|
|
(UA_copySignature)copy8Byte, // DateTime
|
|
(UA_copySignature)copyGuid, // Guid
|
|
(UA_copySignature)copyGuid, // Guid
|
|
- (UA_copySignature)copyNoInit, // ByteString
|
|
|
|
- (UA_copySignature)copyNoInit, // XmlElement
|
|
|
|
|
|
+ (UA_copySignature)copy_noInit, // ByteString
|
|
|
|
+ (UA_copySignature)copy_noInit, // XmlElement
|
|
(UA_copySignature)NodeId_copy,
|
|
(UA_copySignature)NodeId_copy,
|
|
(UA_copySignature)ExpandedNodeId_copy,
|
|
(UA_copySignature)ExpandedNodeId_copy,
|
|
(UA_copySignature)copy4Byte, // StatusCode
|
|
(UA_copySignature)copy4Byte, // StatusCode
|
|
- (UA_copySignature)copyNoInit, // QualifiedName
|
|
|
|
|
|
+ (UA_copySignature)copy_noInit, // QualifiedName
|
|
(UA_copySignature)LocalizedText_copy, // LocalizedText
|
|
(UA_copySignature)LocalizedText_copy, // LocalizedText
|
|
(UA_copySignature)ExtensionObject_copy,
|
|
(UA_copySignature)ExtensionObject_copy,
|
|
(UA_copySignature)DataValue_copy,
|
|
(UA_copySignature)DataValue_copy,
|
|
(UA_copySignature)Variant_copy,
|
|
(UA_copySignature)Variant_copy,
|
|
(UA_copySignature)DiagnosticInfo_copy,
|
|
(UA_copySignature)DiagnosticInfo_copy,
|
|
- (UA_copySignature)copyNoInit // all others
|
|
|
|
|
|
+ (UA_copySignature)copy_noInit // all others
|
|
};
|
|
};
|
|
|
|
|
|
static UA_StatusCode
|
|
static UA_StatusCode
|
|
-copyNoInit(const void *src, void *dst, const UA_DataType *type) {
|
|
|
|
|
|
+copy_noInit(const void *src, void *dst, const UA_DataType *type) {
|
|
UA_StatusCode retval = UA_STATUSCODE_GOOD;
|
|
UA_StatusCode retval = UA_STATUSCODE_GOOD;
|
|
uintptr_t ptrs = (uintptr_t)src;
|
|
uintptr_t ptrs = (uintptr_t)src;
|
|
uintptr_t ptrd = (uintptr_t)dst;
|
|
uintptr_t ptrd = (uintptr_t)dst;
|
|
UA_Byte membersSize = type->membersSize;
|
|
UA_Byte membersSize = type->membersSize;
|
|
for(size_t i = 0; i < membersSize; i++) {
|
|
for(size_t i = 0; i < membersSize; i++) {
|
|
- const UA_DataTypeMember *member = &type->members[i];
|
|
|
|
|
|
+ const UA_DataTypeMember *m= &type->members[i];
|
|
const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] };
|
|
const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] };
|
|
- const UA_DataType *memberType = &typelists[!member->namespaceZero][member->memberTypeIndex];
|
|
|
|
- if(!member->isArray) {
|
|
|
|
- ptrs += member->padding;
|
|
|
|
- ptrd += member->padding;
|
|
|
|
- size_t fi = memberType->builtin ? memberType->typeIndex : UA_BUILTIN_TYPES_COUNT;
|
|
|
|
- retval |= copyJumpTable[fi]((const void*)ptrs, (void*)ptrd, memberType);
|
|
|
|
- ptrs += memberType->memSize;
|
|
|
|
- ptrd += memberType->memSize;
|
|
|
|
|
|
+ const UA_DataType *mt = &typelists[!m->namespaceZero][m->memberTypeIndex];
|
|
|
|
+ if(!m->isArray) {
|
|
|
|
+ ptrs += m->padding;
|
|
|
|
+ ptrd += m->padding;
|
|
|
|
+ size_t fi = mt->builtin ? mt->typeIndex : UA_BUILTIN_TYPES_COUNT;
|
|
|
|
+ retval |= copyJumpTable[fi]((const void*)ptrs, (void*)ptrd, mt);
|
|
|
|
+ ptrs += mt->memSize;
|
|
|
|
+ ptrd += mt->memSize;
|
|
} else {
|
|
} else {
|
|
- ptrs += member->padding;
|
|
|
|
- ptrd += member->padding;
|
|
|
|
|
|
+ ptrs += m->padding;
|
|
|
|
+ ptrd += m->padding;
|
|
size_t *dst_size = (size_t*)ptrd;
|
|
size_t *dst_size = (size_t*)ptrd;
|
|
const size_t size = *((const size_t*)ptrs);
|
|
const size_t size = *((const size_t*)ptrs);
|
|
ptrs += sizeof(size_t);
|
|
ptrs += sizeof(size_t);
|
|
ptrd += sizeof(size_t);
|
|
ptrd += sizeof(size_t);
|
|
- retval |= UA_Array_copy(*(void* const*)ptrs, size, (void**)ptrd, memberType);
|
|
|
|
|
|
+ retval |= UA_Array_copy(*(void* const*)ptrs, size, (void**)ptrd, mt);
|
|
if(retval == UA_STATUSCODE_GOOD)
|
|
if(retval == UA_STATUSCODE_GOOD)
|
|
*dst_size = size;
|
|
*dst_size = size;
|
|
else
|
|
else
|
|
@@ -847,16 +864,18 @@ copyNoInit(const void *src, void *dst, const UA_DataType *type) {
|
|
UA_StatusCode
|
|
UA_StatusCode
|
|
UA_copy(const void *src, void *dst, const UA_DataType *type) {
|
|
UA_copy(const void *src, void *dst, const UA_DataType *type) {
|
|
memset(dst, 0, type->memSize); /* init */
|
|
memset(dst, 0, type->memSize); /* init */
|
|
- UA_StatusCode retval = copyNoInit(src, dst, type);
|
|
|
|
|
|
+ UA_StatusCode retval = copy_noInit(src, dst, type);
|
|
if(retval != UA_STATUSCODE_GOOD)
|
|
if(retval != UA_STATUSCODE_GOOD)
|
|
UA_deleteMembers(dst, type);
|
|
UA_deleteMembers(dst, type);
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|
|
-typedef void (*UA_deleteMembersSignature)(void *p, const UA_DataType *type);
|
|
|
|
static void nopDeleteMembers(void *p, const UA_DataType *type) { }
|
|
static void nopDeleteMembers(void *p, const UA_DataType *type) { }
|
|
|
|
|
|
-static const UA_deleteMembersSignature deleteMembersJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
|
|
|
|
|
|
+typedef void (*UA_deleteMembersSignature)(void *p, const UA_DataType *type);
|
|
|
|
+
|
|
|
|
+static const
|
|
|
|
+UA_deleteMembersSignature deleteMembersJumpTable[UA_BUILTIN_TYPES_COUNT + 1] = {
|
|
(UA_deleteMembersSignature)nopDeleteMembers, // Boolean
|
|
(UA_deleteMembersSignature)nopDeleteMembers, // Boolean
|
|
(UA_deleteMembersSignature)nopDeleteMembers, // SByte
|
|
(UA_deleteMembersSignature)nopDeleteMembers, // SByte
|
|
(UA_deleteMembersSignature)nopDeleteMembers, // Byte
|
|
(UA_deleteMembersSignature)nopDeleteMembers, // Byte
|
|
@@ -876,33 +895,33 @@ static const UA_deleteMembersSignature deleteMembersJumpTable[UA_BUILTIN_TYPES_C
|
|
(UA_deleteMembersSignature)NodeId_deleteMembers,
|
|
(UA_deleteMembersSignature)NodeId_deleteMembers,
|
|
(UA_deleteMembersSignature)ExpandedNodeId_deleteMembers, // ExpandedNodeId
|
|
(UA_deleteMembersSignature)ExpandedNodeId_deleteMembers, // ExpandedNodeId
|
|
(UA_deleteMembersSignature)nopDeleteMembers, // StatusCode
|
|
(UA_deleteMembersSignature)nopDeleteMembers, // StatusCode
|
|
- (UA_deleteMembersSignature)UA_deleteMembers_noInit, // QualifiedName
|
|
|
|
|
|
+ (UA_deleteMembersSignature)deleteMembers_noInit, // QualifiedName
|
|
(UA_deleteMembersSignature)LocalizedText_deleteMembers, // LocalizedText
|
|
(UA_deleteMembersSignature)LocalizedText_deleteMembers, // LocalizedText
|
|
(UA_deleteMembersSignature)ExtensionObject_deleteMembers,
|
|
(UA_deleteMembersSignature)ExtensionObject_deleteMembers,
|
|
(UA_deleteMembersSignature)DataValue_deleteMembers,
|
|
(UA_deleteMembersSignature)DataValue_deleteMembers,
|
|
(UA_deleteMembersSignature)Variant_deletemembers,
|
|
(UA_deleteMembersSignature)Variant_deletemembers,
|
|
(UA_deleteMembersSignature)DiagnosticInfo_deleteMembers,
|
|
(UA_deleteMembersSignature)DiagnosticInfo_deleteMembers,
|
|
- (UA_deleteMembersSignature)UA_deleteMembers_noInit,
|
|
|
|
|
|
+ (UA_deleteMembersSignature)deleteMembers_noInit,
|
|
};
|
|
};
|
|
|
|
|
|
static void
|
|
static void
|
|
-UA_deleteMembers_noInit(void *p, const UA_DataType *type) {
|
|
|
|
|
|
+deleteMembers_noInit(void *p, const UA_DataType *type) {
|
|
uintptr_t ptr = (uintptr_t)p;
|
|
uintptr_t ptr = (uintptr_t)p;
|
|
UA_Byte membersSize = type->membersSize;
|
|
UA_Byte membersSize = type->membersSize;
|
|
for(size_t i = 0; i < membersSize; i++) {
|
|
for(size_t i = 0; i < membersSize; i++) {
|
|
- const UA_DataTypeMember *member = &type->members[i];
|
|
|
|
|
|
+ const UA_DataTypeMember *m= &type->members[i];
|
|
const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] };
|
|
const UA_DataType *typelists[2] = { UA_TYPES, &type[-type->typeIndex] };
|
|
- const UA_DataType *memberType = &typelists[!member->namespaceZero][member->memberTypeIndex];
|
|
|
|
- if(!member->isArray) {
|
|
|
|
- ptr += member->padding;
|
|
|
|
- size_t fi = memberType->builtin ? memberType->typeIndex : UA_BUILTIN_TYPES_COUNT;
|
|
|
|
- deleteMembersJumpTable[fi]((void*)ptr, memberType);
|
|
|
|
- ptr += memberType->memSize;
|
|
|
|
|
|
+ const UA_DataType *mt = &typelists[!m->namespaceZero][m->memberTypeIndex];
|
|
|
|
+ if(!m->isArray) {
|
|
|
|
+ ptr += m->padding;
|
|
|
|
+ size_t fi = mt->builtin ? mt->typeIndex : UA_BUILTIN_TYPES_COUNT;
|
|
|
|
+ deleteMembersJumpTable[fi]((void*)ptr, mt);
|
|
|
|
+ ptr += mt->memSize;
|
|
} else {
|
|
} else {
|
|
- ptr += member->padding;
|
|
|
|
|
|
+ ptr += m->padding;
|
|
size_t length = *(size_t*)ptr;
|
|
size_t length = *(size_t*)ptr;
|
|
ptr += sizeof(size_t);
|
|
ptr += sizeof(size_t);
|
|
- UA_Array_delete(*(void**)ptr, length, memberType);
|
|
|
|
|
|
+ UA_Array_delete(*(void**)ptr, length, mt);
|
|
ptr += sizeof(void*);
|
|
ptr += sizeof(void*);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -910,13 +929,13 @@ UA_deleteMembers_noInit(void *p, const UA_DataType *type) {
|
|
|
|
|
|
void
|
|
void
|
|
UA_deleteMembers(void *p, const UA_DataType *type) {
|
|
UA_deleteMembers(void *p, const UA_DataType *type) {
|
|
- UA_deleteMembers_noInit(p, type);
|
|
|
|
|
|
+ deleteMembers_noInit(p, type);
|
|
memset(p, 0, type->memSize); /* init */
|
|
memset(p, 0, type->memSize); /* init */
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
void
|
|
UA_delete(void *p, const UA_DataType *type) {
|
|
UA_delete(void *p, const UA_DataType *type) {
|
|
- UA_deleteMembers_noInit(p, type);
|
|
|
|
|
|
+ deleteMembers_noInit(p, type);
|
|
UA_free(p);
|
|
UA_free(p);
|
|
}
|
|
}
|
|
|
|
|