Skip to content

Commit

Permalink
fix arrayWrite for arrays of strings: They are char[num][len], not ch…
Browse files Browse the repository at this point in the history
…ar*[num]
  • Loading branch information
dirk-zimoch committed Sep 27, 2024
1 parent b5db094 commit 8ca3dc3
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 34 deletions.
15 changes: 8 additions & 7 deletions devOpcuaSup/UaSdk/DataElementUaSdk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 {
Expand All @@ -1077,24 +1077,25 @@ 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);
UaVariant_set(outgoingData, arr);
markAsDirty();
}

dbgWriteArray(num, epicsTypeString(*value));
dbgWriteArray(num, epicsTypeString(value));
}
return ret;
}
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion devOpcuaSup/UaSdk/DataElementUaSdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
37 changes: 12 additions & 25 deletions devOpcuaSup/open62541/DataElementOpen62541.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -1109,44 +1109,31 @@ 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 {
UA_String *arr = static_cast<UA_String *>(UA_Array_new(num, &UA_TYPES[UA_TYPES_STRING]));
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<epicsInt64>(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_Byte*>(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;
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion devOpcuaSup/open62541/DataElementOpen62541.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 8ca3dc3

Please sign in to comment.