Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for long DBF_STRING fields #22

Open
anjohnson opened this issue Aug 29, 2018 · 3 comments
Open

Support for long DBF_STRING fields #22

anjohnson opened this issue Aug 29, 2018 · 3 comments

Comments

@anjohnson
Copy link
Member

Since QSRV talks directly to dbAccess it could determine how long a DBF_STRING field's buffer is (they are allowed to be longer than MAX_STRING_SIZE, e.g. the NAME field, and the VAL fields of the lsi, lso and printf record types). QSRV could thus provide access to long string fields without truncation, although it doesn't at the moment.

This is using pvaSrv, which handles this long string's value (although possibly more by luck than by design):

epics> dba this-is-a-long-prefix-to-test-pvaSrv:BaseVersion.NAME
Record Address: 0x77a130 Field Address: 0x77a130 Field Description: 0x7710b0
   No Elements: 1
   Record Type: stringin
    Field Type: 0 = DBF_STRING
    Field Size: 61
       Special: 1
DBR Field Type: 0 = DBR_STRING

tux% pvget this-is-a-long-prefix-to-test-pvaSrv:BaseVersion.NAME
this-is-a-long-prefix-to-test-pvaSrv:BaseVersion.NAME this-is-a-long-prefix-to-test-pvaSrv:BaseVersion

This is using QSRV, which truncates the long string's value at 39 characters:

epics> dba this-is-a-long-prefix-to-test-qsrv:BaseVersion.NAME
Record Address: 0x1104d08 Field Address: 0x1104d08 Field Description: 0x10f1970
   No Elements: 1
   Record Type: stringin
    Field Type: 0 = DBF_STRING
    Field Size: 61
       Special: 1
DBR Field Type: 0 = DBR_STRING

tux% pvget this-is-a-long-prefix-to-test-qsrv:BaseVersion.NAME
this-is-a-long-prefix-to-test-qsrv:BaseVersion.NAME this-is-a-long-prefix-to-test-qsrv:Base
@mdavidsaver
Copy link
Member

I'm not clear on how this would work. I guess you mean to use dbChannelFinalFieldSize(chan) instead of MAX_STRING_SIZE? Can I do this through dbGet()?

@anjohnson
Copy link
Member Author

For monitors and gets using dbChannelFinalFieldSize(chan) would allow any filters to modify the string (not that we have any filters that do string processing yet to my knowledge), so yes. For puts you could use dbChannelFieldSize(chan) to determine the max length if you need it.

This may be harder than I thought to do properly though, and we might want to change dbAccess to make it simpler. As I showed above a pvget from pvaSrv works, but that's because the code just copies an unlimited zero-terminated string from static_cast<char *>(dbChannelField(chan)). For most uses that should work, but it isn't bullet-proof against an unterminated string. I don't see a problem with copying up to a zero-terminator as long as you take no more than dbChannelFinalFieldSize(chan) bytes.

The code for dbGet(chan, DBF_STRING, pbuffer 0, 0, 0) can't handle long strings because there's no way to tell it how big pbuffer is, so it uses the smaller of MAX_STRING_SIZE or chan->addr.field_size. I already added special routines for handling long strings to dbLink.c in 3.15, and we might want to do something similar in dbAccess.c for dbGet() and dbPut().

@mdavidsaver
Copy link
Member

This may be harder than I thought to do properly though

This was my reading of the situation :)

we might want to do something similar in dbAccess.c

I would prefer this to filling up QSRV with workarounds for limitations in this API.

@mdavidsaver mdavidsaver mentioned this issue Mar 27, 2023
21 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants