init notmative types repo, which is moved from alphaCPP repo

This commit is contained in:
Guobao Shen
2012-07-16 10:01:32 -04:00
commit 7facd19fb1
25 changed files with 3678 additions and 0 deletions

22
src/Makefile Normal file
View File

@@ -0,0 +1,22 @@
TOP = ..
include $(TOP)/configure/CONFIG
SRC = $(TOP)/src/
SRC_DIRS += $(SRC)/nt
INC += nt.h
INC += ntfield.h
INC += ntnameValue.h
INC += nttable.h
LIBSRCS += ntfield.cpp
LIBSRCS += ntnameValue.cpp
LIBSRCS += nttable.cpp
LIBRARY=nt
nt_LIBS += pvData Com
include $(TOP)/configure/RULES

15
src/nt/nt.h Normal file
View File

@@ -0,0 +1,15 @@
/* nt.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NT_H
#define NT_H
#include <pv/ntfield.h>
#include <pv/ntnameValue.h>
#include <pv/nttable.h>
#endif /* NT_H */

339
src/nt/ntfield.cpp Normal file
View File

@@ -0,0 +1,339 @@
/* ntArgument.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <pv/lock.h>
#include <pv/ntfield.h>
namespace epics { namespace pvData {
NTField *NTField::get()
{
static Mutex mutex;
static NTField *ntstructureField = 0;
Lock xx(mutex);
if(ntstructureField==0) ntstructureField = new NTField();
return ntstructureField;
}
NTField::NTField()
: fieldCreate(getFieldCreate()),
standardField(getStandardField())
{
}
bool NTField::isEnumerated(FieldConstPtr field)
{
if(field->getType()!=structure) return false;
const Structure *st = static_cast<const Structure *>(field.get());
FieldConstPtrArray fields = st->getFields();
int n = st->getNumberFields();
if(n!=2) return false;
FieldConstPtr f = fields[0];
if(f->getFieldName().compare("index")!=0) return false;
if(f->getType()!=scalar) return false;
const Scalar* s = static_cast<const Scalar*>(f.get());
if(s->getScalarType()!=pvInt) return false;
f = fields[1];
if(f->getFieldName().compare("choices")!=0) return false;
if(f->getType()!=scalarArray) return false;
const ScalarArray* sa = static_cast<const ScalarArray*>(f.get());
if(sa->getElementType()!=pvString) return false;
return true;
}
bool NTField::isTimeStamp(FieldConstPtr field)
{
if(field->getType()!=structure) return false;
const Structure *st = static_cast<const Structure *>(field.get());
if(field->getFieldName().compare("timeStamp")!=0) return false;
FieldConstPtrArray fields = st->getFields();
int n = st->getNumberFields();
if(n!=3) return false;
FieldConstPtr f = fields[0];
if(f->getFieldName().compare("secondsPastEpoch")!=0) return false;
if(f->getType()!=scalar) return false;
const Scalar* s = static_cast<const Scalar*>(f.get());
if(s->getScalarType()!=pvLong) return false;
f = fields[1];
if(f->getFieldName().compare("nanoSeconds")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_cast<const Scalar*>(f.get());
if(s->getScalarType()!=pvInt) return false;
f = fields[2];
if(f->getFieldName().compare("userTag")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_cast<const Scalar*>(f.get());
if(s->getScalarType()!=pvInt) return false;
return true;
}
bool NTField::isAlarm(FieldConstPtr field)
{
if(field->getType()!=structure) return false;
const Structure *st = static_cast<const Structure *>(field.get());
if(field->getFieldName().compare("alarm")!=0) return false;
FieldConstPtrArray fields = st->getFields();
int n = st->getNumberFields();
if(n!=3) return false;
FieldConstPtr f = fields[0];
if(f->getFieldName().compare("severity")!=0) return false;
if(f->getType()!=scalar) return false;
const Scalar* s = static_cast<const Scalar*>(f.get());
if(s->getScalarType()!=pvInt) return false;
f = fields[1];
if(f->getFieldName().compare("status")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_cast<const Scalar*>(f.get());
if(s->getScalarType()!=pvInt) return false;
f = fields[2];
if(f->getFieldName().compare("message")!=0) return false;
if(f->getType()!=scalar) return false;
s = static_cast<const Scalar*>(f.get());
if(s->getScalarType()!=pvString) return false;
return true;
}
bool NTField::isDisplay(FieldConstPtr field)
{
if(field->getType()!=structure) return false;
const Structure *st = static_cast<const Structure *>(field.get());
if(field->getFieldName().compare("display")!=0) return false;
FieldConstPtrArray fields = st->getFields();
int n = st->getNumberFields();
if(n!=4) return false;
// look at limit first
FieldConstPtr f = fields[3];
if(f->getFieldName().compare("limit")!=0) return false;
if(f->getType()!=structure) return false;
const Structure* s = static_cast<const Structure*>(f.get());
FieldConstPtrArray subfields = s->getFields();
n = s->getNumberFields();
if(n!=2) return false;
f = subfields[0];
if(f->getFieldName().compare("low")!=0) return false;
if(f->getType()!=scalar) return false;
const Scalar* sc = static_cast<const Scalar*>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
f = subfields[1];
if(f->getFieldName().compare("high")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar*>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
f = fields[0];
if(f->getFieldName().compare("description")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar*>(f.get());
if(sc->getScalarType()!=pvString) return false;
f = fields[1];
if(f->getFieldName().compare("format")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar*>(f.get());
if(sc->getScalarType()!=pvString) return false;
f = fields[2];
if(f->getFieldName().compare("units")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar*>(f.get());
if(sc->getScalarType()!=pvString) return false;
return true;
}
bool NTField::isAlarmLimit(FieldConstPtr field)
{
if(field->getType()!=structure) return false;
const Structure *st = static_cast<const Structure *>(field.get());
if(field->getFieldName().compare("alarmLimit")!=0) return false;
FieldConstPtrArray fields = st->getFields();
int n = st->getNumberFields();
if(n!=4) return false;
FieldConstPtr f = fields[0];
if(f->getFieldName().compare("highAlarm")!=0) return false;
if(f->getType()!=scalar) return false;
const Scalar *sc = static_cast<const Scalar *>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
f = fields[1];
if(f->getFieldName().compare("highWarning")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar *>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
f = fields[2];
if(f->getFieldName().compare("lowWarning")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar *>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
f = fields[3];
if(f->getFieldName().compare("lowAlarm")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar *>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
return true;
}
bool NTField::isControl(FieldConstPtr field)
{
if(field->getType()!=structure) return false;
const Structure *st = static_cast<const Structure *>(field.get());
if(field->getFieldName().compare("control")!=0) return false;
FieldConstPtrArray fields = st->getFields();
int n = st->getNumberFields();
if(n!=2) return false;
FieldConstPtr f = fields[1];
if(f->getFieldName().compare("minStep")!=0) return false;
if(f->getType()!=scalar) return false;
const Scalar* sc = static_cast<const Scalar*>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
f = fields[0];
if(f->getFieldName().compare("limit")!=0) return false;
if(f->getType()!=structure) return false;
const Structure* s = static_cast<const Structure*>(f.get());
fields = s->getFields();
n = s->getNumberFields();
if(n!=2) return false;
f = fields[0];
if(f->getFieldName().compare("low")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar*>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
f = fields[1];
if(f->getFieldName().compare("high")!=0) return false;
if(f->getType()!=scalar) return false;
sc = static_cast<const Scalar*>(f.get());
if(sc->getScalarType()!=pvDouble) return false;
return true;
}
StructureConstPtr NTField::createEnumerated(String fieldName)
{
return standardField->enumerated(fieldName);
}
StructureConstPtr NTField::createTimeStamp()
{
return standardField->timeStamp();
}
StructureConstPtr NTField::createAlarm()
{
return standardField->alarm();
}
StructureConstPtr NTField::createDisplay()
{
return standardField->display();
}
StructureConstPtr NTField::createAlarmLimit()
{
int numFields = 4;
FieldConstPtrArray fields = new FieldConstPtr[numFields];
fields[0] = fieldCreate->createScalar(String("highAlarm"),pvDouble);
fields[1] = fieldCreate->createScalar(String("highWarning"),pvDouble);
fields[2] = fieldCreate->createScalar(String("lowWarning"),pvDouble);
fields[3] = fieldCreate->createScalar(String("lowAlarm"),pvDouble);
return fieldCreate->createStructure(String("alarmLimit"),numFields,fields);
}
StructureConstPtr NTField::createControl()
{
return standardField->control();
}
StructureArrayConstPtr NTField::createEnumeratedArray(String fieldName)
{
StructureConstPtr st = createEnumerated(fieldName);
return fieldCreate->createStructureArray(fieldName,st);
}
StructureArrayConstPtr NTField::createTimeStampArray(String fieldName)
{
StructureConstPtr st = createTimeStamp();
return fieldCreate->createStructureArray(fieldName,st);
}
StructureArrayConstPtr NTField::createAlarmArray(String fieldName)
{
StructureConstPtr st = createAlarm();
return fieldCreate->createStructureArray(fieldName,st);
}
PVNTField *PVNTField::get()
{
static Mutex mutex;
static PVNTField *pvntstructureField = 0;
Lock xx(mutex);
if(pvntstructureField==0) pvntstructureField = new PVNTField();
return pvntstructureField;
}
PVNTField::PVNTField()
: pvDataCreate(getPVDataCreate()),
standardPVField(getStandardPVField()),
ntstructureField(NTField::get())
{
}
PVStructurePtr PVNTField::createEnumerated(
PVStructurePtr parent,
String fieldName,
StringArray choices,
int numberChoices)
{
return standardPVField->enumerated(parent,fieldName,choices,numberChoices);
}
PVStructurePtr PVNTField::createTimeStamp(PVStructurePtr parent)
{
return standardPVField->timeStamp(parent);
}
PVStructurePtr PVNTField::createAlarm(PVStructurePtr parent)
{
return standardPVField->alarm(parent);
}
PVStructurePtr PVNTField::createDisplay(PVStructurePtr parent)
{
return standardPVField->display(parent);
}
PVStructurePtr PVNTField::createAlarmLimit(PVStructurePtr parent)
{
StructureConstPtr structure = NTField::get()->createAlarmLimit();
return pvDataCreate->createPVStructure(parent,structure);
}
PVStructurePtr PVNTField::createControl(PVStructurePtr parent)
{
return standardPVField->control(parent);
}
PVStructureArray *PVNTField::createEnumeratedArray(
PVStructurePtr parent,String fieldName)
{
StructureArrayConstPtr sa = ntstructureField->createEnumeratedArray(fieldName);
return pvDataCreate->createPVStructureArray(parent,sa);
}
PVStructureArray *PVNTField::createTimeStampArray(
PVStructurePtr parent,String fieldName)
{
StructureArrayConstPtr sa = ntstructureField->createTimeStampArray(fieldName);
return pvDataCreate->createPVStructureArray(parent,sa);
}
PVStructureArray *PVNTField::createAlarmArray(
PVStructurePtr parent,String fieldName)
{
StructureArrayConstPtr sa = ntstructureField->createAlarmArray(fieldName);
return pvDataCreate->createPVStructureArray(parent,sa);
}
}}

221
src/nt/ntfield.h Normal file
View File

@@ -0,0 +1,221 @@
/* ntfield.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTFIELD_H
#define NTFIELD_H
#include <cstdarg>
#include <pv/standardField.h>
#include <pv/standardPVField.h>
#include <pv/alarm.h>
#include <pv/pvAlarm.h>
#include <pv/timeStamp.h>
#include <pv/pvTimeStamp.h>
namespace epics { namespace pvData {
/**
* Convenience Class for introspection fields of a Normative Type
* @author mrk
*
*/
class NTField: NoDefaultMethods {
public:
/**
* get the single implementation of this class.
* @return the implementation
*/
static NTField * get();
/**
* destructor
*/
~NTField() {}
/**
* Is field an enumerated structure.
* @param field The field to test.
* @return (false,true) if field (is not,is) an enumerated structure.
*/
bool isEnumerated(FieldConstPtr field);
/**
* Is field a timeStamp structure.
* @param field The field to test.
* @return (false,true) if field (is not,is) a timeStamp structure.
*/
bool isTimeStamp(FieldConstPtr field);
/**
* Is field an alarm structure.
* @param field The field to test.
* @return (false,true) if field (is not,is) an alarm structure.
*/
bool isAlarm(FieldConstPtr field);
/**
* Is field a display structure.
* @param field The field to test.
* @return (false,true) if field (is not,is) a display structure.
*/
bool isDisplay(FieldConstPtr field);
/**
* Is field an alarmLimit structure.
* @param field The field to test.
* @return (false,true) if field (is not,is) an alarmLimit structure.
*/
bool isAlarmLimit(FieldConstPtr field);
/**
* Is field a control structure.
* @param field The field to test.
* @return (false,true) if field (is not,is) a control structure.
*/
bool isControl(FieldConstPtr field);
/**
* Create an enumerated structure.
* @param fieldName The fieldName for the structure.
* @return an enumerated structure.
*/
StructureConstPtr createEnumerated(String fieldName);
/**
* Create a timeStamp structure.
* @return a timeStamp structure.
*/
StructureConstPtr createTimeStamp();
/**
* Create an alarm structure.
* @return an alarm structure.
*/
StructureConstPtr createAlarm();
/**
* Create a display structure.
* @return a displayalarm structure.
*/
StructureConstPtr createDisplay();
/**
* Create an alarmLimit structure.
* @return an alarmLimit structure.
*/
StructureConstPtr createAlarmLimit();
/**
* Create a control structure.
* @return a control structure.
*/
StructureConstPtr createControl();
/**
* Create an array of enumerated structures.
* @param fieldName The fieldName for the array.
* @return an array of enumerated structures.
*/
StructureArrayConstPtr createEnumeratedArray(String fieldName);
/**
* Create an array of timeStamp structures.
* @param fieldName The fieldName for the array.
* @return an array of timeStamp structures.
*/
StructureArrayConstPtr createTimeStampArray(String fieldName);
/**
* Create an array of alarm structures.
* @param fieldName The fieldName for the array.
* @return an array of alarm structures.
*/
StructureArrayConstPtr createAlarmArray(String fieldName);
private:
NTField();
FieldCreate *fieldCreate;
StandardField *standardField;
};
/**
* Convenience Class for data fields of a Normative Type
* @author mrk
*
*/
class PVNTField: NoDefaultMethods {
public:
/**
* get the single implementation of this class.
* @return the implementation
*/
static PVNTField * get();
/**
* destructor
*/
~PVNTField() {}
/**
* Create an enumerated PVStructure.
* @param parent The parent structure.
* @param fieldName The fieldName for the structure.
* @param choices The array of choices.
* @param numberChoices The number of choices.
* @return an enumerated PVStructure..
*/
PVStructurePtr createEnumerated(
PVStructurePtr parent,
String fieldName,
StringArray choices,
int numberChoices);
/**
* Create a timeStamp PVStructure.
* @param parent The parent structure.
* @return a timeStamp PVStructure..
*/
PVStructurePtr createTimeStamp(PVStructurePtr parent);
/**
* Create an alarm PVStructure.
* @param parent The parent structure.
* @return an alarm PVStructure..
*/
PVStructurePtr createAlarm(PVStructurePtr parent);
/**
* Create a display PVStructure.
* @param parent The parent structure.
* @return a display PVStructure..
*/
PVStructurePtr createDisplay(PVStructurePtr parent);
/**
* Create an alarmLimit PVStructure.
* @param parent The parent structure.
* @return an alarmLimit PVStructure..
*/
PVStructurePtr createAlarmLimit(PVStructurePtr parent);
/**
* Create a control PVStructure.
* @param parent The parent structure.
* @return a control PVStructure..
*/
PVStructurePtr createControl(PVStructurePtr parent);
/**
* Create an enumerated PVStructureArray.
* @param parent The parent structure.
* @param fieldName The fieldName for the structure.
* @return an enumerated PVStructureArray..
*/
PVStructureArray * createEnumeratedArray(
PVStructurePtr parent,String fieldName);
/**
* Create a timeStamp PVStructureArray.
* @param parent The parent structure.
* @param fieldName The fieldName for the structure.
* @return a timeStamp PVStructureArray
*/
PVStructureArray * createTimeStampArray(
PVStructurePtr parent,String fieldName);
/**
* Create an alarm PVStructureArray.
* @param parent The parent structure.
* @param fieldName The fieldName for the structure.
* @return an alarm PVStructureArray..
*/
PVStructureArray * createAlarmArray(
PVStructurePtr parent,String fieldName);
private:
PVNTField();
PVDataCreate *pvDataCreate;
StandardPVField *standardPVField;
NTField *ntstructureField;
};
}}
#endif /* NTFIELD_H */

