diff --git a/modules/database/src/ioc/db/dbConstLink.c b/modules/database/src/ioc/db/dbConstLink.c index c05915717..91478d942 100644 --- a/modules/database/src/ioc/db/dbConstLink.c +++ b/modules/database/src/ioc/db/dbConstLink.c @@ -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; } diff --git a/modules/database/src/ioc/db/dbConvertJSON.c b/modules/database/src/ioc/db/dbConvertJSON.c index f4bc81940..d685b69a9 100644 --- a/modules/database/src/ioc/db/dbConvertJSON.c +++ b/modules/database/src/ioc/db/dbConvertJSON.c @@ -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; } diff --git a/modules/database/src/ioc/db/dbTest.c b/modules/database/src/ioc/db/dbTest.c index 6f5c3eab2..a82b9eb6b 100644 --- a/modules/database/src/ioc/db/dbTest.c +++ b/modules/database/src/ioc/db/dbTest.c @@ -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, " +");