10#include <pv/sharedPtr.h>
14#define epicsExportSharedSymbols
20using namespace epics::pvData;
22namespace epics {
namespace nt {
26static FieldCreatePtr fieldCreate = getFieldCreate();
27static PVDataCreatePtr pvDataCreate = getPVDataCreate();
41 const size_t NUMBER_OF_INDICES = DISPLAY_INDEX+1;
42 const size_t NUMBER_OF_STRUCTURES = 1 << NUMBER_OF_INDICES;
46 static StructureConstPtr ntndarrayStruc[NUMBER_OF_STRUCTURES];
47 static UnionConstPtr valueType;
48 static StructureConstPtr codecStruc;
49 static StructureConstPtr dimensionStruc;
50 static StructureConstPtr attributeStruc;
52 StructureConstPtr returnedStruc;
55 if (descriptor) index |= 1 << DISCRIPTOR_INDEX;
56 if (timeStamp) index |= 1 << TIMESTAMP_INDEX;
57 if (alarm) index |= 1 << ALARM_INDEX;
58 if (display) index |= 1 << DISPLAY_INDEX;
60 bool isExtended = !extraFieldNames.empty();
62 if (isExtended || !ntndarrayStruc[index])
64 StandardFieldPtr standardField = getStandardField();
65 FieldBuilderPtr fb = fieldCreate->createFieldBuilder();
69 for (
int i = pvBoolean; i < pvString; ++i)
71 ScalarType st =
static_cast<ScalarType
>(i);
72 fb->addArray(std::string(ScalarTypeFunc::name(st)) +
"Value", st);
74 valueType = fb->createUnion();
79 codecStruc = fb->setId(
"codec_t")->
80 add(
"name", pvString)->
81 add(
"parameters", fieldCreate->createVariantUnion())->
87 dimensionStruc = fb->setId(
"dimension_t")->
89 add(
"offset", pvInt)->
90 add(
"fullSize", pvInt)->
91 add(
"binning", pvInt)->
92 add(
"reverse", pvBoolean)->
102 add(
"value", valueType)->
103 add(
"codec", codecStruc)->
104 add(
"compressedSize", pvLong)->
105 add(
"uncompressedSize", pvLong)->
106 addArray(
"dimension", dimensionStruc)->
107 add(
"uniqueId", pvInt)->
108 add(
"dataTimeStamp", standardField->timeStamp())->
109 addArray(
"attribute", attributeStruc);
112 fb->add(
"descriptor", pvString);
115 fb->add(
"alarm", standardField->alarm());
118 fb->add(
"timeStamp", standardField->timeStamp());
121 fb->add(
"display", standardField->display());
123 size_t extraCount = extraFieldNames.size();
124 for (
size_t i = 0; i< extraCount; i++)
125 fb->add(extraFieldNames[i], extraFields[i]);
127 returnedStruc = fb->createStructure();
130 ntndarrayStruc[index] = returnedStruc;
134 return ntndarrayStruc[index];
137 return returnedStruc;
143 return shared_from_this();
149 return shared_from_this();
155 return shared_from_this();
161 return shared_from_this();
174NTNDArrayBuilder::NTNDArrayBuilder()
179void NTNDArrayBuilder::reset()
185 extraFieldNames.clear();
191 extraFields.push_back(field); extraFieldNames.push_back(name);
192 return shared_from_this();
208 return shared_pointer(
new NTNDArray(pvStructure));
218 return is_a(pvStructure->getStructure());
222 Result& isValue(Result& result)
224 result.is<Union>(Union::defaultId());
226 for (
int i = pvBoolean; i < pvString; ++i) {
227 ScalarType type =
static_cast<ScalarType
>(i);
228 string name(ScalarTypeFunc::name(type));
229 result.has<ScalarArray>(name +
"Value");
235 Result& isCodec(Result& result)
238 .is<Structure>(
"codec_t")
240 .has<Union>(
"parameters");
243 Result& isDimension(Result& result)
246 .is<StructureArray>(
"dimension_t[]")
248 .has<Scalar>(
"offset")
249 .has<Scalar>(
"fullSize")
250 .has<Scalar>(
"binning")
251 .has<Scalar>(
"reverse");
260 Result result(structure);
264 .has<&isValue>(
"value")
265 .has<&isCodec>(
"codec")
266 .has<Scalar>(
"compressedSize")
267 .has<Scalar>(
"uncompressedSize")
268 .has<&isDimension>(
"dimension")
269 .has<Scalar>(
"uniqueId")
270 .has<&NTField::isTimeStamp, Structure>(
"dataTimeStamp")
271 .has<&NTNDArrayAttribute::isAttribute, StructureArray>(
"attribute")
272 .maybeHas<Scalar>(
"descriptor")
274 .maybeHas<&NTField::isTimeStamp, Structure>(
"timeStamp")
282 if(!pvStructure.get())
return false;
289 int64 valueSize = getValueSize();
291 if (valueSize != compressedSize)
294 long expectedUncompressed = getExpectedUncompressedSize();
296 if (uncompressedSize != expectedUncompressed)
299 std::string codecName =
getCodec()->getSubField<PVString>(
"name")->get();
300 if (codecName ==
"" && valueSize < uncompressedSize)
306int64 NTNDArray::getExpectedUncompressedSize()
311 if (pvDim->getLength() != 0)
313 PVStructureArray::const_svector data = pvDim->view();
314 size = getValueTypeSize();
315 for (PVStructureArray::const_svector::const_iterator it = data.begin();
316 it != data.end(); ++it )
318 PVStructurePtr dim = *it;
319 size *= dim->getSubField<PVInt>(
"size")->get();
326int64 NTNDArray::getValueSize()
329 PVScalarArrayPtr storedValue =
getValue()->get<PVScalarArray>();
330 if (storedValue.get())
331 size = storedValue->getLength()*getValueTypeSize();
335int64 NTNDArray::getValueTypeSize()
338 PVScalarArrayPtr storedValue =
getValue()->get<PVScalarArray>();
339 if (storedValue.get())
341 switch (storedValue->getScalarArray()->getElementType())
383 return pvTimeStamp.attach(ts);
392 return pvTimeStamp.attach(ts);
401 return pvAlarm.attach(al);
410 return pvDisplay.attach(dp);
422 return pvNTNDArray->getSubField<PVUnion>(
"value");
427 return pvNTNDArray->getSubField<PVStructure>(
"codec");
432 return pvNTNDArray->getSubField<PVLong>(
"compressedSize");
437 return pvNTNDArray->getSubField<PVLong>(
"uncompressedSize");
442 return pvNTNDArray->getSubField<PVStructureArray>(
"dimension");
447 return pvNTNDArray->getSubField<PVInt>(
"uniqueId");
452 return pvNTNDArray->getSubField<PVStructure>(
"dataTimeStamp");
457 return pvNTNDArray->getSubField<PVStructureArray>(
"attribute");
462 return pvNTNDArray->getSubField<PVString>(
"descriptor");
467 return pvNTNDArray->getSubField<PVStructure>(
"timeStamp");
472 return pvNTNDArray->getSubField<PVStructure>(
"alarm");
477 return pvNTNDArray->getSubField<PVStructure>(
"display");
481NTNDArray::NTNDArray(PVStructurePtr
const & pvStructure) :
482 pvNTNDArray(pvStructure)
bool isAlarm(epics::pvData::FieldConstPtr const &field)
bool isDisplay(epics::pvData::FieldConstPtr const &field)
static NTNDArrayAttributeBuilderPtr createBuilder()
Convenience Class for NTNDArray.
epics::pvData::PVStructurePtr getDataTimeStamp() const
epics::pvData::PVStructureArrayPtr getAttribute() const
bool attachDisplay(epics::pvData::PVDisplay &pvDisplay) const
static NTNDArrayBuilderPtr createBuilder()
epics::pvData::PVLongPtr getUncompressedDataSize() const
epics::pvData::PVLongPtr getCompressedDataSize() const
static shared_pointer wrapUnsafe(epics::pvData::PVStructurePtr const &pvStructure)
epics::pvData::PVStructurePtr getTimeStamp() const
epics::pvData::PVStringPtr getDescriptor() const
bool attachAlarm(epics::pvData::PVAlarm &pvAlarm) const
static bool isCompatible(epics::pvData::StructureConstPtr const &structure)
epics::pvData::PVStructurePtr getAlarm() const
epics::pvData::PVStructurePtr getPVStructure() const
epics::pvData::PVStructurePtr getCodec() const
epics::pvData::PVIntPtr getUniqueId() const
epics::pvData::PVUnionPtr getValue() const
static shared_pointer wrap(epics::pvData::PVStructurePtr const &pvStructure)
bool attachTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const
epics::pvData::PVStructureArrayPtr getDimension() const
bool attachDataTimeStamp(epics::pvData::PVTimeStamp &pvTimeStamp) const
static bool is_a(epics::pvData::StructureConstPtr const &structure)
epics::pvData::PVStructurePtr getDisplay() const
static const std::string URI
static bool is_a(const std::string &u1, const std::string &u2)
Interface for in-line creating of NTNDArray.
shared_pointer addAlarm()
friend class ::epics::nt::NTNDArray
shared_pointer addDisplay()
shared_pointer addTimeStamp()
epics::pvData::StructureConstPtr createStructure()
shared_pointer addDescriptor()
shared_pointer add(std::string const &name, epics::pvData::FieldConstPtr const &field)
epics::pvData::PVStructurePtr createPVStructure()
const std::string ntAttrStr("epics:nt/NTAttribute:1.0")
std::tr1::shared_ptr< detail::NTNDArrayBuilder > NTNDArrayBuilderPtr
std::tr1::shared_ptr< NTNDArray > NTNDArrayPtr