129
src/nt/ntnameValue.cpp Normal file
View File

@@ -0,0 +1,129 @@
/* ntnameValue.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <pv/ntnameValue.h>
namespace epics { namespace pvData {
using std::tr1::static_pointer_cast;
bool NTNameValue::isNTNameValue(PVStructurePtr pvStructure)
{
String name = pvStructure->getField()->getFieldName();
if(name.compare("NTNameValue")!=0) return false;
PVFieldPtr pvField = pvStructure->getSubField("names");
if(pvField==0) return false;
FieldConstPtr field = pvField->getField();
if(field->getType()!=scalarArray) return false;
ScalarArrayConstPtr pscalarArray = static_pointer_cast<const ScalarArray>(field);
if(pscalarArray->getElementType()!=pvString) return false;
pvField = pvStructure->getSubField("values");
if(pvField==0) return false;
field = pvField->getField();
if(field->getType()!=scalarArray) return false;
pscalarArray = static_pointer_cast<const ScalarArray>(field);
if(pscalarArray->getElementType()!=pvString) return false;
return true;
}
PVStructure::shared_pointer NTNameValue::create(
bool hasFunction,bool hasTimeStamp, bool hasAlarm)
{
StandardField *standardField = getStandardField();
int nfields = 2;
if(hasFunction) nfields++;
if(hasTimeStamp) nfields++;
if(hasAlarm) nfields++;
FieldCreate *fieldCreate = getFieldCreate();
PVDataCreate *pvDataCreate = getPVDataCreate();
FieldConstPtrArray fields = new FieldConstPtr[nfields];
fields[0] = fieldCreate->createScalarArray("names",pvString);
fields[1] = fieldCreate->createScalarArray("values",pvString);
int ind = 2;
if(hasFunction) {
fields[ind++] = fieldCreate->createScalar(String("function"),pvString);
}
if(hasTimeStamp) {
fields[ind++] = standardField->timeStamp();
}
if(hasAlarm) {
fields[ind++] = standardField->alarm();
}
return PVStructure::shared_pointer(
pvDataCreate->createPVStructure(0,"NTNameValue",ind,fields));
}
NTNameValue::NTNameValue(PVStructure::shared_pointer const & pvStructure)
: pvNTNameValue(pvStructure),
pvFunction(0),
pvTimeStamp(0),
pvAlarm(0),
pvNames(0),
pvValues(0)
{
NTField *ntfield = NTField::get();
String name = pvStructure->getField()->getFieldName();
if(name.compare("NTNameValue")!=0) {
throw std::invalid_argument(
"pvArgument does not have name NTNameValue");
}
PVArray * pvArray = pvStructure->getScalarArrayField("names",pvString);
if(pvArray==0) {
throw std::invalid_argument(
"pvArgument does not have a string array field names");
}
pvNames = static_cast<PVStringArray *>(pvArray);
pvArray = pvStructure->getScalarArrayField("values",pvString);
if(pvArray==0) {
throw std::invalid_argument(
"pvArgument does not have a string array field values");
}
pvValues = static_cast<PVStringArray *>(pvArray);
PVFieldPtr pvField = pvStructure->getSubField("function");
if(pvField!=0) {
pvFunction = pvStructure->getStringField("function");
}
pvField = pvStructure->getSubField("timeStamp");
if(pvField!=0 && ntfield->isTimeStamp(pvField->getField())) {
pvTimeStamp = static_cast<PVStructure *>(pvField);
}
pvField = pvStructure->getSubField("alarm");
if(pvField!=0 && ntfield->isAlarm(pvField->getField())) {
pvAlarm = static_cast<PVStructure *>(pvField);
}
}
NTNameValue::~NTNameValue()
{
}
PVString * NTNameValue::getFunction()
{
return pvFunction;
}
void NTNameValue::attachTimeStamp(PVTimeStamp &pvTimeStamp)
{
if(this->pvTimeStamp==0) return;
pvTimeStamp.attach(this->pvTimeStamp);
}
void NTNameValue::attachAlarm(PVAlarm &pvAlarm)
{
if(this->pvAlarm==0) return;
pvAlarm.attach(this->pvAlarm);
}
PVStringArray * NTNameValue::getNames() {
return pvNames;
}
PVStringArray * NTNameValue::getValues() {
return pvValues;
}
}}

101
src/nt/ntnameValue.h Normal file
View File

@@ -0,0 +1,101 @@
/* ntnameValue.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTNAMEVALUE_H
#define NTNAMEVALUE_H
#include <pv/ntfield.h>
namespace epics { namespace pvData {
/**
* Convenience Class for NTNameValue
* @author mrk
*
*/
class NTNameValue
{
public:
POINTER_DEFINITIONS(NTNameValue);
/**
* Is the pvStructure an NTNameValue.
* @param pvStructure The pvStructure to test.
* @return (false,true) if (is not, is) an NTNameValue.
*/
static bool isNTNameValue(PVStructurePtr pvStructure);
/**
* Create an NTNameValue pvStructure.
* @param hasFunction Create a PVString field named function.
* @param hasTimeStamp Create a timeStamp structure field.
* @param hasAlarm Create an alarm structure field.
* @return a NTNameValue pvStructure.
*/
static PVStructure::shared_pointer create(
bool hasFunction,bool hasTimeStamp, bool hasAlarm);
/**
* Constructor
* @param pvStructure The pvStructure to which to attach.
* @return A NTNameValue that is attached to the pvStructure
*/
NTNameValue(PVStructure::shared_pointer const & pvStructure);
/**
* Destructor
*/
~NTNameValue();
/**
* Get the function field.
* @return The pvString or null if no function field.
*/
PVString* getFunction();
/**
* Attach a pvTimeStamp.
* @param pvTimeStamp The pvTimeStamp that will be attached.
* Does nothing if no timeStamp
*/
void attachTimeStamp(PVTimeStamp &pvTimeStamp);
/**
* Attach an pvAlarm.
* @param pvAlarm The pvAlarm that will be attached.
* Does nothing if no alarm
*/
void attachAlarm(PVAlarm &pvAlarm);
/**
* Get the pvStructure.
* @return PVStructurePtr.
*/
PVStructurePtr getPVStructure(){return pvNTNameValue.get();}
/**
* Get the timeStamp.
* @return PVStructurePtr which may be null.
*/
PVStructurePtr getTimeStamp(){return pvTimeStamp;}
/**
* Get the alarm.
* @return PVStructurePtr which may be null.
*/
PVStructurePtr getAlarm() {return pvAlarm;}
/**
* Get the string array on names.
* @return The array of names.
*/
PVStringArray *getNames();
/**
* Get the string array on values.
* @return The array of values.
*/
PVStringArray *getValues();
private:
PVStructure::shared_pointer pvNTNameValue;
PVString * pvFunction;
PVStructurePtr pvTimeStamp;
PVStructurePtr pvAlarm;
PVStringArray *pvNames;
PVStringArray *pvValues;
};
}}
#endif /* NTNAMEVALUE_H */

