pvxs
pvxs copied to clipboard
Not possible to distinguish between scalars and arrays of length 1
Describe the bug It is not possible at the moment to distinguish between the following records via PVAccess:
record(waveform, "one") {
field(FTVL, "STRING")
field(NELM, "1")
field(INP, {const: "foo"})
}
record(stringin, "onestring") {
field(INP, {const: "bar"})
}
This ultimately manifests in the fact that fetching and processing data from a record that is a waveform of strings typically requires some additional checks, since you get something like
$ pvget one
one 2024-06-03 14:23:52.988 foo
whereas if the array has NELM > 1
then you instead get
$ pvget two
one 2024-06-03 14:23:52.988 [foo, bar]
which is typically handled differently in e.g. pyepics, p4p, etc.
Note that this is not really restricted to PVXS, or even PVAccessCPP, but also ChannelAccess. In channel access I believe that due to the protocol there is no possible fix; in PVAccess, it should be fixable since an array of length 1 of type string is sent as an NTScalar, whereas an array of length > 1 is sent as an NTScalarArray; it should be possible to send an array of length one also as an NTScalarArray, which should fix this.
To Reproduce Steps to reproduce the behavior:
- Start an IOC with the db file above
- get the values
- be sad
Expected behavior This is a bit murky, because I might be proposing a breaking change in how IOCs communicate over PVAccess. I think it would be more consistent to have arrays always send as NTScalarArrays instead of NTScalars if they are length 1. But there might be a good reason for the current behaviour.
Information (please complete the following):
$ pvxs/bin/darwin-x86/pvxinfo -D
Host: darwin-x86
Target: darwin-x86 Darwin clang
Toolchain
__cplusplus = 201103
clang 14.0.3 (clang-1403.0.22.14.1)
GCC 4.2.1
_LIBCPP_VERSION 160006
Versions
PVXS 1.2.3 (1.3.1-5-g57f79ce747f062a32eed-dirty)
EPICS 7.0.8.1-DEV
libevent 2.2.0-alpha-dev
Runtime
uname() -> Darwin CIN-716194 22.6.0 Darwin Kernel Version 22.6.0: Mon Apr 22 20:54:28 PDT 2024; root:xnu-8796.141.3.705.2~1/RELEASE_X86_64 x86_64
epicsThreadGetCPUs() -> 16
osiLocalAddr() -> 172.18.21.40
osiSockDiscoverBroadcastAddresses() ->
172.18.23.255
172.18.23.255
192.168.205.255
Effective Client config from environment
EPICS_PVA_ADDR_LIST=172.18.23.255 192.168.205.255
EPICS_PVA_AUTO_ADDR_LIST=NO
EPICS_PVA_BROADCAST_PORT=5076
EPICS_PVA_CONN_TMO=30
EPICS_PVA_INTF_ADDR_LIST=0.0.0.0
EPICS_PVA_NAME_SERVERS=
EPICS_PVA_SERVER_PORT=5075
Effective Server config from environment
EPICS_PVAS_AUTO_BEACON_ADDR_LIST=NO
EPICS_PVAS_BEACON_ADDR_LIST=172.18.23.255 192.168.205.255
EPICS_PVAS_BROADCAST_PORT=5076
EPICS_PVAS_IGNORE_ADDR_LIST=
EPICS_PVAS_INTF_ADDR_LIST=0.0.0.0
EPICS_PVAS_SERVER_PORT=5075
Additional context Add any other context about the problem here.