allow arrays of strings in CHAR wf and lsi (concatenating)

This commit is contained in:
2022-07-28 12:20:48 +02:00
parent 96fe9306c7
commit efd9e7908a
3 changed files with 49 additions and 113 deletions

View File

@@ -186,8 +186,8 @@ static long dbConstLoadLS(struct link *plink, char *pbuffer, epicsUInt32 size,
status = dbLSConvertJSON(pstr, pbuffer, size, plen);
if (status)
errlogPrintf("... while parsing link %s.%s %s\n",
plink->precord->name, dbLinkFieldName(plink), pstr);
errlogPrintf("... while parsing link %s.%s\n",
plink->precord->name, dbLinkFieldName(plink));
return status;
}
@@ -206,8 +206,8 @@ static long dbConstLoadArray(struct link *plink, short dbrType, void *pbuffer,
status = dbPutConvertJSON(pstr, dbrType, pbuffer, pnReq);
if (status)
errlogPrintf("... while parsing link %s.%s %s\n",
plink->precord->name, dbLinkFieldName(plink), pstr);
errlogPrintf("... while parsing link %s.%s\n",
plink->precord->name, dbLinkFieldName(plink));
return status;
}

View File

@@ -26,14 +26,16 @@ typedef struct parseContext {
short dbrType;
short dbrSize;
char *pdest;
int elems;
size_t elems;
} parseContext;
static int dbcj_null(void *ctx) {
errlogPrintf("dbConvertJSON: Null objects not supported\n");
return 0; /* Illegal */
}
static int dbcj_boolean(void *ctx, int val) {
errlogPrintf("dbConvertJSON: Boolean not supported\n");
return 0; /* Illegal */
}
@@ -50,10 +52,6 @@ static int dbcj_integer(void *ctx, long long num) {
return 1;
}
static int dblsj_integer(void *ctx, long long num) {
return 0; /* Illegal */
}
static int dbcj_double(void *ctx, double num) {
parseContext *parser = (parseContext *) ctx;
FASTCONVERT conv = dbFastPutConvertRoutine[DBF_DOUBLE][parser->dbrType];
@@ -66,19 +64,23 @@ static int dbcj_double(void *ctx, double num) {
return 1;
}
static int dblsj_double(void *ctx, double num) {
return 0; /* Illegal */
}
static int dbcj_string(void *ctx, const unsigned char *val, size_t len) {
parseContext *parser = (parseContext *) ctx;
char *pdest = parser->pdest;
/* Not attempting to handle char-array fields here, they need more
* metadata about the field than we have available at the moment.
*/
if (parser->dbrType == DBF_CHAR || parser->dbrType == DBF_UCHAR) {
/* Treating char array as long string */
if (len > parser->elems)
len = parser->elems;
strncpy(pdest, (const char *) val, len);
parser->elems -= len;
parser->pdest += len;
return 1;
}
if (parser->dbrType != DBF_STRING) {
errlogPrintf("dbConvertJSON: String provided, numeric value(s) expected\n");
errlogPrintf("dbConvertJSON: String \"%.*s\" provided, numeric value expected\n",
(int)len, val);
return 0; /* Illegal */
}
@@ -93,39 +95,11 @@ static int dbcj_string(void *ctx, const unsigned char *val, size_t len) {
return 1;
}
static int dblsj_string(void *ctx, const unsigned char *val, size_t len) {
parseContext *parser = (parseContext *) ctx;
char *pdest = parser->pdest;
if (parser->dbrType != DBF_STRING) {
errlogPrintf("dbConvertJSON: dblsj_string dbrType error\n");
return 0; /* Illegal */
}
if (parser->elems > 0) {
if (len > parser->dbrSize - 1)
len = parser->dbrSize - 1;
strncpy(pdest, (const char *) val, len);
pdest[len] = 0;
parser->pdest = pdest + len;
parser->elems = 0;
}
return 1;
}
static int dbcj_start_map(void *ctx) {
errlogPrintf("dbConvertJSON: Map type not supported\n");
return 0; /* Illegal */
}
static int dbcj_map_key(void *ctx, const unsigned char *key, size_t len) {
return 0; /* Illegal */
}
static int dbcj_end_map(void *ctx) {
return 0; /* Illegal */
}
static int dbcj_start_array(void *ctx) {
parseContext *parser = (parseContext *) ctx;
@@ -135,32 +109,30 @@ static int dbcj_start_array(void *ctx) {
return (parser->depth == 1);
}
static int dbcj_end_array(void *ctx) {
parseContext *parser = (parseContext *) ctx;
parser->depth--;
return (parser->depth == 0);
}
static yajl_callbacks dbcj_callbacks = {
dbcj_null, dbcj_boolean, dbcj_integer, dbcj_double, NULL, dbcj_string,
dbcj_start_map, dbcj_map_key, dbcj_end_map,
dbcj_start_array, dbcj_end_array
dbcj_start_map, NULL, NULL,
dbcj_start_array, NULL
};
long dbPutConvertJSON(const char *json, short dbrType,
void *pdest, long *pnRequest)
{
parseContext context, *parser = &context;
yajl_alloc_funcs dbcj_alloc;
yajl_handle yh;
yajl_status ys;
size_t jlen = strlen(json);
long status;
if(INVALID_DB_REQ(dbrType))
if (INVALID_DB_REQ(dbrType)) {
errlogPrintf("dbConvertJSON: Invalid dbrType %d\n", dbrType);
return S_db_badDbrtype;
}
if (!jlen) {
*pnRequest = 0;
return 0;
}
if (!jlen) {
*pnRequest = 0;
@@ -173,10 +145,11 @@ long dbPutConvertJSON(const char *json, short dbrType,
parser->pdest = pdest;
parser->elems = *pnRequest;
yajl_set_default_alloc_funcs(&dbcj_alloc);
yh = yajl_alloc(&dbcj_callbacks, &dbcj_alloc, parser);
if (!yh)
yh = yajl_alloc(&dbcj_callbacks, NULL, parser);
if (!yh) {
errlogPrintf("dbConvertJSON: out of memory\n");
return S_db_noMemory;
}
ys = yajl_parse(yh, (const unsigned char *) json, jlen);
if (ys == yajl_status_ok)
@@ -188,36 +161,23 @@ long dbPutConvertJSON(const char *json, short dbrType,
status = 0;
break;
case yajl_status_error: {
unsigned char *err = yajl_get_error(yh, 1,
(const unsigned char *) json, jlen);
errlogPrintf("dbConvertJSON: %s\n", err);
yajl_free_error(yh, err);
default: {
unsigned char *err = yajl_get_error(yh, 1,
(const unsigned char *) json, jlen);
errlogPrintf("dbConvertJSON: %s", err);
yajl_free_error(yh, err);
status = S_db_badField;
}
/* fall through */
default:
status = S_db_badField;
}
yajl_free(yh);
return status;
}
static yajl_callbacks dblsj_callbacks = {
dbcj_null, dbcj_boolean, dblsj_integer, dblsj_double, NULL, dblsj_string,
dbcj_start_map, dbcj_map_key, dbcj_end_map,
dbcj_start_array, dbcj_end_array
};
long dbLSConvertJSON(const char *json, char *pdest, epicsUInt32 size,
epicsUInt32 *plen)
{
parseContext context, *parser = &context;
yajl_alloc_funcs dbcj_alloc;
yajl_handle yh;
yajl_status ys;
size_t jlen = strlen(json);
long nRequest = size-1;
long status;
if (!size) {
@@ -225,36 +185,8 @@ long dbLSConvertJSON(const char *json, char *pdest, epicsUInt32 size,
return 0;
}
parser->depth = 0;
parser->dbrType = DBF_STRING;
parser->dbrSize = size;
parser->pdest = pdest;
parser->elems = 1;
yajl_set_default_alloc_funcs(&dbcj_alloc);
yh = yajl_alloc(&dblsj_callbacks, &dbcj_alloc, parser);
if (!yh)
return S_db_noMemory;
ys = yajl_parse(yh, (const unsigned char *) json, jlen);
switch (ys) {
case yajl_status_ok:
*plen = (char *) parser->pdest - pdest + 1;
status = 0;
break;
case yajl_status_error: {
unsigned char *err = yajl_get_error(yh, 1,
(const unsigned char *) json, jlen);
errlogPrintf("dbLoadLS_JSON: %s\n", err);
yajl_free_error(yh, err);
}
/* fall through */
default:
status = S_db_badField;
}
yajl_free(yh);
status = dbPutConvertJSON(json, DBF_CHAR, pdest, &nRequest);
pdest[nRequest++] = 0;
*plen = nRequest;
return status;
}

View File

@@ -996,8 +996,12 @@ static void printBuffer(
i = 0;
while (len > 0) {
int chunk = (len > MAXLINE - 5) ? MAXLINE - 5 : len;
sprintf(pmsg, "\"%.*s\"", chunk, (char *)pbuffer + i);
strcpy(pmsg, "\"");
while (epicsStrnEscapedFromRawSize((char *)pbuffer + i, chunk) >= MAXLINE - 5)
chunk--;
epicsStrnEscapedFromRaw(pmsg+1, MAXLINE - 5,
(char *)pbuffer + i, chunk);
strcat(pmsg, "\"");
len -= chunk; i += chunk;
if (len > 0)
strcat(pmsg, " +");