162
src/nt/nttable.cpp Normal file
View File

@@ -0,0 +1,162 @@
/* nttable.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#include <pv/nttable.h>
namespace epics { namespace pvData {
bool NTTable::isNTTable(PVStructurePtr pvStructure)
{
NTField *ntfield = NTField::get();
//StandardField *standardField = getStandardField();
String name = pvStructure->getField()->getFieldName();
if(name.compare("NTTable")!=0) return false;
PVStringArray *pvLabel = static_cast<PVStringArray *>
(pvStructure->getScalarArrayField("label",pvString));
if(pvLabel==0) return false;
int nfields = pvLabel->getLength();
int nextra = 1; // label is 1 field
PVFieldPtr pvField = pvStructure->getSubField("function");
if(pvField!=0 && pvStructure->getStringField("function")) nextra++;
pvField = pvStructure->getSubField("timeStamp");
if(pvField!=0 && ntfield->isTimeStamp(pvField->getField())) {
nextra++;
}
pvField = pvStructure->getSubField("alarm");
if(pvField!=0 && ntfield->isAlarm(pvField->getField())) {
nextra++;
}
if(nfields!=(pvStructure->getStructure()->getNumberFields()-nextra)) return false;
FieldConstPtrArray fields = pvStructure->getStructure()->getFields();
int n = nfields - nextra;
for(int i=0; i<n; i++) {
FieldConstPtr field = fields[i+nextra];
Type type = field->getType();
if(type!=scalarArray && type!=structureArray) return false;
}
return true;
}
PVStructure::shared_pointer NTTable::create(
bool hasFunction,bool hasTimeStamp, bool hasAlarm,
int numberValues,
FieldConstPtrArray valueFields)
{
StandardField *standardField = getStandardField();
int nfields = 1;
if(hasFunction) nfields++;
if(hasTimeStamp) nfields++;
if(hasAlarm) nfields++;
nfields += numberValues;
FieldCreate *fieldCreate = getFieldCreate();
PVDataCreate *pvDataCreate = getPVDataCreate();
FieldConstPtrArray fields = new FieldConstPtr[nfields];
int ind = 0;
if(hasFunction) {
fields[ind++] = fieldCreate->createScalar(String("function"),pvString);
}
if(hasTimeStamp) {
fields[ind++] = standardField->timeStamp();
}
if(hasAlarm) {
fields[ind++] = standardField->alarm();
}
fields[ind++] = standardField->scalarArray("label",pvString);
for(int i=0; i<numberValues ; i++) fields[ind++] = valueFields[i];
PVStructure::shared_pointer pvStructure = PVStructure::shared_pointer(
pvDataCreate->createPVStructure(0,"NTTable",nfields,fields));
String label[numberValues];
for(int i=0; i<numberValues; i++) {
FieldConstPtr field = fields[nfields - numberValues +i];
label[i] = field->getFieldName();
}
PVStringArray *pvLabel = static_cast<PVStringArray *>
(pvStructure->getScalarArrayField("label",pvString));
pvLabel->put(0,numberValues,label,0);
return pvStructure;
}
NTTable::NTTable(PVStructure::shared_pointer const & pvStructure)
: pvNTTable(pvStructure),
pvFunction(0),
pvTimeStamp(0),
pvAlarm(0),
pvLabel(0),
offsetFields(1)
{
NTField *ntfield = NTField::get();
String name = pvStructure->getField()->getFieldName();
if(name.compare("NTTable")!=0) {
throw std::invalid_argument(
"pvArgument does not have name NTTable");
}
PVScalarArray * pvScalarArray
= pvStructure->getScalarArrayField("label",pvString);
if(pvScalarArray==0) {
throw std::invalid_argument(
"pvArgument did not have a structureArray field value");
}
pvLabel = static_cast<PVStringArray *>(pvScalarArray);
PVFieldPtr pvField = pvStructure->getSubField("function");
if(pvField!=0) {
pvFunction = pvStructure->getStringField("function");
offsetFields++;
}
pvField = pvStructure->getSubField("timeStamp");
if(pvField!=0 && ntfield->isTimeStamp(pvField->getField())) {
pvTimeStamp = static_cast<PVStructure *>(pvField);
offsetFields++;
}
pvField = pvStructure->getSubField("alarm");
if(pvField!=0 && ntfield->isAlarm(pvField->getField())) {
pvAlarm = static_cast<PVStructure *>(pvField);
offsetFields++;
}
}
NTTable::~NTTable()
{
}
PVString * NTTable::getFunction()
{
return pvFunction;
}
void NTTable::attachTimeStamp(PVTimeStamp &pvTimeStamp)
{
if(this->pvTimeStamp==0) return;
pvTimeStamp.attach(this->pvTimeStamp);
}
void NTTable::attachAlarm(PVAlarm &pvAlarm)
{
if(this->pvAlarm==0) return;
pvAlarm.attach(this->pvAlarm);
}
PVStringArray * NTTable::getLabel()
{
return pvLabel;
}
int NTTable::getNumberValues()
{
return pvLabel->getLength();
}
FieldConstPtr NTTable::getField(int index)
{
return pvNTTable->getStructure()->getFields()[index+offsetFields];
}
PVFieldPtr NTTable::getPVField(int index)
{
return pvNTTable->getPVFields()[index+offsetFields];
}
}}

117
src/nt/nttable.h Normal file
View File

@@ -0,0 +1,117 @@
/* nttable.h */
/**
* Copyright - See the COPYRIGHT that is included with this distribution.
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*/
#ifndef NTTABLE_H
#define NTTABLE_H
#include <pv/ntfield.h>
namespace epics { namespace pvData {
/**
* Convenience Class for NTTable
* @author mrk
*
*/
class NTTable
{
public:
POINTER_DEFINITIONS(NTTable);
/**
* Is the pvStructure an NTTable.
* @param pvStructure The pvStructure to test.
* @return (false,true) if (is not, is) an NTNameValuePair.
*/
static bool isNTTable(PVStructurePtr pvStructure);
/**
* Create an NTTable pvStructure.
* @param hasFunction Create a PVString field named function.
* @param hasTimeStamp Create a timeStamp structure field.
* @param hasAlarm Create an alarm structure field.
* @param numberValues The number of fields that follow the label field.
* @param valueFields The fields that follow the label field.
* @return an NTTable pvStructure.
*/
static PVStructure::shared_pointer create(
bool hasFunction,bool hasTimeStamp, bool hasAlarm,
int numberValues,
FieldConstPtrArray valueFields);
/**
* Constructor
* @param pvStructure The pvStructure to which to attach.
* @return A NTTable that is attached to the pvStructure
*/
NTTable(PVStructure::shared_pointer const & pvStructure);
/**
* Destructor
*/
~NTTable();
/**
* Get the function field.
* @return The pvString or null if no function field.
*/
PVString *getFunction();
/**
* Attach a pvTimeStamp.
* @param pvTimeStamp The pvTimeStamp that will be attached.
* Does nothing if no timeStamp
*/
void attachTimeStamp(PVTimeStamp &pvTimeStamp);
/**
* Attach an pvAlarm.
* @param pvAlarm The pvAlarm that will be attached.
* Does nothing if no alarm
*/
void attachAlarm(PVAlarm &pvAlarm);
/**
* Get the pvStructure.
* @return PVStructurePtr.
*/
PVStructurePtr getPVStructure(){return pvNTTable.get();}
/**
* Get the timeStamp.
* @return PVStructurePtr which may be null.
*/
PVStructurePtr getTimeStamp(){return pvTimeStamp;}
/**
* Get the alarm.
* @return PVStructurePtr which may be null.
*/
PVStructurePtr getAlarm() {return pvAlarm;}
/**
* Get the label field.
* @return The pvStringArray for the label.
*/
PVStringArray *getLabel();
/**
* Get the the number of fields that follow the label field.
* @return The number of fields.
*/
int getNumberValues();
/**
* Get the Field for a field that follows the label field.
* @param index The index of the field desired.
* @return The FieldConstPtr for the field.
*/
FieldConstPtr getField(int index);
/**
* Get the PVField for a field that follows the label field.
* @param index The index of the field desired.
* @return The PVFieldPtr for the field.
*/
PVFieldPtr getPVField(int index);
private:
PVStructure::shared_pointer pvNTTable;
PVString *pvFunction;
PVStructurePtr pvTimeStamp;
PVStructurePtr pvAlarm;
PVStringArray *pvLabel;
int offsetFields;
};
}}
#endif /* NTTABLE_H */