Merge pull request #3 from dhickin/NTScalarMultiChannel
Add NTScalarMultiChannel
This commit is contained in:
@@ -13,6 +13,7 @@ INC += ntscalarArray.h
|
||||
INC += ntnameValue.h
|
||||
INC += nttable.h
|
||||
INC += ntmultiChannel.h
|
||||
INC += ntscalarMultiChannel.h
|
||||
INC += ntndarray.h
|
||||
|
||||
LIBSRCS += ntutils.cpp
|
||||
@@ -22,6 +23,7 @@ LIBSRCS += ntscalarArray.cpp
|
||||
LIBSRCS += ntnameValue.cpp
|
||||
LIBSRCS += nttable.cpp
|
||||
LIBSRCS += ntmultiChannel.cpp
|
||||
LIBSRCS += ntscalarMultiChannel.cpp
|
||||
LIBSRCS += ntndarray.cpp
|
||||
|
||||
LIBRARY = nt
|
||||
|
||||
278
src/nt/ntscalarMultiChannel.cpp
Normal file
278
src/nt/ntscalarMultiChannel.cpp
Normal file
@@ -0,0 +1,278 @@
|
||||
/* ntscalarMultiChannel.cpp */
|
||||
/**
|
||||
* 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 <algorithm>
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include <pv/ntscalarMultiChannel.h>
|
||||
#include <pv/ntutils.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace epics::pvData;
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
|
||||
namespace detail {
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::value(ScalarType scalarType)
|
||||
{
|
||||
valueType = scalarType;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addDescriptor()
|
||||
{
|
||||
descriptor = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addAlarm()
|
||||
{
|
||||
alarm = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addTimeStamp()
|
||||
{
|
||||
timeStamp = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addSeverity()
|
||||
{
|
||||
severity = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addStatus()
|
||||
{
|
||||
status = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addMessage()
|
||||
{
|
||||
message = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addSecondsPastEpoch()
|
||||
{
|
||||
secondsPastEpoch = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addNanoseconds()
|
||||
{
|
||||
nanoseconds = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::addUserTag()
|
||||
{
|
||||
userTag = true;
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
StructureConstPtr NTScalarMultiChannelBuilder::createStructure()
|
||||
{
|
||||
StandardFieldPtr standardField = getStandardField();
|
||||
size_t nfields = 3;
|
||||
size_t extraCount = extraFieldNames.size();
|
||||
nfields += extraCount;
|
||||
if(descriptor) ++nfields;
|
||||
if(alarm) ++nfields;
|
||||
if(timeStamp) ++nfields;
|
||||
if(severity) ++nfields;
|
||||
if(status) ++nfields;
|
||||
if(message) ++nfields;
|
||||
if(secondsPastEpoch) ++nfields;
|
||||
if(nanoseconds) ++nfields;
|
||||
if(userTag) ++nfields;
|
||||
FieldConstPtrArray fields(nfields);
|
||||
StringArray names(nfields);
|
||||
size_t ind = 0;
|
||||
names[ind] = "value";
|
||||
fields[ind++] = fieldCreate->createScalarArray(valueType);
|
||||
names[ind] = "channelName";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvString);
|
||||
names[ind] = "isConnected";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvBoolean);
|
||||
if(descriptor) {
|
||||
names[ind] = "descriptor";
|
||||
fields[ind++] = fieldCreate->createScalar(pvString);
|
||||
}
|
||||
if(alarm) {
|
||||
names[ind] = "alarm";
|
||||
fields[ind++] = standardField->alarm();
|
||||
}
|
||||
if(timeStamp) {
|
||||
names[ind] = "timeStamp";
|
||||
fields[ind++] = standardField->timeStamp();
|
||||
}
|
||||
if(severity) {
|
||||
names[ind] = "severity";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(status) {
|
||||
names[ind] = "status";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(message) {
|
||||
names[ind] = "message";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvString);
|
||||
}
|
||||
if(secondsPastEpoch) {
|
||||
names[ind] = "secondsPastEpoch";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvLong);
|
||||
}
|
||||
if(nanoseconds) {
|
||||
names[ind] = "nanoseconds";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
if(userTag) {
|
||||
names[ind] = "userTag";
|
||||
fields[ind++] = fieldCreate->createScalarArray(pvInt);
|
||||
}
|
||||
for (size_t i = 0; i< extraCount; i++) {
|
||||
names[ind] = extraFieldNames[i];
|
||||
fields[ind++] = extraFields[i];
|
||||
}
|
||||
|
||||
StructureConstPtr st = fieldCreate->createStructure(NTScalarMultiChannel::URI,names,fields);
|
||||
reset();
|
||||
return st;
|
||||
}
|
||||
|
||||
PVStructurePtr NTScalarMultiChannelBuilder::createPVStructure()
|
||||
{
|
||||
return pvDataCreate->createPVStructure(createStructure());
|
||||
}
|
||||
|
||||
NTScalarMultiChannelPtr NTScalarMultiChannelBuilder::create()
|
||||
{
|
||||
return NTScalarMultiChannelPtr(new NTScalarMultiChannel(createPVStructure()));
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilder::NTScalarMultiChannelBuilder()
|
||||
: valueType(pvDouble)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void NTScalarMultiChannelBuilder::reset()
|
||||
{
|
||||
extraFieldNames.clear();
|
||||
extraFields.clear();
|
||||
valueType = pvDouble;
|
||||
descriptor = false;
|
||||
alarm = false;
|
||||
timeStamp = false;
|
||||
severity = false;
|
||||
status = false;
|
||||
message = false;
|
||||
secondsPastEpoch = false;
|
||||
nanoseconds = false;
|
||||
userTag = false;
|
||||
}
|
||||
|
||||
|
||||
NTScalarMultiChannelBuilder::shared_pointer NTScalarMultiChannelBuilder::add(string const & name, FieldConstPtr const & field)
|
||||
{
|
||||
extraFields.push_back(field); extraFieldNames.push_back(name);
|
||||
return shared_from_this();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const std::string NTScalarMultiChannel::URI("epics:nt/NTScalarMultiChannel:1.0");
|
||||
|
||||
NTScalarMultiChannel::shared_pointer NTScalarMultiChannel::wrap(PVStructurePtr const & structure)
|
||||
{
|
||||
if(!isCompatible(structure)) return shared_pointer();
|
||||
return wrapUnsafe(structure);
|
||||
}
|
||||
|
||||
NTScalarMultiChannel::shared_pointer NTScalarMultiChannel::wrapUnsafe(PVStructurePtr const & structure)
|
||||
{
|
||||
return shared_pointer(new NTScalarMultiChannel(structure));
|
||||
}
|
||||
|
||||
bool NTScalarMultiChannel::is_a(StructureConstPtr const &structure)
|
||||
{
|
||||
return NTUtils::is_a(structure->getID(), URI);
|
||||
}
|
||||
|
||||
bool NTScalarMultiChannel::isCompatible(PVStructurePtr const &pvStructure)
|
||||
{
|
||||
if(!pvStructure) return false;
|
||||
PVScalarArrayPtr pvValue = pvStructure->getSubField<PVScalarArray>("value");
|
||||
if(!pvValue) return false;
|
||||
PVFieldPtr pvField = pvStructure->getSubField("descriptor");
|
||||
if(pvField && !pvStructure->getSubField<PVString>("descriptor")) return false;
|
||||
pvField = pvStructure->getSubField("alarm");
|
||||
if(pvField && !ntField->isAlarm(pvField->getField())) return false;
|
||||
pvField = pvStructure->getSubField("timeStamp");
|
||||
if(pvField && !ntField->isTimeStamp(pvField->getField())) return false;
|
||||
pvField = pvStructure->getSubField("severity");
|
||||
if(pvField && !pvStructure->getSubField<PVIntArray>("severity")) return false;
|
||||
pvField = pvStructure->getSubField("status");
|
||||
if(pvField && !pvStructure->getSubField<PVIntArray>("status")) return false;
|
||||
pvField = pvStructure->getSubField("message");
|
||||
if(pvField && !pvStructure->getSubField<PVStringArray>("message")) return false;
|
||||
pvField = pvStructure->getSubField("secondsPastEpoch");
|
||||
if(pvField && !pvStructure->getSubField<PVLongArray>("secondsPastEpoch")) return false;
|
||||
pvField = pvStructure->getSubField("nanoseconds");
|
||||
if(pvField && !pvStructure->getSubField<PVIntArray>("nanoseconds")) return false;
|
||||
pvField = pvStructure->getSubField("userTag");
|
||||
if(pvField && !pvStructure->getSubField<PVIntArray>("userTag")) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NTScalarMultiChannelBuilderPtr NTScalarMultiChannel::createBuilder()
|
||||
{
|
||||
return NTScalarMultiChannelBuilderPtr(new detail::NTScalarMultiChannelBuilder());
|
||||
}
|
||||
|
||||
|
||||
NTScalarMultiChannel::NTScalarMultiChannel(PVStructurePtr const & pvStructure)
|
||||
: pvNTScalarMultiChannel(pvStructure),
|
||||
pvTimeStamp(pvStructure->getSubField<PVStructure>("timeStamp")),
|
||||
pvAlarm(pvStructure->getSubField<PVStructure>("alarm")),
|
||||
pvValue(pvStructure->getSubField<PVScalarArray>("value")),
|
||||
pvChannelName(pvStructure->getSubField<PVStringArray>("channelName")),
|
||||
pvIsConnected(pvStructure->getSubField<PVBooleanArray>("isConnected")),
|
||||
pvSeverity(pvStructure->getSubField<PVIntArray>("severity")),
|
||||
pvStatus(pvStructure->getSubField<PVIntArray>("status")),
|
||||
pvMessage(pvStructure->getSubField<PVStringArray>("message")),
|
||||
pvSecondsPastEpoch(pvStructure->getSubField<PVLongArray>("secondsPastEpoch")),
|
||||
pvNanoseconds(pvStructure->getSubField<PVIntArray>("nanoseconds")),
|
||||
pvUserTag(pvStructure->getSubField<PVIntArray>("userTag")),
|
||||
pvDescriptor(pvStructure->getSubField<PVString>("descriptor"))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void NTScalarMultiChannel::attachTimeStamp(PVTimeStamp &pv) const
|
||||
{
|
||||
if(!pvTimeStamp) return;
|
||||
pv.attach(pvTimeStamp);
|
||||
}
|
||||
|
||||
void NTScalarMultiChannel::attachAlarm(PVAlarm &pv) const
|
||||
{
|
||||
if(!pvAlarm) return;
|
||||
pv.attach(pvAlarm);
|
||||
}
|
||||
|
||||
}}
|
||||
328
src/nt/ntscalarMultiChannel.h
Normal file
328
src/nt/ntscalarMultiChannel.h
Normal file
@@ -0,0 +1,328 @@
|
||||
/* ntscalarMultiChannel.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 NTSCALARMULTICHANNEL_H
|
||||
#define NTSCALARMULTICHANNEL_H
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#ifdef epicsExportSharedSymbols
|
||||
# define ntscalarMultiChannelEpicsExportSharedSymbols
|
||||
# undef epicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/pvDisplay.h>
|
||||
#include <pv/pvControl.h>
|
||||
|
||||
#ifdef ntscalarMultiChannelEpicsExportSharedSymbols
|
||||
# define epicsExportSharedSymbols
|
||||
# undef ntscalarMultiChannelEpicsExportSharedSymbols
|
||||
#endif
|
||||
|
||||
#include <pv/ntfield.h>
|
||||
|
||||
#include <shareLib.h>
|
||||
|
||||
|
||||
namespace epics { namespace nt {
|
||||
|
||||
|
||||
class NTScalarMultiChannel;
|
||||
typedef std::tr1::shared_ptr<NTScalarMultiChannel> NTScalarMultiChannelPtr;
|
||||
|
||||
namespace detail {
|
||||
|
||||
/**
|
||||
* @brief Interface for in-line creating of NTScalarMultiChannel.
|
||||
*
|
||||
* One instance can be used to create multiple instances.
|
||||
* An instance of this object must not be used concurrently (an object has a state).
|
||||
* @author dgh
|
||||
* @author mse
|
||||
*/
|
||||
class epicsShareClass NTScalarMultiChannelBuilder :
|
||||
public std::tr1::enable_shared_from_this<NTScalarMultiChannelBuilder>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTScalarMultiChannelBuilder);
|
||||
/**
|
||||
* specify the scalar type for the value field.
|
||||
* If this is not called then pvDouble is the default.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer value(epics::pvData::ScalarType scalarType);
|
||||
/**
|
||||
* Add descriptor field to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addDescriptor();
|
||||
/**
|
||||
* Add alarm structure to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addAlarm();
|
||||
/**
|
||||
* Add timeStamp structure to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addTimeStamp();
|
||||
/**
|
||||
* Add severity array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addSeverity();
|
||||
/**
|
||||
* Add status array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addStatus();
|
||||
/**
|
||||
* Add message array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addMessage();
|
||||
/**
|
||||
* Add secondsPastEpoch array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addSecondsPastEpoch();
|
||||
/**
|
||||
* Add nanoseconds array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addNanoseconds();
|
||||
/**
|
||||
* Add userTag array to the NTScalarMultiChannel.
|
||||
* @return this instance of <b>NTScalarMultiChannelBuilder</b>.
|
||||
*/
|
||||
shared_pointer addUserTag();
|
||||
/**
|
||||
* Create a <b>Structure</b> that represents NTScalarMultiChannel.
|
||||
* This resets this instance state and allows new instance to be created.
|
||||
* @return a new instance of a <b>Structure</b>.
|
||||
*/
|
||||
epics::pvData::StructureConstPtr createStructure();
|
||||
/**
|
||||
* Create a <b>PVStructure</b> that represents NTScalarMultiChannel.
|
||||
* This resets this instance state and allows new {@code instance to be created.}
|
||||
* @return a new instance of a <b>PVStructure</b>
|
||||
*/
|
||||
epics::pvData::PVStructurePtr createPVStructure();
|
||||
/**
|
||||
* Create a <b>NTScalarMultiChannel</b> instance.
|
||||
* This resets this instance state and allows new {@code instance to be created.}
|
||||
* @return a new instance of a <b>NTScalarMultiChannel</b>
|
||||
*/
|
||||
NTScalarMultiChannelPtr create();
|
||||
/**
|
||||
* Add extra <b>Field</b> to the type.
|
||||
* @param name name of the field.
|
||||
* @param field a field to add.
|
||||
* @return this instance of a <b>NTScalarMultiChannelBuilder</b>
|
||||
*/
|
||||
shared_pointer add(std::string const & name, epics::pvData::FieldConstPtr const & field);
|
||||
private:
|
||||
NTScalarMultiChannelBuilder();
|
||||
|
||||
void reset();
|
||||
|
||||
epics::pvData::ScalarType valueType;
|
||||
bool descriptor;
|
||||
bool alarm;
|
||||
bool timeStamp;
|
||||
bool severity;
|
||||
bool status;
|
||||
bool message;
|
||||
bool secondsPastEpoch;
|
||||
bool nanoseconds;
|
||||
bool userTag;
|
||||
|
||||
// NOTE: this preserves order, however it does not handle duplicates
|
||||
epics::pvData::StringArray extraFieldNames;
|
||||
epics::pvData::FieldConstPtrArray extraFields;
|
||||
|
||||
friend class ::epics::nt::NTScalarMultiChannel;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef std::tr1::shared_ptr<detail::NTScalarMultiChannelBuilder> NTScalarMultiChannelBuilderPtr;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Convenience Class for NTScalarMultiChannel
|
||||
* @author dgh
|
||||
* @author mrk
|
||||
*
|
||||
*/
|
||||
class epicsShareClass NTScalarMultiChannel
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(NTScalarMultiChannel);
|
||||
|
||||
static const std::string URI;
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTScalarMultiChannel.
|
||||
* First isCompatible is called.
|
||||
* This method will nullptr if the structure is is not compatible.
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTScalarMultiChannel.
|
||||
* @return NTScalarMultiChannel instance on success, nullptr otherwise.
|
||||
*/
|
||||
static shared_pointer wrap(epics::pvData::PVStructurePtr const & structure);
|
||||
|
||||
/**
|
||||
* Wrap (aka dynamic cast, or wrap) the structure to NTScalarMultiChannel without checking for isCompatible
|
||||
* @param structure The structure to wrap-ed (dynamic cast, wrapped) to NTScalarMultiChannel.
|
||||
* @return NTScalarMultiChannel instance.
|
||||
*/
|
||||
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const & structure);
|
||||
/**
|
||||
* Is the Structure an NTScalarMultiChannel.
|
||||
* This method structure->getID() and checks if it is the same as the URI.
|
||||
* @param structure The structure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarMultiChannel.
|
||||
*/
|
||||
static bool is_a(
|
||||
epics::pvData::StructureConstPtr const &structure);
|
||||
/**
|
||||
* Is the pvStructure compatible with NTScalarMultiChannel.
|
||||
* This method introspects the fields to see if they are compatible.
|
||||
* @param pvStructure The pvStructure to test.
|
||||
* @return (false,true) if (is not, is) an NTScalarMultiChannel.
|
||||
*/
|
||||
static bool isCompatible(
|
||||
epics::pvData::PVStructurePtr const &pvStructure);
|
||||
/**
|
||||
* Create a NTScalarMultiChannelBuilder instance
|
||||
* @return builder instance.
|
||||
*/
|
||||
static NTScalarMultiChannelBuilderPtr createBuilder();
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~NTScalarMultiChannel() {}
|
||||
/**
|
||||
* Attach a pvTimeStamp.
|
||||
* @param pvTimeStamp The pvTimeStamp that will be attached.
|
||||
* Does nothing if no timeStamp
|
||||
*/
|
||||
void attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
|
||||
/**
|
||||
* Attach a pvAlarm.
|
||||
* @param pvAlarm The pvAlarm that will be attached.
|
||||
* Does nothing if no alarm
|
||||
*/
|
||||
void attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
|
||||
/**
|
||||
* Get the pvStructure.
|
||||
* @return PVStructurePtr.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getPVStructure() const
|
||||
{return pvNTScalarMultiChannel;}
|
||||
/**
|
||||
* Get the timeStamp.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getTimeStamp() const
|
||||
{return pvTimeStamp;}
|
||||
/**
|
||||
* Get the alarm.
|
||||
* @return PVStructurePtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStructurePtr getAlarm() const
|
||||
{return pvAlarm;}
|
||||
/**
|
||||
* Get the value of each channel.
|
||||
* @return PVScalarArrayPtr
|
||||
*/
|
||||
epics::pvData::PVScalarArrayPtr getValue() const
|
||||
{return pvValue;}
|
||||
/**
|
||||
* Get the value field of a specified type (e.g. PVDoubleArray).
|
||||
* @return The <PVT> field for the values.
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getValue() const
|
||||
{
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvValue);
|
||||
}
|
||||
/**
|
||||
* Get the channelName of each channel.
|
||||
* @return PVStringArrayPtr
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getChannelName() const
|
||||
{ return pvChannelName;};
|
||||
/**
|
||||
* Get the connection state of each channel.
|
||||
* @return PVBooleanArrayPtr
|
||||
*/
|
||||
epics::pvData::PVBooleanArrayPtr getIsConnected() const
|
||||
{ return pvIsConnected;};
|
||||
/**
|
||||
* Get the severity of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getSeverity() const
|
||||
{return pvSeverity;}
|
||||
/**
|
||||
* Get the status of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getStatus() const
|
||||
{return pvStatus;}
|
||||
/**
|
||||
* Get the message of each chnnel.
|
||||
* @return PVStringArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringArrayPtr getMessage() const
|
||||
{return pvMessage;}
|
||||
/**
|
||||
* Get the secondsPastEpoch of each channel.
|
||||
* @return PVLongArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVLongArrayPtr getSecondsPastEpoch() const
|
||||
{return pvSecondsPastEpoch;}
|
||||
/**
|
||||
* Get the nanoseconds of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getNanoseconds() const
|
||||
{return pvNanoseconds;}
|
||||
/**
|
||||
* Get the userTag of each channel.
|
||||
* @return PVIntArrayPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVIntArrayPtr getUserTag() const
|
||||
{return pvUserTag;}
|
||||
/**
|
||||
* Get the descriptor.
|
||||
* @return PVStringPtr which may be null.
|
||||
*/
|
||||
epics::pvData::PVStringPtr getDescriptor() const
|
||||
{return pvDescriptor;}
|
||||
private:
|
||||
NTScalarMultiChannel(epics::pvData::PVStructurePtr const & pvStructure);
|
||||
epics::pvData::PVStructurePtr pvNTScalarMultiChannel;
|
||||
epics::pvData::PVStructurePtr pvTimeStamp;
|
||||
epics::pvData::PVStructurePtr pvAlarm;
|
||||
epics::pvData::PVScalarArrayPtr pvValue;
|
||||
epics::pvData::PVStringArrayPtr pvChannelName;
|
||||
epics::pvData::PVBooleanArrayPtr pvIsConnected;
|
||||
epics::pvData::PVIntArrayPtr pvSeverity;
|
||||
epics::pvData::PVIntArrayPtr pvStatus;
|
||||
epics::pvData::PVStringArrayPtr pvMessage;
|
||||
epics::pvData::PVLongArrayPtr pvSecondsPastEpoch;
|
||||
epics::pvData::PVIntArrayPtr pvNanoseconds;
|
||||
epics::pvData::PVIntArrayPtr pvUserTag;
|
||||
epics::pvData::PVStringPtr pvDescriptor;
|
||||
friend class detail::NTScalarMultiChannelBuilder;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* NTSCALARMULTICHANNEL_H */
|
||||
@@ -24,6 +24,10 @@ TESTPROD_HOST += ntmultiChannelTest
|
||||
ntmultiChannelTest_SRCS += ntmultiChannelTest.cpp
|
||||
TESTS += ntmultiChannelTest
|
||||
|
||||
TESTPROD_HOST += ntscalarMultiChannelTest
|
||||
ntscalarMultiChannelTest_SRCS += ntscalarMultiChannelTest.cpp
|
||||
TESTS += ntscalarMultiChannelTest
|
||||
|
||||
TESTPROD_HOST += nttableTest
|
||||
nttableTest_SRCS = nttableTest.cpp
|
||||
TESTS += nttableTest
|
||||
|
||||
179
test/nt/ntscalarMultiChannelTest.cpp
Normal file
179
test/nt/ntscalarMultiChannelTest.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
/*
|
||||
* ntscalarMultiChannelTest.cpp
|
||||
*
|
||||
* Created on: 2015.08
|
||||
* Authors: Marty Kraimer, Dave Hickin
|
||||
*/
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdlib>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
|
||||
#include <epicsUnitTest.h>
|
||||
#include <testMain.h>
|
||||
|
||||
|
||||
#include <pv/nt.h>
|
||||
#include <pv/sharedVector.h>
|
||||
#include <pv/ntscalarMultiChannel.h>
|
||||
|
||||
using namespace epics::pvData;
|
||||
using namespace epics::nt;
|
||||
using std::string;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::vector;
|
||||
|
||||
static bool debug = false;
|
||||
|
||||
static FieldCreatePtr fieldCreate = getFieldCreate();
|
||||
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
|
||||
static NTFieldPtr ntField = NTField::get();
|
||||
static PVNTFieldPtr pvntField = PVNTField::get();
|
||||
|
||||
static void test()
|
||||
{
|
||||
NTScalarMultiChannelBuilderPtr builder = NTScalarMultiChannel::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
NTScalarMultiChannelPtr multiChannel = builder->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
add("extra1",fieldCreate->createScalar(pvString)) ->
|
||||
add("extra2",fieldCreate->createScalarArray(pvString)) ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
|
||||
PVStructurePtr pvStructure = multiChannel->getPVStructure();
|
||||
testOk1(pvStructure.get()!=NULL);
|
||||
testOk1(NTScalarMultiChannel::is_a(pvStructure->getStructure()));
|
||||
size_t nchan = 3;
|
||||
shared_vector<string> names(nchan);
|
||||
names[0] = "channel 0";
|
||||
names[1] = "channel 1";
|
||||
names[2] = "channel 2";
|
||||
shared_vector<const string> channelNames(freeze(names));
|
||||
PVStringArrayPtr pvChannelName = multiChannel->getChannelName();
|
||||
pvChannelName->replace(channelNames);
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
multiChannel = builder->
|
||||
value(pvDouble) ->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
pvStructure = multiChannel->getPVStructure();
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
pvChannelName = multiChannel->getChannelName();
|
||||
pvChannelName->replace(channelNames);
|
||||
PVDoubleArrayPtr pvValue = multiChannel->getValue<PVDoubleArray>();
|
||||
PVDoubleArray::svector doubles(nchan);
|
||||
doubles.resize(nchan);
|
||||
doubles[0] = 3.14159;
|
||||
doubles[1] = 2.71828;
|
||||
doubles[2] = 137.036;
|
||||
pvValue->replace(freeze(doubles));
|
||||
shared_vector<int32> severities(nchan);
|
||||
severities[0] = 0;
|
||||
severities[1] = 1;
|
||||
severities[2] = 2;
|
||||
PVIntArrayPtr pvSeverity = multiChannel->getSeverity();
|
||||
pvSeverity->replace(freeze(severities));
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
PVBooleanArrayPtr pvIsConnected = multiChannel->getIsConnected();
|
||||
shared_vector<const epics::pvData::boolean> isConnected = pvIsConnected->view();
|
||||
multiChannel = builder->
|
||||
value(pvDouble) ->
|
||||
addDescriptor()->
|
||||
addAlarm()->
|
||||
addTimeStamp()->
|
||||
addSeverity() ->
|
||||
addStatus() ->
|
||||
addMessage() ->
|
||||
addSecondsPastEpoch() ->
|
||||
addNanoseconds() ->
|
||||
addUserTag() ->
|
||||
create();
|
||||
testOk1(multiChannel.get() != 0);
|
||||
pvStructure = multiChannel->getPVStructure();
|
||||
if(debug) {cout << *pvStructure << endl;}
|
||||
testOk1(NTScalarMultiChannel::isCompatible(pvStructure)==true);
|
||||
PVStructurePtr pvTimeStamp = multiChannel->getTimeStamp();
|
||||
testOk1(pvTimeStamp.get() !=0);
|
||||
PVStructurePtr pvAlarm = multiChannel->getAlarm();
|
||||
testOk1(pvAlarm.get() !=0);
|
||||
pvValue = multiChannel->getValue<PVDoubleArray>();
|
||||
testOk1(pvValue.get() !=0);
|
||||
pvChannelName = multiChannel->getChannelName();
|
||||
testOk1(pvChannelName.get() !=0);
|
||||
pvIsConnected = multiChannel->getIsConnected();
|
||||
testOk1(pvIsConnected.get() !=0);
|
||||
pvSeverity = multiChannel->getSeverity();
|
||||
testOk1(pvSeverity.get() !=0);
|
||||
PVIntArrayPtr pvStatus = multiChannel->getStatus();
|
||||
testOk1(pvStatus.get() !=0);
|
||||
PVStringArrayPtr pvMessage = multiChannel->getMessage();
|
||||
testOk1(pvMessage.get() !=0);
|
||||
PVLongArrayPtr pvSecondsPastEpoch = multiChannel->getSecondsPastEpoch();
|
||||
testOk1(pvSecondsPastEpoch.get() !=0);
|
||||
PVIntArrayPtr pvNanoseconds = multiChannel->getNanoseconds();
|
||||
testOk1(pvNanoseconds.get() !=0);
|
||||
PVIntArrayPtr pvUserTag = multiChannel->getUserTag();
|
||||
testOk1(pvUserTag.get() !=0);
|
||||
PVStringPtr pvDescriptor = multiChannel->getDescriptor();
|
||||
testOk1(pvDescriptor.get() !=0);
|
||||
}
|
||||
|
||||
|
||||
void test_wrap()
|
||||
{
|
||||
testDiag("test_wrap");
|
||||
|
||||
NTScalarMultiChannelPtr nullPtr = NTScalarMultiChannel::wrap(PVStructurePtr());
|
||||
testOk(nullPtr.get() == 0, "nullptr wrap");
|
||||
|
||||
nullPtr = NTScalarMultiChannel::wrap(
|
||||
getPVDataCreate()->createPVStructure(
|
||||
NTField::get()->createTimeStamp()
|
||||
)
|
||||
);
|
||||
testOk(nullPtr.get() == 0, "wrong type wrap");
|
||||
|
||||
|
||||
NTScalarMultiChannelBuilderPtr builder = NTScalarMultiChannel::createBuilder();
|
||||
testOk(builder.get() != 0, "Got builder");
|
||||
|
||||
PVStructurePtr pvStructure = builder->
|
||||
createPVStructure();
|
||||
testOk1(pvStructure.get() != 0);
|
||||
if (!pvStructure)
|
||||
return;
|
||||
|
||||
NTScalarMultiChannelPtr ptr = NTScalarMultiChannel::wrap(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrap OK");
|
||||
|
||||
builder = NTScalarMultiChannel::createBuilder();
|
||||
ptr = NTScalarMultiChannel::wrapUnsafe(pvStructure);
|
||||
testOk(ptr.get() != 0, "wrapUnsafe OK");
|
||||
}
|
||||
|
||||
MAIN(testCreateRequest)
|
||||
{
|
||||
testPlan(25);
|
||||
test();
|
||||
test_wrap();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user