This commit is contained in:
Matej Sekoranja
2014-08-22 22:56:51 +02:00
4 changed files with 412 additions and 0 deletions

View File

@@ -11,12 +11,14 @@ INC += ntscalar.h
INC += ntnameValue.h
INC += nttable.h
INC += ntmultiChannel.h
INC += ntndarray.h
LIBSRCS += ntfield.cpp
LIBSRCS += ntscalar.cpp
LIBSRCS += ntnameValue.cpp
LIBSRCS += nttable.cpp
LIBSRCS += ntmultiChannel.cpp
LIBSRCS += ntndarray.cpp
LIBRARY=nt

View File

@@ -11,6 +11,7 @@
#include <pv/ntscalar.h>
#include <pv/ntnameValue.h>
#include <pv/nttable.h>
#include <pv/ntndarray.h>
#endif /* NT_H */

244
src/nt/ntndarray.cpp Normal file
View File

@@ -0,0 +1,244 @@
/* ntndarray.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>
#include <pv/ntndarray.h>
using namespace std;
using namespace epics::pvData;
namespace epics { namespace nt {
const std::string NTNDArray::URI("uri:ev4:nt/2012/pwd:NTNDArray");
const std::string ntAttrStr("uri:ev4:nt/2012/pwd:NTAttribute");
static FieldCreatePtr fieldCreate = getFieldCreate();
static PVDataCreatePtr pvDataCreate = getPVDataCreate();
bool NTNDArray::is_a(StructureConstPtr const & structure)
{
return structure->getID() == URI;
}
NTNDArrayPtr NTNDArray::create(epics::pvData::PVStructurePtr const &pvStructure)
{
return NTNDArrayPtr(new NTNDArray(pvStructure));
}
NTNDArrayPtr NTNDArray::create(bool hasDescriptor,
bool hasTimeStamp, bool hasAlarm, bool hasDisplay)
{
PVStructurePtr pvStructure = pvDataCreate->createPVStructure(
createStructure(hasDescriptor, hasTimeStamp, hasAlarm, hasDisplay));
return NTNDArrayPtr(new NTNDArray(pvStructure));
}
NTNDArrayPtr NTNDArray::create()
{
return create(true,true,true,true);
}
StructureConstPtr NTNDArray::createStructure(bool hasDescriptor,
bool hasTimeStamp, bool hasAlarm, bool hasDisplay)
{
enum
{
DISCRIPTOR_INDEX,
TIMESTAMP_INDEX,
ALARM_INDEX,
DISPLAY_INDEX
};
const size_t NUMBER_OF_INDICES = DISPLAY_INDEX+1;
const size_t NUMBER_OF_STRUCTURES = 1 << NUMBER_OF_INDICES;
static epics::pvData::StructureConstPtr ntndarrayStruc[NUMBER_OF_STRUCTURES];
static epics::pvData::StructureConstPtr codecStruc;
static epics::pvData::StructureConstPtr dimensionStruc;
static epics::pvData::StructureConstPtr attributeStruc;
static Mutex mutex;
Lock xx(mutex);
size_t index = 0;
if (hasDescriptor) index |= 1 << DISCRIPTOR_INDEX;
if (hasTimeStamp) index |= 1 << TIMESTAMP_INDEX;
if (hasAlarm) index |= 1 << ALARM_INDEX;
if (hasDisplay) index |= 1 << DISPLAY_INDEX;
if (ntndarrayStruc[index] == NULL)
{
StandardFieldPtr standardField = getStandardField();
FieldBuilderPtr fb = fieldCreate->createFieldBuilder();
UnionConstPtr codecParameters = fb->createUnion();
if (codecStruc == NULL)
{
codecStruc = fb->setId("codec_t")->
add("name", pvString)->
add("parameters", codecParameters)->
createStructure();
}
if (dimensionStruc == NULL)
{
dimensionStruc = fb->setId("dimension_t")->
add("size", pvInt)->
add("offset", pvInt)->
add("fullSize", pvInt)->
add("binning", pvInt)->
add("reverse", pvBoolean)->
createStructure();
}
if (attributeStruc == NULL)
{
attributeStruc = fb->setId(ntAttrStr)->
add("name", pvString)->
add("value", fieldCreate->createVariantUnion())->
add("description", pvString)->
add("sourceType", pvInt)->
add("source", pvString)->
createStructure();
}
fb->setId(URI)->
add("value", makeValueType())->
add("compressedSize", pvLong)->
add("uncompressedSize", pvLong)->
add("codec", codecStruc)->
addArray("dimension", dimensionStruc)->
add("dataTimeStamp", standardField->timeStamp())->
add("uniqueId", pvInt)->
addArray("attribute", attributeStruc);
if (hasDescriptor) fb->add("descriptor", pvString);
if (hasAlarm) fb->add("alarm", standardField->alarm());
if (hasTimeStamp) fb->add("timeStamp", standardField->timeStamp());
if (hasDisplay) fb->add("display", standardField->display());
ntndarrayStruc[index] = fb->createStructure();
}
return ntndarrayStruc[index];
}
UnionConstPtr NTNDArray::makeValueType()
{
static epics::pvData::UnionConstPtr valueType;
if (valueType == NULL)
{
FieldBuilderPtr fb = getFieldCreate()->createFieldBuilder();
for (int i = pvBoolean; i < pvString; ++i)
{
ScalarType st = static_cast<ScalarType>(i);
fb->addArray(std::string(ScalarTypeFunc::name(st)) + "Value", st);
}
valueType = fb->createUnion();
}
return valueType;
}
bool NTNDArray::attachTimeStamp(PVTimeStamp &pvTimeStamp) const
{
PVStructurePtr ts = getTimeStamp();
if (ts)
return pvTimeStamp.attach(ts);
else
return false;
}
bool NTNDArray::attachDataTimeStamp(PVTimeStamp &pvTimeStamp) const
{
PVStructurePtr ts = getDataTimeStamp();
if (ts)
return pvTimeStamp.attach(ts);
else
return false;
}
bool NTNDArray::attachAlarm(PVAlarm &pvAlarm) const
{
PVStructurePtr al = getAlarm();
if (al)
return pvAlarm.attach(al);
else
return false;
}
PVStructurePtr NTNDArray::getPVStructure() const
{
return pvNTNDArray;
}
PVUnionPtr NTNDArray::getValue() const
{
return pvNTNDArray->getSubField<PVUnion>("value");
}
PVLongPtr NTNDArray::getCompressedDataSize() const
{
return pvNTNDArray->getSubField<PVLong>("compressedSize");
}
PVLongPtr NTNDArray::getUncompressedDataSize() const
{
return pvNTNDArray->getSubField<PVLong>("uncompressedSize");
}
PVStructurePtr NTNDArray::getCodec() const
{
return pvNTNDArray->getSubField<PVStructure>("codec");
}
PVStructureArrayPtr NTNDArray::getAttribute() const
{
return pvNTNDArray->getSubField<PVStructureArray>("attribute");
}
PVStructureArrayPtr NTNDArray::getDimension() const
{
return pvNTNDArray->getSubField<PVStructureArray>("dimension");
}
PVStructurePtr NTNDArray::getDataTimeStamp() const
{
return pvNTNDArray->getSubField<PVStructure>("dataTimeStamp");
}
PVStringPtr NTNDArray::getDescriptor() const
{
return pvNTNDArray->getSubField<PVString>("descriptor");
}
PVStructurePtr NTNDArray::getTimeStamp() const
{
return pvNTNDArray->getSubField<PVStructure>("timeStamp");
}
PVStructurePtr NTNDArray::getAlarm() const
{
return pvNTNDArray->getSubField<PVStructure>("alarm");
}
NTNDArray::NTNDArray(PVStructurePtr const & pvStructure) :
pvNTNDArray(pvStructure)
{}
}}

165
src/nt/ntndarray.h Normal file
View File

@@ -0,0 +1,165 @@
/* ntndarray.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 NTNDARRAY_H
#define NTNDARRAY_H
#include <pv/ntfield.h>
#include <vector>
#include <string>
namespace epics { namespace nt {
class NTNDArray;
typedef std::tr1::shared_ptr<NTNDArray> NTNDArrayPtr;
/**
* Convenience Class for NTNDArray
* @author dgh
*/
class NTNDArray
{
public:
POINTER_DEFINITIONS(NTNDArray);
static const std::string URI;
/**
* Is the structure an NTNDArray.
* @param structure The structure to test.
* @return (false,true) if (is not, is) an NTNDArray.
*/
static bool is_a(epics::pvData::StructureConstPtr const & structure);
static NTNDArrayPtr create(
epics::pvData::PVStructurePtr const &pvStructure);
static NTNDArrayPtr create(bool hasDescriptor,
bool hasTimeStamp, bool hasAlarm, bool hasDisplay);
static NTNDArrayPtr create();
static NTNDArrayPtr clone(epics::pvData::PVStructurePtr const &);
/**
* Create a {@code Structure} that represents NTNDArray.
*/
static epics::pvData::StructureConstPtr createStructure(bool hasDescriptor,
bool hasTimeStamp, bool hasAlarm, bool hasDisplay);
/**
* Destructor.
*/
~NTNDArray() {}
/**
* Attach a pvTimeStamp to timeStamp field.
* @param pvTimeStamp The pvTimeStamp that will be attached.
* Does nothing if no timeStamp.
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
*/
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
/**
* Attach a pvTimeStamp to dataTimeStamp field.
* @param pvTimeStamp The pvTimeStamp that will be attached.
* Does nothing if no timeStamp.
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
*/
bool attachDataTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const;
/**
* Attach an pvAlarm.
* @param pvAlarm The pvAlarm that will be attached.
* Does nothing if no alarm.
* @return true if the operation was successfull (i.e. this instance has a timeStamp field), otherwise false.
*/
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const;
/**
* Get the pvStructure.
* @return PVStructurePtr.
*/
epics::pvData::PVStructurePtr getPVStructure() const;
/**
* Get the value field.
* @return The PVField for the values.
*/
epics::pvData::PVUnionPtr getValue() const;
/**
* Get the compressedDataSize field.
* @return PVStructurePtr.
*/
epics::pvData::PVLongPtr getCompressedDataSize() const;
/**
* Get the uncompressedDataSize field.
* @return PVStructurePtr.
*/
epics::pvData::PVLongPtr getUncompressedDataSize() const;
/**
* Get the codec field.
* @return the PVStructurePtr.
*/
epics::pvData::PVStructurePtr getCodec() const;
/**
* Get the attribute field.
* @return the PVStructurePtr.
*/
epics::pvData::PVStructureArrayPtr getAttribute() const;
/**
* Get the dimension field.
* @return the PVStructurePtr.
*/
epics::pvData::PVStructureArrayPtr getDimension() const;
/**
* Get the uniqueId field.
* @return PVStructurePtr.
*/
epics::pvData::PVIntPtr getUniqueId() const;
/**
* Get the data timeStamp field.
* @return PVStructurePtr.
*/
epics::pvData::PVStructurePtr getDataTimeStamp() const;
/**
* Get the descriptor field.
* @return The pvString or null if no function field.
*/
epics::pvData::PVStringPtr getDescriptor() const;
/**
* Get the timeStamp field.
* @return PVStructurePtr which may be null.
*/
epics::pvData::PVStructurePtr getTimeStamp() const;
/**
* Get the alarm field.
* @return PVStructurePtr which may be null.
*/
epics::pvData::PVStructurePtr getAlarm() const;
private:
NTNDArray(epics::pvData::PVStructurePtr const & pvStructure);
static epics::pvData::UnionConstPtr makeValueType();
epics::pvData::PVStructurePtr pvNTNDArray;
};
}}
#endif /* NTNDARRAY_H */