From 8ca3dc3d84bb6a6b8d019933c2287356ed6fff63 Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Wed, 25 Sep 2024 10:47:42 +0200 Subject: [PATCH] fix arrayWrite for arrays of strings: They are char[num][len], not char*[num] --- devOpcuaSup/UaSdk/DataElementUaSdk.cpp | 15 ++++---- devOpcuaSup/UaSdk/DataElementUaSdk.h | 2 +- .../open62541/DataElementOpen62541.cpp | 37 ++++++------------- devOpcuaSup/open62541/DataElementOpen62541.h | 2 +- 4 files changed, 22 insertions(+), 34 deletions(-) diff --git a/devOpcuaSup/UaSdk/DataElementUaSdk.cpp b/devOpcuaSup/UaSdk/DataElementUaSdk.cpp index e7cbce2f..330d417d 100644 --- a/devOpcuaSup/UaSdk/DataElementUaSdk.cpp +++ b/devOpcuaSup/UaSdk/DataElementUaSdk.cpp @@ -1051,7 +1051,7 @@ DataElementUaSdk::dbgWriteArray (const epicsUInt32 targetSize, const std::string // Write array for EPICS String / OpcUa_String long -DataElementUaSdk::writeArray (const char **value, const epicsUInt32 len, +DataElementUaSdk::writeArray (const char *value, const epicsUInt32 len, const epicsUInt32 num, OpcUa_BuiltInType targetType, dbCommon *prec) @@ -1067,7 +1067,7 @@ DataElementUaSdk::writeArray (const char **value, const epicsUInt32 len, prec->name, variantTypeString(incomingData.type()), variantTypeString(targetType), - epicsTypeString(*value)); + epicsTypeString(value)); (void) recGblSetSevr(prec, WRITE_ALARM, INVALID_ALARM); ret = 1; } else { @@ -1077,16 +1077,17 @@ DataElementUaSdk::writeArray (const char **value, const epicsUInt32 len, char *val = nullptr; const char *pval; // add zero termination if necessary - if (memchr(value[i], '\0', len) == nullptr) { + if (value[len-1] != '\0') { val = new char[len+1]; - strncpy(val, value[i], len); + strncpy(val, value, len); val[len] = '\0'; pval = val; } else { - pval = value[i]; + pval = value; } UaString(pval).copyTo(&arr[i]); delete[] val; + value += len; } { // Scope of Guard G Guard G(outgoingLock); @@ -1094,7 +1095,7 @@ DataElementUaSdk::writeArray (const char **value, const epicsUInt32 len, markAsDirty(); } - dbgWriteArray(num, epicsTypeString(*value)); + dbgWriteArray(num, epicsTypeString(value)); } return ret; } @@ -1198,7 +1199,7 @@ DataElementUaSdk::writeArray (const epicsFloat64 *value, const epicsUInt32 num, long DataElementUaSdk::writeArray (const char *value, const epicsUInt32 len, const epicsUInt32 num, dbCommon *prec) { - return writeArray(&value, len, num, OpcUaType_String, prec); + return writeArray(value, len, num, OpcUaType_String, prec); } void diff --git a/devOpcuaSup/UaSdk/DataElementUaSdk.h b/devOpcuaSup/UaSdk/DataElementUaSdk.h index b9ad542c..34a490a9 100644 --- a/devOpcuaSup/UaSdk/DataElementUaSdk.h +++ b/devOpcuaSup/UaSdk/DataElementUaSdk.h @@ -1065,7 +1065,7 @@ class DataElementUaSdk : public DataElement // Write array value for EPICS String / OpcUa_String long - writeArray (const char **value, const epicsUInt32 len, + writeArray (const char *value, const epicsUInt32 len, const epicsUInt32 num, OpcUa_BuiltInType targetType, dbCommon *prec); diff --git a/devOpcuaSup/open62541/DataElementOpen62541.cpp b/devOpcuaSup/open62541/DataElementOpen62541.cpp index dcacf46f..01761086 100644 --- a/devOpcuaSup/open62541/DataElementOpen62541.cpp +++ b/devOpcuaSup/open62541/DataElementOpen62541.cpp @@ -1093,7 +1093,7 @@ DataElementOpen62541::dbgWriteArray (const epicsUInt32 targetSize, const std::st // Write array for EPICS String / UA_String long -DataElementOpen62541::writeArray (const char **value, const epicsUInt32 len, +DataElementOpen62541::writeArray (const char *value, const epicsUInt32 len, const epicsUInt32 num, const UA_DataType *targetType, dbCommon *prec) @@ -1109,7 +1109,7 @@ DataElementOpen62541::writeArray (const char **value, const epicsUInt32 len, prec->name, variantTypeString(incomingData), variantTypeString(targetType), - epicsTypeString(*value)); + epicsTypeString(value)); (void) recGblSetSevr(prec, WRITE_ALARM, INVALID_ALARM); ret = 1; } else { @@ -1117,36 +1117,23 @@ DataElementOpen62541::writeArray (const char **value, const epicsUInt32 len, if (!arr) { errlogPrintf("%s : out of memory\n", prec->name); (void) recGblSetSevr(prec, WRITE_ALARM, INVALID_ALARM); + ret = 1; } else { for (epicsUInt32 i = 0; i < num; i++) { - char *val = nullptr; - const char *pval; - // add zero termination if necessary - if (memchr(value[i], '\0', len) == nullptr) { - val = new char[static_cast(len)+1]; // static_cast to avoid warning C26451 - strncpy(val, value[i], len); - val[len] = '\0'; - pval = val; - } else { - pval = value[i]; + arr[i].length = strnlen(value, len); + if (arr[i].length) { + arr[i].data = static_cast(UA_malloc(arr[i].length)); + memcpy(arr[i].data, value, arr[i].length); } - arr[i] = UA_STRING_ALLOC(pval); - delete[] val; + value += len; } - UA_StatusCode status; { // Scope of Guard G Guard G(outgoingLock); - status = UA_Variant_setArrayCopy(&outgoingData, arr, num, targetType); + UA_Variant_setArray(&outgoingData, arr, num, targetType); markAsDirty(); } - if (UA_STATUS_IS_BAD(status)) { - errlogPrintf("%s : array copy failed: %s\n", - prec->name, UA_StatusCode_name(status)); - (void) recGblSetSevr(prec, WRITE_ALARM, INVALID_ALARM); - ret = 1; - } else { - dbgWriteArray(num, epicsTypeString(*value)); - } + + dbgWriteArray(num, epicsTypeString(value)); } } return ret; @@ -1215,7 +1202,7 @@ DataElementOpen62541::writeArray (const epicsFloat64 *value, const epicsUInt32 n long DataElementOpen62541::writeArray (const char *value, const epicsUInt32 len, const epicsUInt32 num, dbCommon *prec) { - return writeArray(&value, len, num, &UA_TYPES[UA_TYPES_STRING], prec); + return writeArray(value, len, num, &UA_TYPES[UA_TYPES_STRING], prec); } void diff --git a/devOpcuaSup/open62541/DataElementOpen62541.h b/devOpcuaSup/open62541/DataElementOpen62541.h index 979f1068..a9c2c17f 100644 --- a/devOpcuaSup/open62541/DataElementOpen62541.h +++ b/devOpcuaSup/open62541/DataElementOpen62541.h @@ -1210,7 +1210,7 @@ class DataElementOpen62541 : public DataElement // Write array value for EPICS String / UA_String long - writeArray (const char **value, const epicsUInt32 len, + writeArray (const char *value, const epicsUInt32 len, const epicsUInt32 num, const UA_DataType *targetType, dbCommon *prec);