Merge pull request #3 from dhickin/NTScalarMultiChannel

Add NTScalarMultiChannel
This commit is contained in:
dhickin
2015-08-05 22:13:19 +01:00
5 changed files with 791 additions and 0 deletions

View File

@@ -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

View 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);
}
}}

View 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 */

View File

@@ -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

View 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();
}