From 40a3a6674530a824ab9065c4ed8cfb5356fd6502 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 31 Aug 2016 00:36:23 -0500 Subject: [PATCH] Added loadLS routine to lset The long string in/out records use a different initializer for constant links. The new loadLS method allows a constant link type to initialize such a long string field. NB: This routine was added in the middle of the lset table. Any external link support implementations must be adjusted. --- src/ioc/db/dbCa.c | 2 +- src/ioc/db/dbConstLink.c | 25 +++++++++++++++++++++++++ src/ioc/db/dbDbLink.c | 2 +- src/ioc/db/dbLink.c | 25 +++++++++++-------------- src/ioc/db/dbLink.h | 2 ++ src/std/link/lnkConst.c | 31 ++++++++++++++++++++++++++++++- 6 files changed, 70 insertions(+), 17 deletions(-) diff --git a/src/ioc/db/dbCa.c b/src/ioc/db/dbCa.c index 99dcd75bb..88d4468f4 100644 --- a/src/ioc/db/dbCa.c +++ b/src/ioc/db/dbCa.c @@ -715,7 +715,7 @@ static void scanLinkOnce(dbCommon *prec, caLink *pca) { static lset dbCa_lset = { 0, 1, /* not Constant, Volatile */ dbCaRemoveLink, - NULL, NULL, + NULL, NULL, NULL, isConnected, getDBFtype, getElements, dbCaGetLink, diff --git a/src/ioc/db/dbConstLink.c b/src/ioc/db/dbConstLink.c index 821fc58da..5f3aa1ac0 100644 --- a/src/ioc/db/dbConstLink.c +++ b/src/ioc/db/dbConstLink.c @@ -69,6 +69,30 @@ static long dbConstLoadScalar(struct link *plink, short dbrType, void *pbuffer) (pstr, pbuffer, NULL); } +static long dbConstLoadLS(struct link *plink, char *pbuffer, epicsUInt32 size, + epicsUInt32 *plen) +{ + const char *pstr = plink->value.constantStr; + size_t len; + + if (!pstr) + return S_db_badField; + len = strlen(pstr); + + /* FIXME This handles the common case, but not the general one... */ + if (pstr[0] == '[' && pstr[1] == '"' && + pstr[len-2] == '"' && pstr[len-1] == ']') { + pstr += 2; + len -= 4; + } + if (--size > len) size = len; + + strncpy(pbuffer, pstr, size); + pbuffer[size] = 0; + *plen = (epicsUInt32) strlen(pbuffer) + 1; + return 0; +} + static long dbConstLoadArray(struct link *plink, short dbrType, void *pbuffer, long *pnReq) { @@ -102,6 +126,7 @@ static lset dbConst_lset = { 1, 0, /* Constant, not Volatile */ NULL, dbConstLoadScalar, + dbConstLoadLS, dbConstLoadArray, NULL, NULL, dbConstGetNelements, diff --git a/src/ioc/db/dbDbLink.c b/src/ioc/db/dbDbLink.c index cdecd0ea6..2fc21c5bc 100644 --- a/src/ioc/db/dbDbLink.c +++ b/src/ioc/db/dbDbLink.c @@ -338,7 +338,7 @@ static void dbDbScanFwdLink(struct link *plink) static lset dbDb_lset = { 0, 0, /* not Constant, not Volatile */ dbDbRemoveLink, - NULL, NULL, + NULL, NULL, NULL, dbDbIsConnected, dbDbGetDBFtype, dbDbGetElements, dbDbGetValue, diff --git a/src/ioc/db/dbLink.c b/src/ioc/db/dbLink.c index 7e1cceb03..78df46941 100644 --- a/src/ioc/db/dbLink.c +++ b/src/ioc/db/dbLink.c @@ -206,6 +206,17 @@ long dbLoadLink(struct link *plink, short dbrType, void *pbuffer) return S_db_noLSET; } +long dbLoadLinkLS(struct link *plink, char *pbuffer, epicsUInt32 size, + epicsUInt32 *plen) +{ + lset *plset = plink->lset; + + if (plset && plset->loadLS) + return plset->loadLS(plink, pbuffer, size, plen); + + return S_db_noLSET; +} + long dbLoadLinkArray(struct link *plink, short dbrType, void *pbuffer, long *pnRequest) { @@ -400,20 +411,6 @@ void dbScanFwdLink(struct link *plink) /* Helper functions for long string support */ -long dbLoadLinkLS(struct link *plink, char *pbuffer, epicsUInt32 size, - epicsUInt32 *plen) -{ - if (plink->type == CONSTANT && - plink->value.constantStr) { - strncpy(pbuffer, plink->value.constantStr, --size); - pbuffer[size] = 0; - *plen = (epicsUInt32) strlen(pbuffer) + 1; - return 0; - } - - return S_db_noLSET; -} - long dbGetLinkLS(struct link *plink, char *pbuffer, epicsUInt32 size, epicsUInt32 *plen) { diff --git a/src/ioc/db/dbLink.h b/src/ioc/db/dbLink.h index 2903528c1..ebdf24307 100644 --- a/src/ioc/db/dbLink.h +++ b/src/ioc/db/dbLink.h @@ -37,6 +37,8 @@ typedef struct lset { /* Const init, data type hinting */ long (*loadScalar)(struct link *plink, short dbrType, void *pbuffer); + long (*loadLS)(struct link *plink, char *pbuffer, epicsUInt32 size, + epicsUInt32 *plen); long (*loadArray)(struct link *plink, short dbrType, void *pbuffer, long *pnRequest); diff --git a/src/std/link/lnkConst.c b/src/std/link/lnkConst.c index bf956215e..842867b6d 100644 --- a/src/std/link/lnkConst.c +++ b/src/std/link/lnkConst.c @@ -341,6 +341,35 @@ static long lnkConst_loadScalar(struct link *plink, short dbrType, void *pbuffer return status; } +static long lnkConst_loadLS(struct link *plink, char *pbuffer, epicsUInt32 size, + epicsUInt32 *plen) +{ + clink *clink = CONTAINER(plink->value.json.jlink, struct clink, jlink); + const char *pstr; + + IFDEBUG(10) + printf("lnkConst_loadLS(const@%p, %p, %d, %d)\n", + clink, pbuffer, size, *plen); + + switch (clink->type) { + case sc40: + pstr = clink->value.scalar_string; + break; + + case ac40: + pstr = clink->value.pstrings[0]; + break; + + default: + return S_db_badField; + } + + strncpy(pbuffer, pstr, --size); + pbuffer[size] = 0; + *plen = (epicsUInt32) strlen(pbuffer) + 1; + return 0; +} + static long lnkConst_loadArray(struct link *plink, short dbrType, void *pbuffer, long *pnReq) { @@ -437,7 +466,7 @@ static long lnkConst_getValue(struct link *plink, short dbrType, void *pbuffer, static lset lnkConst_lset = { 1, 0, /* Constant, not Volatile */ - NULL, lnkConst_loadScalar, lnkConst_loadArray, NULL, + NULL, lnkConst_loadScalar, lnkConst_loadLS, lnkConst_loadArray, NULL, NULL, lnkConst_getNelements, lnkConst_getValue, NULL, NULL, NULL, NULL, NULL,