Extended functionality of dbChannel code:

* Deleted the chan->magic member and associated checks.
 * Moved rset->cvt_dbaddr() call into dbChannelCreate()
 * Added many accessor routines
 * Renamed dbChannelReport() to dbChannelShow() and added dbChannelFilterShow()
This commit is contained in:
Andrew Johnson
2012-04-27 13:21:41 -04:00
committed by Michael Davidsaver
parent f4d55f1249
commit 56468b684e
3 changed files with 119 additions and 55 deletions

View File

@@ -10,6 +10,7 @@
#include "cantProceed.h"
#include "dbChannel.h"
#include "dbCommon.h"
#include "dbBase.h"
#include "link.h"
#include "dbAccessDefs.h"
@@ -292,21 +293,21 @@ static long pvNameLookup(DBENTRY *pdbe, const char **ppname)
return status;
}
long dbChannelTest(const char *pname)
long dbChannelTest(const char *name)
{
DBENTRY dbEntry;
long status;
if (!pname || !*pname || !pdbbase)
if (!name || !*name || !pdbbase)
return S_db_notFound;
status = pvNameLookup(&dbEntry, &pname);
status = pvNameLookup(&dbEntry, &name);
if (status)
goto finish;
/* Test field modifiers */
while (*pname) {
switch (*pname) {
while (*name) {
switch (*name) {
case '$':
switch (dbEntry.pflddes->field_type) {
case DBF_STRING:
@@ -320,13 +321,13 @@ long dbChannelTest(const char *pname)
}
break;
case '{':
status = json_validate(pname);
status = json_validate(name);
goto finish;
default:
status = S_dbLib_fieldNotFound;
goto finish;
}
pname++;
name++;
}
finish:
@@ -356,17 +357,16 @@ static short mapDBFToDBR[DBF_NTYPES] =
dbChannel * dbChannelCreate(const char *name)
{
const char *pname = name;
DBENTRY dbEntry;
dbChannel *chan = NULL;
DBADDR *paddr;
dbFldDes *pflddes;
const char *pname;
long status;
short dbfType;
if (!name || !*name || !pdbbase)
return NULL;
pname = name;
status = pvNameLookup(&dbEntry, &pname);
if (status)
@@ -374,7 +374,6 @@ dbChannel * dbChannelCreate(const char *name)
// FIXME: Use free-list
chan = (dbChannel *) callocMustSucceed(1, sizeof(*chan), "dbChannelCreate");
chan->magic = DBCHANNEL_MAGIC;
chan->name = strdup(name); // FIXME?
ellInit(&chan->filters);
@@ -421,36 +420,30 @@ dbChannel * dbChannelCreate(const char *name)
pname++;
}
finish:
dbFinishEntry(&dbEntry);
if (status && chan) {
dbChannelDelete(chan);
chan = NULL;
}
return chan;
}
long dbChannelOpen(dbChannel *chan)
{
DBADDR *paddr;
chFilter *filter;
long status = 0;
if (chan->magic != DBCHANNEL_MAGIC)
return S_db_notInit;
paddr = &chan->addr;
if (paddr->special == SPC_DBADDR) {
struct rset *prset = dbGetRset(paddr);
/* Let record type modify the dbAddr */
if (prset && prset->cvt_dbaddr) {
status = prset->cvt_dbaddr(paddr);
if (status)
return status;
if (status) goto finish;
}
}
finish:
if (status && chan) {
dbChannelDelete(chan);
chan = NULL;
}
dbFinishEntry(&dbEntry);
return chan;
}
long dbChannelOpen(dbChannel *chan)
{
chFilter *filter;
long status = 0;
filter = (chFilter *) ellFirst(&chan->filters);
while (filter) {
status = filter->fif->channel_open(filter);
@@ -461,19 +454,81 @@ long dbChannelOpen(dbChannel *chan)
return status;
}
void dbChannelReport(dbChannel *chan, int level)
const char * dbChannelName(dbChannel *chan)
{
chFilter *filter;
return chan->name;
}
if (chan->magic != DBCHANNEL_MAGIC)
return;
struct dbCommon * dbChannelRecord(dbChannel *chan)
{
return chan->addr.precord;
}
printf("Channel '%s': %d filter(s)\n", chan->name,
ellCount(&chan->filters));
struct dbFldDes * dbChannelFldDes(dbChannel *chan)
{
return chan->addr.pfldDes;
}
filter = (chFilter *) ellFirst(&chan->filters);
long dbChannelElements(dbChannel *chan)
{
return chan->addr.no_elements;
}
short dbChannelFieldType(dbChannel *chan)
{
return chan->addr.field_type;
}
short dbChannelExportType(dbChannel *chan)
{
return chan->addr.dbr_field_type;
}
short dbChannelElementSize(dbChannel *chan)
{
return chan->addr.field_size;
}
short dbChannelSpecial(dbChannel *chan)
{
return chan->addr.special;
}
void * dbChannelData(dbChannel *chan)
{
void * pdata = chan->addr.pfield;
/* FIXME: offer to filters? */
return pdata;
}
long dbChannelPut(dbChannel *chan, short type, const void *pbuffer, long nRequest)
{
/* FIXME: offer to filters? */
return dbPut(&chan->addr, type, pbuffer, nRequest);
}
long dbChannelPutField(dbChannel *chan, short type, const void *pbuffer, long nRequest)
{
/* FIXME: offer to filters? */
return dbPutField(&chan->addr, type, pbuffer, nRequest);
}
void dbChannelShow(dbChannel *chan, int level)
{
printf(" dbChannel name: %s\n", chan->name);
/* FIXME: show field_type name */
printf(" field_type %d, %ld element(s), %d filter(s)",
chan->addr.field_type,
chan->addr.no_elements, ellCount(&chan->filters));
if (level > 0)
dbChannelFilterShow(chan, level - 1);
}
void dbChannelFilterShow(dbChannel *chan, int level)
{
chFilter *filter = (chFilter *) ellFirst(&chan->filters);
while (filter) {
filter->fif->channel_report(filter, level);
filter->fif->channel_report(filter, level - 1);
filter = (chFilter *) ellNext(&filter->node);
}
}
@@ -482,20 +537,17 @@ long dbChannelDelete(dbChannel *chan)
{
chFilter *filter;
if (chan->magic != DBCHANNEL_MAGIC)
return S_db_notInit;
while ((filter = (chFilter *) ellGet(&chan->filters))) {
filter->fif->channel_close(filter);
free(filter);
}
free(chan->name); // FIXME?
chan->magic = 0;
free((char *) chan->name); // FIXME: Use free-list
free(chan); // FIXME: Use free-list
return 0;
}
/* FIXME: Do these belong in a different file? */
void dbRegisterFilter(const char *name, const chFilterIf *fif)

View File

@@ -16,16 +16,11 @@
#include "shareLib.h"
#ifdef __cplusplus
// extern "C" {
extern "C" {
#endif
#define DBCHANNEL_MAGIC 0xdbc4a9e1
#define S_db_notInit (M_dbAccess|21) /*dbChannel not initialized*/
/* A dbChannel points to a record field, and can have multiple filters */
typedef struct dbChannel {
epicsUInt32 magic;
const char *name;
dbAddr addr;
ELLLIST filters;
@@ -74,7 +69,7 @@ typedef struct chFilterIf {
/* Channel operations: */
long (* channel_open)(chFilter *filter);
void (* channel_report)(chFilter *filter, int level);
/* FIXME: More routines here ... */
/* FIXME: More filter routines here ... */
void (* channel_close)(chFilter *filter);
} chFilterIf;
@@ -86,10 +81,27 @@ struct chFilter {
void *puser;
};
epicsShareFunc long dbChannelTest(const char *pname);
epicsShareFunc dbChannel * dbChannelCreate(const char *pname);
struct dbCommon;
struct dbFldDes;
epicsShareFunc long dbChannelTest(const char *name);
epicsShareFunc dbChannel * dbChannelCreate(const char *name);
epicsShareFunc long dbChannelOpen(dbChannel *chan);
epicsShareFunc void dbChannelReport(dbChannel *chan, int level);
epicsShareFunc const char * dbChannelName(dbChannel *chan);
epicsShareFunc struct dbCommon * dbChannelRecord(dbChannel *chan);
epicsShareFunc struct dbFldDes * dbChannelFldDes(dbChannel *chan);
epicsShareFunc long dbChannelElements(dbChannel *chan);
epicsShareFunc short dbChannelFieldType(dbChannel *chan);
epicsShareFunc short dbChannelExportType(dbChannel *chan);
epicsShareFunc short dbChannelElementSize(dbChannel *chan);
epicsShareFunc short dbChannelSpecial(dbChannel *chan);
epicsShareFunc void * dbChannelData(dbChannel *chan);
epicsShareFunc long dbChannelPut(dbChannel *chan, short type,
const void *pbuffer, long nRequest);
epicsShareFunc long dbChannelPutField(dbChannel *chan, short type,
const void *pbuffer, long nRequest);
epicsShareFunc void dbChannelShow(dbChannel *chan, int level);
epicsShareFunc void dbChannelFilterShow(dbChannel *chan, int level);
epicsShareFunc long dbChannelDelete(dbChannel *chan);
epicsShareFunc void dbRegisterFilter(const char *key, const chFilterIf *fif);

View File

@@ -185,7 +185,7 @@ MAIN(dbChannelTest)
testOk1(!!(pch = dbChannelCreate("x.{\"scalar\":null}")));
e = e_report;
dbChannelReport(pch, 0);
dbChannelShow(pch, 0);
e = e_close;
testOk1(!dbChannelDelete(pch));