add arCFChanWrite_args
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* Copyright 1990-92, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
@@ -25,13 +25,14 @@
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 03-09-90 rac initial version
|
||||
* .02 07-31-91 rac installed in SCCS
|
||||
* .03 09-18-91 rac change arg for arCFChanRead to int--short
|
||||
* causes problems on Sun4; other minor fixes
|
||||
* .01 03-09-90 rac initial version
|
||||
* .02 07-31-91 rac installed in SCCS
|
||||
* .03 09-18-91 rac change arg for arCFChanRead to int--short
|
||||
* causes problems on Sun4; other minor fixes
|
||||
* .04 04-04-92 rac add arCFChanWrite_args; handle flags for begin
|
||||
* and end of snapshot
|
||||
*
|
||||
* make options
|
||||
* -DvxWorks makes a version for VxWorks
|
||||
* -DNDEBUG don't compile assert() checking
|
||||
* -DDEBUG compile various debug code, including checks on
|
||||
* malloc'd memory
|
||||
@@ -49,11 +50,7 @@
|
||||
* #include <cadef.h> definitions for Channel Access
|
||||
* #include <db_access.h> definitions for database related items
|
||||
* #include <arAccessLib.h> structures for AR access library routines
|
||||
* #ifdef vxWorks
|
||||
* # include <ioLib.h> obtain mode definitions for VxWorks
|
||||
* #else
|
||||
* # include <sys/file.h> obtain mode definitions for SunOS
|
||||
* #endif
|
||||
* #include <sys/file.h> obtain mode definitions for SunOS
|
||||
*
|
||||
* AR_CHAN_DESC *pChanDesc; pointer to channel descriptor in chan file
|
||||
* AR_CF_DESC *pCfDesc; pointer to channel file descriptor
|
||||
@@ -70,6 +67,9 @@
|
||||
* long arCFChanPurge( pChanDesc, pStamp )
|
||||
* long arCFChanRead( pChanDesc, type, >pDbrBuf, count)
|
||||
* long arCFChanWrite( pChanDesc, pEvHandArg )
|
||||
* long arCFChanWrite_args( pChanDesc, stamp, dbfType,
|
||||
* count, pData, alStat, alSevr)
|
||||
* long arCFChanWriteByte( pArChanDesc, value )
|
||||
* long arCFChanWriteGR( pChanDesc, pEvHandArg )
|
||||
* long arCFClose( >ppCfDesc )
|
||||
* AR_CF_DESC *arCFCreate( name, maxBytes )
|
||||
@@ -100,17 +100,13 @@
|
||||
#ifndef INCLcadefh
|
||||
# include <cadef.h>
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
# include <vxWorks.h>
|
||||
# include <ioLib.h> /* for O_RDWR and O_RDONLY definitions */
|
||||
# include <stdioLib.h>
|
||||
# include <strLib.h>
|
||||
#else
|
||||
# include <stdio.h>
|
||||
# include <sys/file.h> /* for O_RDWR and O_RDONLY definitions */
|
||||
# include <strings.h>
|
||||
#ifndef INCLdb_accessh
|
||||
# include <db_access.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/file.h> /* for O_RDWR and O_RDONLY definitions */
|
||||
#include <strings.h>
|
||||
|
||||
/*+/internal------------------------------------------------------------------
|
||||
* NAME arCF_malloc/arCF_free
|
||||
@@ -869,7 +865,9 @@ TS_STAMP *pPosStamp; /* I stamp for desired data; NULL for `rewind' */
|
||||
while (1) {
|
||||
stat = arCFChanReadTs(pArChanDesc);
|
||||
if (stat != OK) {
|
||||
if ((pArChanDesc->flags & (AR_CDESC_BEGIN|AR_CDESC_INACT)) == 0) {
|
||||
if ((pArChanDesc->flags &
|
||||
(AR_CDESC_BEGIN|AR_CDESC_INACT|
|
||||
AR_CDESC_SNAP_BEGIN|AR_CDESC_SNAP_END)) == 0) {
|
||||
retStat = ERROR;
|
||||
break;
|
||||
}
|
||||
@@ -1128,6 +1126,10 @@ TS_STAMP *pKeepStamp; /* I stamp for oldest data to keep; NULL says
|
||||
* end of file
|
||||
* AR_CDESC_BEGIN indicates that a new run of data is beginning
|
||||
* for the channel
|
||||
* AR_CDESC_SNAP_BEGIN indicates that a new run of data is beginning
|
||||
* for the channel, where the run is a synchronous snapshot
|
||||
* AR_CDESC_SNAP_END indicates that the following value is the
|
||||
* last in a snapshot (may occur with AR_CDESC_SNAP_BEGIN)
|
||||
* AR_CDESC_INACT indicates that the run of data is done, because
|
||||
* the archive request was inactivated (or disabled)
|
||||
*
|
||||
@@ -1165,6 +1167,7 @@ int count; /* I array element count for caller's buffer */
|
||||
int i; /* temp for loops */
|
||||
int byte0, byteN; /* bytes from the entry */
|
||||
char *pBuf; /* temporary pointer for moving data */
|
||||
chtype recType; /* type of buffer */
|
||||
|
||||
assert(pArChanDesc != NULL);
|
||||
assert(pArChanDesc->pMIBuf != NULL);
|
||||
@@ -1228,6 +1231,27 @@ int count; /* I array element count for caller's buffer */
|
||||
ArCRShrtGr.lowWarnLim;
|
||||
pAccessBuf->gshrtval.lower_alarm_limit = ArCRShrtGr.lowAlmLim;
|
||||
break;
|
||||
case DBR_GR_LONG:
|
||||
#define ArCRLngGr ArCDChanHdr(pArChanDesc).graphics.longGr
|
||||
(void)strcpy(pAccessBuf->glngval.units, ArCRLngGr.units);
|
||||
pAccessBuf->glngval.upper_disp_limit = ArCRLngGr.upDispLim;
|
||||
pAccessBuf->glngval.lower_disp_limit = ArCRLngGr.lowDispLim;
|
||||
pAccessBuf->glngval.upper_alarm_limit = ArCRLngGr.upAlmLim;
|
||||
pAccessBuf->glngval.upper_warning_limit = ArCRLngGr.upWarnLim;
|
||||
pAccessBuf->glngval.lower_warning_limit =
|
||||
ArCRLngGr.lowWarnLim;
|
||||
pAccessBuf->glngval.lower_alarm_limit = ArCRLngGr.lowAlmLim;
|
||||
break;
|
||||
case DBR_GR_CHAR:
|
||||
#define ArCRChrGr ArCDChanHdr(pArChanDesc).graphics.shortGr
|
||||
(void)strcpy(pAccessBuf->gchrval.units, ArCRChrGr.units);
|
||||
pAccessBuf->gchrval.upper_disp_limit = ArCRChrGr.upDispLim;
|
||||
pAccessBuf->gchrval.lower_disp_limit = ArCRChrGr.lowDispLim;
|
||||
pAccessBuf->gchrval.upper_alarm_limit = ArCRChrGr.upAlmLim;
|
||||
pAccessBuf->gchrval.upper_warning_limit = ArCRChrGr.upWarnLim;
|
||||
pAccessBuf->gchrval.lower_warning_limit = ArCRChrGr.lowWarnLim;
|
||||
pAccessBuf->gchrval.lower_alarm_limit = ArCRChrGr.lowAlmLim;
|
||||
break;
|
||||
case DBR_GR_FLOAT:
|
||||
#define ArCRFltGr ArCDChanHdr(pArChanDesc).graphics.floatGr
|
||||
pAccessBuf->gfltval.precision = ArCRFltGr.precision;
|
||||
@@ -1239,6 +1263,17 @@ int count; /* I array element count for caller's buffer */
|
||||
pAccessBuf->gfltval.lower_warning_limit = ArCRFltGr.lowWarnLim;
|
||||
pAccessBuf->gfltval.lower_alarm_limit = ArCRFltGr.lowAlmLim;
|
||||
break;
|
||||
case DBR_GR_DOUBLE:
|
||||
#define ArCRDblGr ArCDChanHdr(pArChanDesc).graphics.doubleGr
|
||||
pAccessBuf->gdblval.precision = ArCRDblGr.precision;
|
||||
(void)strcpy(pAccessBuf->gdblval.units, ArCRDblGr.units);
|
||||
pAccessBuf->gdblval.upper_disp_limit = ArCRDblGr.upDispLim;
|
||||
pAccessBuf->gdblval.lower_disp_limit = ArCRDblGr.lowDispLim;
|
||||
pAccessBuf->gdblval.upper_alarm_limit = ArCRDblGr.upAlmLim;
|
||||
pAccessBuf->gdblval.upper_warning_limit = ArCRDblGr.upWarnLim;
|
||||
pAccessBuf->gdblval.lower_warning_limit = ArCRDblGr.lowWarnLim;
|
||||
pAccessBuf->gdblval.lower_alarm_limit = ArCRDblGr.lowAlmLim;
|
||||
break;
|
||||
case DBR_GR_ENUM:
|
||||
#define ArCREnmGr ArCDChanHdr(pArChanDesc).graphics.enumGr.pGRBuf
|
||||
pAccessBuf->genmval.no_str = ArCREnmGr->numStrings;
|
||||
@@ -1265,222 +1300,21 @@ int count; /* I array element count for caller's buffer */
|
||||
retStat = ERROR;
|
||||
}
|
||||
else {
|
||||
if (ArCDChanHdr(pArChanDesc).chanType == DBF_STRING) {
|
||||
if (type == DBR_STRING)
|
||||
pBuf = ((char *)pAccessBuf->strval) - 1;
|
||||
else if (type == DBR_STS_STRING)
|
||||
pBuf = ((char *)pAccessBuf->sstrval.value) - 1;
|
||||
else if (type == DBR_TIME_STRING)
|
||||
pBuf = ((char *)pAccessBuf->tstrval.value) - 1;
|
||||
else if (type == DBR_GR_STRING)
|
||||
pBuf = ((char *)pAccessBuf->gstrval.value) - 1;
|
||||
else if (count <= 0)
|
||||
pBuf = NULL;
|
||||
else
|
||||
assertAlways(0);
|
||||
|
||||
/* set byte count one byte shy to allow checking status on the
|
||||
last one. This is done as a time saving measure */
|
||||
nBytes = ArCDChanHdr(pArChanDesc).elCount*db_strval_dim - 1;
|
||||
countBytes = count * db_strval_dim;
|
||||
for (i=0; i<nBytes; i++) {
|
||||
if (i<countBytes)
|
||||
*(++pBuf) = ArCRFetch;
|
||||
else
|
||||
ArCRFetch;
|
||||
}
|
||||
byteN = ArCRFetch; /* last, for status */
|
||||
if (countBytes > nBytes)
|
||||
*(++pBuf) = byteN;
|
||||
if (byteN == ERROR)
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (ArCDChanHdr(pArChanDesc).chanType == DBF_SHORT) {
|
||||
if (type == DBR_SHORT)
|
||||
pBuf = ((char *)&pAccessBuf->shrtval) - 1;
|
||||
else if (type == DBR_STS_SHORT)
|
||||
pBuf = ((char *)&pAccessBuf->sshrtval.value) - 1;
|
||||
else if (type == DBR_TIME_SHORT)
|
||||
pBuf = ((char *)&pAccessBuf->tshrtval.value) - 1;
|
||||
else if (type == DBR_GR_SHORT)
|
||||
pBuf = ((char *)&pAccessBuf->gshrtval.value) - 1;
|
||||
else if (count <= 0)
|
||||
pBuf = NULL;
|
||||
else
|
||||
assertAlways(0);
|
||||
|
||||
/* set byte count one byte shy to allow checking status on the
|
||||
last one. This is done as a time saving measure */
|
||||
nBytes = ArCDChanHdr(pArChanDesc).elCount*sizeof(short) - 1;
|
||||
countBytes = count * sizeof(short);
|
||||
for (i=0; i<nBytes; i++) {
|
||||
if (i<countBytes)
|
||||
*(++pBuf) = ArCRFetch;
|
||||
else
|
||||
ArCRFetch;
|
||||
}
|
||||
byteN = ArCRFetch; /* last, for status */
|
||||
if (countBytes > nBytes)
|
||||
*(++pBuf) = byteN;
|
||||
if (byteN == ERROR)
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (ArCDChanHdr(pArChanDesc).chanType == DBF_FLOAT) {
|
||||
if (type == DBR_FLOAT)
|
||||
pBuf = ((char *)&pAccessBuf->fltval) - 1;
|
||||
else if (type == DBR_STS_FLOAT)
|
||||
pBuf = ((char *)&pAccessBuf->sfltval.value) - 1;
|
||||
else if (type == DBR_TIME_FLOAT)
|
||||
pBuf = ((char *)&pAccessBuf->tfltval.value) - 1;
|
||||
else if (type == DBR_GR_FLOAT)
|
||||
pBuf = ((char *)&pAccessBuf->gfltval.value) - 1;
|
||||
else if (count <= 0)
|
||||
pBuf = NULL;
|
||||
else
|
||||
assertAlways(0);
|
||||
|
||||
/* set byte count one byte shy to allow checking status on the
|
||||
last one. This is done as a time saving measure */
|
||||
nBytes = ArCDChanHdr(pArChanDesc).elCount*sizeof(float) - 1;
|
||||
countBytes = count * sizeof(float);
|
||||
for (i=0; i<nBytes; i++) {
|
||||
if (i<countBytes)
|
||||
*(++pBuf) = ArCRFetch;
|
||||
else
|
||||
ArCRFetch;
|
||||
}
|
||||
byteN = ArCRFetch; /* last, for status */
|
||||
if (countBytes > nBytes)
|
||||
*(++pBuf) = byteN;
|
||||
if (byteN == ERROR)
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (ArCDChanHdr(pArChanDesc).chanType == DBF_LONG) {
|
||||
if (type == DBR_LONG)
|
||||
pBuf = ((char *)&pAccessBuf->longval) - 1;
|
||||
else if (type == DBR_STS_LONG)
|
||||
pBuf = ((char *)&pAccessBuf->slngval.value) - 1;
|
||||
else if (type == DBR_TIME_LONG)
|
||||
pBuf = ((char *)&pAccessBuf->tlngval.value) - 1;
|
||||
else if (type == DBR_GR_LONG)
|
||||
pBuf = ((char *)&pAccessBuf->glngval.value) - 1;
|
||||
else if (count <= 0)
|
||||
pBuf = NULL;
|
||||
else
|
||||
assertAlways(0);
|
||||
|
||||
/* set byte count one byte shy to allow checking status on the
|
||||
last one. This is done as a time saving measure */
|
||||
nBytes = ArCDChanHdr(pArChanDesc).elCount*sizeof(long) - 1;
|
||||
countBytes = count * sizeof(long);
|
||||
for (i=0; i<nBytes; i++) {
|
||||
if (i<countBytes)
|
||||
*(++pBuf) = ArCRFetch;
|
||||
else
|
||||
ArCRFetch;
|
||||
}
|
||||
byteN = ArCRFetch; /* last, for status */
|
||||
if (countBytes > nBytes)
|
||||
*(++pBuf) = byteN;
|
||||
if (byteN == ERROR)
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (ArCDChanHdr(pArChanDesc).chanType == DBF_DOUBLE) {
|
||||
if (type == DBR_DOUBLE)
|
||||
pBuf = ((char *)&pAccessBuf->doubleval) - 1;
|
||||
else if (type == DBR_STS_DOUBLE)
|
||||
pBuf = ((char *)&pAccessBuf->sdblval.value) - 1;
|
||||
else if (type == DBR_TIME_DOUBLE)
|
||||
pBuf = ((char *)&pAccessBuf->tdblval.value) - 1;
|
||||
else if (type == DBR_GR_DOUBLE)
|
||||
pBuf = ((char *)&pAccessBuf->gdblval.value) - 1;
|
||||
else if (count <= 0)
|
||||
pBuf = NULL;
|
||||
else
|
||||
assertAlways(0);
|
||||
|
||||
/* set byte count one byte shy to allow checking status on the
|
||||
last one. This is done as a time saving measure */
|
||||
nBytes = ArCDChanHdr(pArChanDesc).elCount*sizeof(double) - 1;
|
||||
countBytes = count * sizeof(double);
|
||||
for (i=0; i<nBytes; i++) {
|
||||
if (i<countBytes)
|
||||
*(++pBuf) = ArCRFetch;
|
||||
else
|
||||
ArCRFetch;
|
||||
}
|
||||
byteN = ArCRFetch; /* last, for status */
|
||||
if (countBytes > nBytes)
|
||||
*(++pBuf) = byteN;
|
||||
if (byteN == ERROR)
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (ArCDChanHdr(pArChanDesc).chanType == DBF_ENUM) {
|
||||
if (type == DBR_ENUM)
|
||||
pBuf = ((char *)&pAccessBuf->enmval) - 1;
|
||||
else if (type == DBR_STS_ENUM)
|
||||
pBuf = ((char *)&pAccessBuf->senmval.value) - 1;
|
||||
else if (type == DBR_TIME_ENUM)
|
||||
pBuf = ((char *)&pAccessBuf->tenmval.value) - 1;
|
||||
else if (type == DBR_GR_ENUM)
|
||||
pBuf = ((char *)&pAccessBuf->genmval.value) - 1;
|
||||
else if (count <= 0)
|
||||
pBuf = NULL;
|
||||
else
|
||||
assertAlways(0);
|
||||
|
||||
/* set byte count one byte shy to allow checking status on the
|
||||
last one. This is done as a time saving measure */
|
||||
nBytes = ArCDChanHdr(pArChanDesc).elCount*sizeof(short) - 1;
|
||||
countBytes = count * sizeof(short);
|
||||
for (i=0; i<nBytes; i++) {
|
||||
if (i<countBytes)
|
||||
*(++pBuf) = ArCRFetch;
|
||||
else
|
||||
ArCRFetch;
|
||||
}
|
||||
byteN = ArCRFetch; /* last, for status */
|
||||
if (countBytes > nBytes)
|
||||
*(++pBuf) = byteN;
|
||||
if (byteN == ERROR)
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (ArCDChanHdr(pArChanDesc).chanType == DBF_CHAR) {
|
||||
if (type == DBR_CHAR)
|
||||
pBuf = ((char *)&pAccessBuf->charval) - 1;
|
||||
else if (type == DBR_STS_CHAR)
|
||||
pBuf = ((char *)&pAccessBuf->schrval.value) - 1;
|
||||
else if (type == DBR_TIME_CHAR)
|
||||
pBuf = ((char *)&pAccessBuf->tchrval.value) - 1;
|
||||
else if (type == DBR_GR_CHAR)
|
||||
pBuf = ((char *)&pAccessBuf->gchrval.value) - 1;
|
||||
else if (count <= 0)
|
||||
pBuf = NULL;
|
||||
else
|
||||
assertAlways(0);
|
||||
|
||||
/* set byte count one byte shy to allow checking status on the
|
||||
last one. This is done as a time saving measure */
|
||||
nBytes = ArCDChanHdr(pArChanDesc).elCount*sizeof(char) - 1;
|
||||
countBytes = count * sizeof(char);
|
||||
for (i=0; i<nBytes; i++) {
|
||||
if (i<countBytes)
|
||||
*(++pBuf) = ArCRFetch;
|
||||
else
|
||||
ArCRFetch;
|
||||
}
|
||||
byteN = ArCRFetch; /* last, for status */
|
||||
if (countBytes > nBytes)
|
||||
*(++pBuf) = byteN;
|
||||
if (byteN == ERROR)
|
||||
retStat = ERROR;
|
||||
}
|
||||
else {
|
||||
/*----------------------------------------------------------------------------
|
||||
* illegal buffer type
|
||||
*---------------------------------------------------------------------------*/
|
||||
(void)fprintf(stderr, "arCFChanRead: unimplemented buffer type\n");
|
||||
assert(dbr_type_is_valid(type));
|
||||
recType = ArCDChanHdr(pArChanDesc).chanType;
|
||||
if (count <= 0) pBuf = NULL;
|
||||
else pBuf = ((char *)dbr_value_ptr(pAccessBuf, type)) - 1;
|
||||
/* set byte count one byte shy to allow checking status on the
|
||||
last one. This is done as a time saving measure */
|
||||
nBytes = ArCDChanHdr(pArChanDesc).elCount*dbr_value_size[recType] - 1;
|
||||
countBytes = count * dbr_value_size[recType];
|
||||
for (i=0; i<nBytes; i++) {
|
||||
if (i<countBytes) *(++pBuf) = ArCRFetch;
|
||||
else ArCRFetch;
|
||||
}
|
||||
byteN = ArCRFetch; /* last, for status */
|
||||
if (countBytes > nBytes) *(++pBuf) = byteN;
|
||||
if (byteN == ERROR) retStat = ERROR;
|
||||
}
|
||||
|
||||
return retStat;
|
||||
@@ -1518,7 +1352,8 @@ AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */
|
||||
|
||||
/* turn off various flags */
|
||||
pArChanDesc->flags &= ~(AR_CDESC_EOF | AR_CDESC_BEGIN | AR_CDESC_INACT |
|
||||
AR_CDESC_DISCON | AR_CDESC_SUP);
|
||||
AR_CDESC_SNAP_BEGIN | AR_CDESC_SNAP_END |
|
||||
AR_CDESC_DISCON | AR_CDESC_SUP);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* handle time stamp
|
||||
@@ -1556,6 +1391,18 @@ AR_CHAN_DESC *pArChanDesc; /* IO pointer to channel descriptor */
|
||||
pArChanDesc->flags |= AR_CDESC_BEGIN;
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (byte0 == AR_DAT_IC_SNAP_BEGIN) { /* begin snapshot */
|
||||
pArChanDesc->flags |= AR_CDESC_SNAP_BEGIN;
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (byte0 == AR_DAT_IC_SNAP_SINGLE) { /* 1 sample snapshot */
|
||||
pArChanDesc->flags |= AR_CDESC_SNAP_BEGIN | AR_CDESC_SNAP_END;
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (byte0 == AR_DAT_IC_SNAP_END) { /* end snapshot */
|
||||
pArChanDesc->flags |= AR_CDESC_SNAP_END;
|
||||
retStat = ERROR;
|
||||
}
|
||||
else if (byte0 == AR_DAT_IC_MON_INACT) { /* req inactivated */
|
||||
pArChanDesc->flags |= AR_CDESC_INACT;
|
||||
retStat = ERROR;
|
||||
@@ -1895,6 +1742,7 @@ struct event_handler_args *pArg;/* I pointer to monitor structure */
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
#undef ArString
|
||||
}
|
||||
else if (pArg->type == DBR_TIME_SHORT) {
|
||||
#define ArShort ((struct dbr_time_short *)pCaBuf)
|
||||
@@ -1904,6 +1752,7 @@ struct event_handler_args *pArg;/* I pointer to monitor structure */
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
#undef ArShort
|
||||
}
|
||||
else if (pArg->type == DBR_TIME_FLOAT) {
|
||||
#define ArFloat ((struct dbr_time_float *)pCaBuf)
|
||||
@@ -1913,6 +1762,7 @@ struct event_handler_args *pArg;/* I pointer to monitor structure */
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
#undef ArFloat
|
||||
}
|
||||
else if (pArg->type == DBR_TIME_LONG) {
|
||||
#define ArLong ((struct dbr_time_long *)pCaBuf)
|
||||
@@ -1922,6 +1772,7 @@ struct event_handler_args *pArg;/* I pointer to monitor structure */
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
#undef ArLong
|
||||
}
|
||||
else if (pArg->type == DBR_TIME_DOUBLE) {
|
||||
#define ArDouble ((struct dbr_time_double *)pCaBuf)
|
||||
@@ -1931,6 +1782,7 @@ struct event_handler_args *pArg;/* I pointer to monitor structure */
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
#undef ArDouble
|
||||
}
|
||||
else if (pArg->type == DBR_TIME_ENUM) {
|
||||
#define ArEnum ((struct dbr_time_enum *)pCaBuf)
|
||||
@@ -1940,6 +1792,7 @@ struct event_handler_args *pArg;/* I pointer to monitor structure */
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
#undef ArEnum
|
||||
}
|
||||
else if (pArg->type == DBR_TIME_CHAR) {
|
||||
#define ArChar ((struct dbr_time_char *)pCaBuf)
|
||||
@@ -1949,6 +1802,303 @@ struct event_handler_args *pArg;/* I pointer to monitor structure */
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
#undef ArChar
|
||||
}
|
||||
else
|
||||
assertAlways(0);
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* update bookkeeping information
|
||||
*
|
||||
* .lastByte
|
||||
* .modified in data buffer
|
||||
* .newestStamp in MI buffer
|
||||
* .modified in MI buffer
|
||||
*----------------------------------------------------------------------------*/
|
||||
if (pArChanDesc->pData != NULL) {
|
||||
pArChanDesc->pDataBuf->bfInfo.lastByte = pArChanDesc->pData -
|
||||
(char *)&pArChanDesc->pDataBuf->bfInfo;
|
||||
assert(pArChanDesc->pDataBuf->bfInfo.lastByte > 0);
|
||||
assert(pArChanDesc->pDataBuf->bfInfo.lastByte < 2000);
|
||||
}
|
||||
ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pDataBuf);
|
||||
ArCDChanHdr(pArChanDesc).newestSecPastEpoch =
|
||||
pArChanDesc->timeStamp.secPastEpoch;
|
||||
ArCDChanHdr(pArChanDesc).newestNsec = pArChanDesc->timeStamp.nsec;
|
||||
ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf);
|
||||
|
||||
return OK;
|
||||
error:
|
||||
return ERROR;
|
||||
#undef CW_NSEC
|
||||
#undef CW_SPE
|
||||
}
|
||||
long
|
||||
arCFChanWrite_args(pArChanDesc, stamp, dbfType, count, pData, alStat, alSevr)
|
||||
register
|
||||
AR_CHAN_DESC *pArChanDesc;/* IO pointer to channel descriptor */
|
||||
TS_STAMP stamp; /* I time stamp for data */
|
||||
chtype dbfType; /* I type of data, one of the DBF_... */
|
||||
int count; /* I element count for data */
|
||||
void *pData; /* I pointer to actual data */
|
||||
int alStat; /* I alarm status for data */
|
||||
int alSevr; /* I alarm severity for data */
|
||||
{
|
||||
#define CW_NSEC stamp.nsec
|
||||
#define CW_SPE stamp.secPastEpoch
|
||||
|
||||
int stat; /* status from calls */
|
||||
int deltaCode; /* AR_DAT_IC_TIME_xxx code for delta time */
|
||||
int deltaCount; /* count of bytes to represent delta time */
|
||||
TS_STAMP diff; /* difference between data stamp and chanDesc */
|
||||
ULONG fraction; /* fractional part of second, units vary */
|
||||
int fracCode; /* AR_DAT_IC_TIME_xxx code for delta time */
|
||||
int fracCount; /* count of bytes to represent delta time */
|
||||
register
|
||||
char *ptr; /* temp for pointer in loops */
|
||||
register
|
||||
char *ptrEnd; /* temp for pointer bound in loops */
|
||||
|
||||
assert(pArChanDesc != NULL);
|
||||
assert(pArChanDesc->pMIBuf != NULL);
|
||||
|
||||
if (count != ArCDChanHdr(pArChanDesc).elCount)
|
||||
goto error; /* ignore changed count */
|
||||
|
||||
pArChanDesc->flags &= ~AR_CDESC_SUP; /* turn off suppress */
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* time stamp handling
|
||||
*
|
||||
* (This is done 'in-line' as an optimization strategy. When done as a
|
||||
* separate routine, this used as much CPU time as all the rest of
|
||||
* arCFChanWrite() used for status and data for DBR_FLOAT.)
|
||||
*
|
||||
* NOTES
|
||||
* 1. A lot of the logic in this routine is in support of the rule that
|
||||
* when a "time item" is used, the item can't cross a block
|
||||
* boundary.
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
if (TsCmpStampsLT(&stamp, &pArChanDesc->timeStamp))
|
||||
goto error; /* ignore time running backward */
|
||||
if (ArCDDatInfo(pArChanDesc).stamp.secPastEpoch == 0) {
|
||||
/*----------------------------------------------------------------------------
|
||||
* case 1
|
||||
* this is the first item which has its beginning in this block. A
|
||||
* time stamp in the datInfo is needed; there must be enough room
|
||||
* in the block to avoid starting a new block--i.e., to hold the item
|
||||
* code for the data entry.
|
||||
*
|
||||
* Since this is the first item which has its beginning in this block,
|
||||
* datInfo.stamp must be set. The .firstByte item may also need to be set.
|
||||
*
|
||||
* This may also be the first item for the channel. If this is the case,
|
||||
* then .oldestSecPastEpoch in chanHdr needs to be set.
|
||||
*---------------------------------------------------------------------------*/
|
||||
if (pArChanDesc->remainCount < 1) {
|
||||
if (ArCWFlushAndStore(AR_DAT_IC_VAL_STAT ) != OK)
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK)
|
||||
goto error;
|
||||
}
|
||||
if (pArChanDesc->pDataBuf->bfInfo.firstByte == 0) {
|
||||
pArChanDesc->pDataBuf->bfInfo.firstByte = pArChanDesc->pData -
|
||||
(char *)(&pArChanDesc->pDataBuf->bfInfo);
|
||||
}
|
||||
ArCDDatInfo(pArChanDesc).stamp = stamp;
|
||||
ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pIndexBuf);
|
||||
|
||||
if (ArCDChanHdr(pArChanDesc).oldestSecPastEpoch == 0) {
|
||||
ArCDChanHdr(pArChanDesc).oldestSecPastEpoch = CW_SPE;
|
||||
ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pMIBuf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*----------------------------------------------------------------------------
|
||||
* not first item beginning in this block. Figure out first what's
|
||||
* going to be needed to handle the time stamp. The questions are:
|
||||
* o without loss of significance, what type of delta time item is
|
||||
* required? For that type of delta time item, is the delta time
|
||||
* less than the maximum? If so, is there enough space left in the
|
||||
* block to hold the delta time item and the first byte of a data item?
|
||||
* o if a delta time item can't be used or if there isn't enough room
|
||||
* in the block, then a full time stamp is needed.
|
||||
*---------------------------------------------------------------------------*/
|
||||
TsDiffAsStamp(&diff, &stamp, &pArChanDesc->timeStamp);
|
||||
if (diff.nsec % 1000000 == 0 && diff.secPastEpoch < 30 &&
|
||||
pArChanDesc->remainCount >= 2+1) {
|
||||
/*----------------------------------------------------------------------------
|
||||
* case 2
|
||||
* the change can be represented as a delta milli-second (and, there is
|
||||
* room enough to store the item and the first byte of value)
|
||||
*----------------------------------------------------------------------------*/
|
||||
fraction = diff.secPastEpoch*1000 + diff.nsec/1000000;
|
||||
(void)ArCWStore( fraction>> 8 );
|
||||
(void)ArCWStore( fraction );
|
||||
if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK)
|
||||
goto error;
|
||||
}
|
||||
else if (diff.nsec % 1000 == 0 && diff.secPastEpoch < 15 &&
|
||||
pArChanDesc->remainCount >= 4+1) {
|
||||
/*----------------------------------------------------------------------------
|
||||
* case 3
|
||||
* the change can be represented as a delta micro-second (and, there is
|
||||
* room enough to store the item and the first byte of value)
|
||||
*----------------------------------------------------------------------------*/
|
||||
fraction = diff.secPastEpoch*1000000 + diff.nsec/1000;
|
||||
(void)ArCWStore( AR_DAT_IC_TIME_USEC );
|
||||
(void)ArCWStore( fraction>>16 );
|
||||
(void)ArCWStore( fraction>> 8 );
|
||||
(void)ArCWStore( fraction );
|
||||
if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK)
|
||||
goto error;
|
||||
}
|
||||
else if (diff.secPastEpoch < 4 && pArChanDesc->remainCount >= 5+1) {
|
||||
/*----------------------------------------------------------------------------
|
||||
* case 4
|
||||
* the change can be represented as a delta nano-second (and, there is
|
||||
* room enough to store the item and the first byte of value)
|
||||
*----------------------------------------------------------------------------*/
|
||||
fraction = diff.secPastEpoch*1000000000 + diff.nsec;
|
||||
(void)ArCWStore( AR_DAT_IC_TIME_NSEC );
|
||||
(void)ArCWStore( fraction>>24 );
|
||||
(void)ArCWStore( fraction>>16 );
|
||||
(void)ArCWStore( fraction>> 8 );
|
||||
(void)ArCWStore( fraction );
|
||||
if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK)
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
/*----------------------------------------------------------------------------
|
||||
* case 5
|
||||
* the change is either too large to be accomodated by a delta time
|
||||
* item or else there isn't enough room left in the block for a delta
|
||||
* time item followed by the first byte of a data item. If there isn't
|
||||
* enough space left in the block for the required items, a new block
|
||||
* will be started.
|
||||
*---------------------------------------------------------------------------*/
|
||||
deltaCode = AR_DAT_IC_TIME_STAMP; /* full time stamp needed */
|
||||
deltaCount = 5+1; /* 5 for stamp, 1 for value code */
|
||||
if (CW_NSEC == 0) {
|
||||
fracCount = 2;
|
||||
fracCode = AR_DAT_IC_TIME_MSEC; /* delta msec */
|
||||
/* don't add to deltaCount, since this item is optional */
|
||||
fraction = 0;
|
||||
}
|
||||
else if (CW_NSEC % 1000000 == 0) {
|
||||
fracCount = 2;
|
||||
fracCode = AR_DAT_IC_TIME_MSEC; /* delta msec */
|
||||
deltaCount += fracCount;
|
||||
fraction = CW_NSEC / 1000000;
|
||||
}
|
||||
else if (CW_NSEC % 1000 == 0) {
|
||||
fracCount = 4;
|
||||
fracCode = AR_DAT_IC_TIME_USEC; /* delta usec */
|
||||
deltaCount += fracCount;
|
||||
fraction = CW_NSEC / 1000;
|
||||
}
|
||||
else {
|
||||
fracCount = 5;
|
||||
fracCode = AR_DAT_IC_TIME_NSEC; /* delta nsec */
|
||||
deltaCount += fracCount;
|
||||
fraction = CW_NSEC;
|
||||
}
|
||||
|
||||
if (pArChanDesc->remainCount < deltaCount) {
|
||||
if (ArCWFlushAndStore(AR_DAT_IC_VAL_STAT ) != OK)
|
||||
goto error;
|
||||
pArChanDesc->pDataBuf->bfInfo.firstByte = pArChanDesc->pData -
|
||||
(char *)(&pArChanDesc->pDataBuf->bfInfo);
|
||||
ArCDDatInfo(pArChanDesc).stamp = stamp;
|
||||
ArCFModifySet(pArChanDesc->pArCfDesc, pArChanDesc->pIndexBuf);
|
||||
}
|
||||
else {
|
||||
(void)ArCWStore(deltaCode );
|
||||
(void)ArCWStore(CW_SPE >>24 );
|
||||
(void)ArCWStore(CW_SPE >>16 );
|
||||
(void)ArCWStore(CW_SPE >> 8 );
|
||||
(void)ArCWStore(CW_SPE );
|
||||
if (fraction != 0) {
|
||||
if (fracCode != AR_DAT_IC_TIME_MSEC) {
|
||||
(void)ArCWStore(fracCode );
|
||||
if (fracCode == AR_DAT_IC_TIME_NSEC)
|
||||
(void)ArCWStore(fraction>>24 );
|
||||
(void)ArCWStore(fraction>>16 );
|
||||
}
|
||||
(void)ArCWStore( fraction>> 8 );
|
||||
(void)ArCWStore( fraction );
|
||||
}
|
||||
if (ArCWStore( AR_DAT_IC_VAL_STAT ) != OK)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
pArChanDesc->timeStamp = stamp;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* now store the status and data. The code above has already stored
|
||||
* an AR_DAT_IC_VAL_STAT item code in the file.
|
||||
*----------------------------------------------------------------------------*/
|
||||
(void)ArCWStore(alStat);
|
||||
(void)ArCWStore(alSevr);
|
||||
if (dbfType == DBF_STRING) {
|
||||
assert(ArCDChanHdr(pArChanDesc).chanType == DBF_STRING);
|
||||
ptr = (char *)(struct dbf_string *)pData;
|
||||
ptrEnd = ptr + count*db_strval_dim - 1;
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
}
|
||||
else if (dbfType == DBF_SHORT) {
|
||||
assert(ArCDChanHdr(pArChanDesc).chanType == DBF_SHORT);
|
||||
ptr = (char *)(struct dbf_short *)pData;
|
||||
ptrEnd = ptr + count * sizeof(short) - 1;
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
}
|
||||
else if (dbfType == DBF_FLOAT) {
|
||||
assert(ArCDChanHdr(pArChanDesc).chanType == DBF_FLOAT);
|
||||
ptr = (char *)(struct dbf_float *)pData;
|
||||
ptrEnd = ptr + count * sizeof(float) - 1;
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
}
|
||||
else if (dbfType == DBF_LONG) {
|
||||
assert(ArCDChanHdr(pArChanDesc).chanType == DBF_LONG);
|
||||
ptr = (char *)(struct dbf_long *)pData;
|
||||
ptrEnd = ptr + count * sizeof(long) - 1;
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
}
|
||||
else if (dbfType == DBF_DOUBLE) {
|
||||
assert(ArCDChanHdr(pArChanDesc).chanType == DBF_DOUBLE);
|
||||
ptr = (char *)(struct dbf_double *)pData;
|
||||
ptrEnd = ptr + count * sizeof(double) - 1;
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
}
|
||||
else if (dbfType == DBF_ENUM) {
|
||||
assert(ArCDChanHdr(pArChanDesc).chanType == DBF_ENUM);
|
||||
ptr = (char *)(struct dbf_enum *)pData;
|
||||
ptrEnd = ptr + count * sizeof(short) - 1;
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
}
|
||||
else if (dbfType == DBF_CHAR) {
|
||||
assert(ArCDChanHdr(pArChanDesc).chanType == DBF_CHAR);
|
||||
ptr = (char *)(struct dbf_char *)pData;
|
||||
ptrEnd = ptr + count * sizeof(char) - 1;
|
||||
while (ptr < ptrEnd)
|
||||
(void)ArCWStore(*ptr++);
|
||||
if (ArCWStore(*ptr++) != OK) goto error;
|
||||
}
|
||||
else
|
||||
assertAlways(0);
|
||||
@@ -1976,6 +2126,7 @@ struct event_handler_args *pArg;/* I pointer to monitor structure */
|
||||
return OK;
|
||||
error:
|
||||
return ERROR;
|
||||
|
||||
}
|
||||
|
||||
/*+/subr**********************************************************************
|
||||
@@ -2617,11 +2768,7 @@ AR_CF_DESC *pArCfDesc; /* I ptr to channel file descriptor */
|
||||
if (MIBuf.chanHdr[i].name[0] != '\0') {
|
||||
assertAlways(strcmp(pMIBuf->chanHdr[i].name,
|
||||
MIBuf.chanHdr[i].name) == 0);
|
||||
assertAlways(pMIBuf->chanHdr[i].indexHead ==
|
||||
MIBuf.chanHdr[i].indexHead);
|
||||
pMIBuf->chanHdr[i].indexTail = MIBuf.chanHdr[i].indexTail;
|
||||
assertAlways(pMIBuf->chanHdr[i].oldestSecPastEpoch ==
|
||||
MIBuf.chanHdr[i].oldestSecPastEpoch);
|
||||
pMIBuf->chanHdr[i].newestSecPastEpoch =
|
||||
MIBuf.chanHdr[i].newestSecPastEpoch;
|
||||
pMIBuf->chanHdr[i].newestNsec =
|
||||
|
||||
Reference in New Issue
Block a user