Add function to dbChannel.c to create a db_field_log copy of array/string data
This commit is contained in:
committed by
Michael Davidsaver
parent
e67ef8a005
commit
d2abc71527
@@ -22,6 +22,7 @@
|
||||
#include "dbBase.h"
|
||||
#include "dbEvent.h"
|
||||
#include "link.h"
|
||||
#include <freeList.h>
|
||||
#include "dbAccessDefs.h"
|
||||
#include "dbLock.h"
|
||||
#include "dbStaticLib.h"
|
||||
@@ -43,6 +44,16 @@ typedef struct parseContext {
|
||||
|
||||
#define CALLIF(rtn) !rtn ? parse_stop : rtn
|
||||
|
||||
static void *dbchStringFreeList;
|
||||
|
||||
void dbChannelInit (void)
|
||||
{
|
||||
if (!dbchStringFreeList) {
|
||||
freeListInitPvt(&dbchStringFreeList,
|
||||
sizeof(epicsOldString), 128);
|
||||
}
|
||||
}
|
||||
|
||||
static void chf_value(parseContext *parser, parse_result *presult)
|
||||
{
|
||||
chFilter *filter = parser->filter;
|
||||
@@ -676,6 +687,38 @@ void dbChannelDelete(dbChannel *chan)
|
||||
free(chan); // FIXME: Use free-list
|
||||
}
|
||||
|
||||
static void freeArray(db_field_log *pfl) {
|
||||
if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
|
||||
freeListFree(dbchStringFreeList, pfl->u.r.field);
|
||||
} else {
|
||||
free(pfl->u.r.field);
|
||||
}
|
||||
}
|
||||
|
||||
void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (!pfl->type == dbfl_type_rec) return;
|
||||
|
||||
struct dbCommon *prec = dbChannelRecord(chan);
|
||||
pfl->type = dbfl_type_ref;
|
||||
pfl->stat = prec->stat;
|
||||
pfl->sevr = prec->sevr;
|
||||
pfl->time = prec->time;
|
||||
pfl->field_type = chan->addr.field_type;
|
||||
pfl->no_elements = chan->addr.no_elements;
|
||||
pfl->field_size = chan->addr.field_size;
|
||||
pfl->u.r.dtor = freeArray;
|
||||
pfl->u.r.pvt = pvt;
|
||||
if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
|
||||
p = freeListCalloc(dbchStringFreeList);
|
||||
} else {
|
||||
p = calloc(pfl->no_elements, pfl->field_size);
|
||||
}
|
||||
if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL);
|
||||
pfl->u.r.field = p;
|
||||
}
|
||||
|
||||
/* FIXME: Do these belong in a different file? */
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ struct chFilter {
|
||||
struct dbCommon;
|
||||
struct dbFldDes;
|
||||
|
||||
epicsShareFunc void dbChannelInit (void);
|
||||
epicsShareFunc long dbChannelTest(const char *name);
|
||||
epicsShareFunc dbChannel * dbChannelCreate(const char *name);
|
||||
epicsShareFunc long dbChannelOpen(dbChannel *chan);
|
||||
@@ -171,6 +172,7 @@ epicsShareFunc void dbRegisterFilter(const char *key, const chFilterIf *fif, voi
|
||||
epicsShareFunc db_field_log* dbChannelRunPreChain(dbChannel *chan, db_field_log *pLogIn);
|
||||
epicsShareFunc db_field_log* dbChannelRunPostChain(dbChannel *chan, db_field_log *pLogIn);
|
||||
epicsShareFunc const chFilterPlugin * dbFindFilter(const char *key, size_t len);
|
||||
epicsShareFunc void dbChannelMakeArrayCopy(void *pvt, db_field_log *pfl, dbChannel *chan);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -11,43 +11,10 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <epicsExport.h>
|
||||
#include <freeList.h>
|
||||
#include <chfPlugin.h>
|
||||
#include <db_field_log.h>
|
||||
#include <dbAccessDefs.h>
|
||||
#include <dbCommon.h>
|
||||
|
||||
static short mapDBFToDBR[DBF_NTYPES] = {
|
||||
/* DBF_STRING => */ DBR_STRING,
|
||||
/* DBF_CHAR => */ DBR_CHAR,
|
||||
/* DBF_UCHAR => */ DBR_UCHAR,
|
||||
/* DBF_SHORT => */ DBR_SHORT,
|
||||
/* DBF_USHORT => */ DBR_USHORT,
|
||||
/* DBF_LONG => */ DBR_LONG,
|
||||
/* DBF_ULONG => */ DBR_ULONG,
|
||||
/* DBF_FLOAT => */ DBR_FLOAT,
|
||||
/* DBF_DOUBLE => */ DBR_DOUBLE,
|
||||
/* DBF_ENUM, => */ DBR_ENUM,
|
||||
/* DBF_MENU, => */ DBR_ENUM,
|
||||
/* DBF_DEVICE => */ DBR_ENUM,
|
||||
/* DBF_INLINK => */ DBR_STRING,
|
||||
/* DBF_OUTLINK => */ DBR_STRING,
|
||||
/* DBF_FWDLINK => */ DBR_STRING,
|
||||
/* DBF_NOACCESS => */ DBR_NOACCESS
|
||||
};
|
||||
|
||||
static void *tsStringFreeList;
|
||||
|
||||
void freeArray(db_field_log *pfl) {
|
||||
if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
|
||||
freeListFree(tsStringFreeList, pfl->u.r.field);
|
||||
} else {
|
||||
free(pfl->u.r.field);
|
||||
}
|
||||
}
|
||||
|
||||
static db_field_log* tsFilter(void* pvt, dbChannel *chan, db_field_log *pfl) {
|
||||
epicsTimeStamp now;
|
||||
@@ -55,23 +22,7 @@ static db_field_log* tsFilter(void* pvt, dbChannel *chan, db_field_log *pfl) {
|
||||
|
||||
/* If string or array, must make a copy (to ensure coherence between time and data) */
|
||||
if (pfl->type == dbfl_type_rec) {
|
||||
void *p;
|
||||
struct dbCommon *prec = dbChannelRecord(chan);
|
||||
pfl->type = dbfl_type_ref;
|
||||
pfl->stat = prec->stat;
|
||||
pfl->sevr = prec->sevr;
|
||||
pfl->field_type = chan->addr.field_type;
|
||||
pfl->no_elements = chan->addr.no_elements;
|
||||
pfl->field_size = chan->addr.field_size;
|
||||
pfl->u.r.dtor = freeArray;
|
||||
pfl->u.r.pvt = pvt;
|
||||
if (pfl->field_type == DBF_STRING && pfl->no_elements == 1) {
|
||||
p = freeListCalloc(tsStringFreeList);
|
||||
} else {
|
||||
p = calloc(pfl->no_elements, pfl->field_size);
|
||||
}
|
||||
if (p) dbGet(&chan->addr, mapDBFToDBR[pfl->field_type], p, NULL, &pfl->no_elements, NULL);
|
||||
pfl->u.r.field = p;
|
||||
dbChannelMakeArrayCopy(pvt, pfl, chan);
|
||||
}
|
||||
|
||||
pfl->time = now;
|
||||
@@ -112,11 +63,6 @@ static void tsInitialize(void)
|
||||
if(!firstTime) return;
|
||||
firstTime = 0;
|
||||
|
||||
if (!tsStringFreeList) {
|
||||
freeListInitPvt(&tsStringFreeList,
|
||||
sizeof(epicsOldString), 64);
|
||||
}
|
||||
|
||||
chfPluginRegister("ts", &tsPif, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "initHooks.h"
|
||||
#include "epicsExit.h"
|
||||
#include "epicsSignal.h"
|
||||
#include "dbChannel.h"
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "epicsRelease.h"
|
||||
@@ -460,6 +461,7 @@ static void doInitRecord1(dbRecordType *pdbRecordType, dbCommon *precord,
|
||||
|
||||
static void initDatabase(void)
|
||||
{
|
||||
dbChannelInit();
|
||||
iterateRecords(doInitRecord0, NULL);
|
||||
iterateRecords(doResolveLinks, NULL);
|
||||
iterateRecords(doInitRecord1, NULL);
|
||||
|
||||
Reference in New Issue
Block a user