void NTNDArrayRecord::setAttributes() { // Get the attribute field PVStructureArrayPtr attributeField = ndarray->getAttribute(); // Create a shared vector or reuse PVStructureArray::svector attributes(attributeField->reuse()); attributes.reserve(1); // Create an attribute for the Color Mode // name: ColorMode // value: variant union stores a PVInt with value 0 // descriptor: "Color mode" // source: "" // sourceType = 0 PVStructurePtr attribute = getPVDataCreate()->createPVStructure(attributeField->getStructureArray()->getStructure()); NTNDArrayAttributePtr ntattribute = NTNDArrayAttribute::wrap(attribute); ntattribute->getName()->put("ColorMode"); PVInt::shared_pointer pvColorMode = getPVDataCreate()->createPVScalar<PVInt>(); pvColorMode->put(0); ntattribute->getValue()->set(pvColorMode); ntattribute->getDescriptor()->put("Color mode"); ntattribute->getSourceType()->put(0); ntattribute->getSource()->put(""); // Add the attribute to the shared_vector attributes.push_back(attribute); // Replace the attribute field's shared vector // (Remember to freeze first) attributeField->replace(freeze(attributes)); }
PVStringArrayPtr PVDatabase::getRecordNames() { lock(); try { PVStringArrayPtr xxx; if(isDestroyed) { unlock(); return xxx; } PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray> (getPVDataCreate()->createPVScalarArray(pvString)); size_t len = recordMap.size(); shared_vector<string> names(len); PVRecordMap::iterator iter; size_t i = 0; for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) { names[i++] = (*iter).first; } shared_vector<const string> temp(freeze(names)); pvStringArray->replace(temp); unlock(); return pvStringArray; } catch(...) { unlock(); throw; } }
void PVUnionArray::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol) { svector data(reuse()); size_t size = this->getArray()->getArraySizeType() == Array::fixed ? this->getArray()->getMaximumCapacity() : SerializeHelper::readSize(pbuffer, pcontrol); data.resize(size); UnionConstPtr punion = unionArray->getUnion(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for(size_t i = 0; i<size; i++) { pcontrol->ensureData(1); size_t temp = pbuffer->getByte(); if(temp==0) { data[i].reset(); } else { if(data[i].get()==NULL || !data[i].unique()) { data[i] = pvDataCreate->createPVUnion(punion); } data[i]->deserialize(pbuffer, pcontrol); } } replace(freeze(data)); // calls postPut() }
void NTNDArrayRecord::setDimension(const int32_t * dims, size_t ndims) { // Get the dimension field PVStructureArrayPtr dimField = ndarray->getDimension(); // create a shared_vector or try to reuse the dimension field's one PVStructureArray::svector dimVector(dimField->reuse()); // resize/reserve the number of elements dimVector.resize(ndims); // Iterate over the number of dimensions, creating and adding the // appropriate dimension structures. for (size_t i = 0; i < ndims; i++) { PVStructurePtr d = dimVector[i]; // If d is null or not unique create a new PVStructure if (!d || !d.unique()) d = dimVector[i] = getPVDataCreate()->createPVStructure(dimField->getStructureArray()->getStructure()); // Set the size, offset, fullSize, binning and reverse fields // (binning should be 1) d->getSubField<PVInt>("size")->put(dims[i]); d->getSubField<PVInt>("offset")->put(0); d->getSubField<PVInt>("fullSize")->put(dims[i]); d->getSubField<PVInt>("binning")->put(1); d->getSubField<PVBoolean>("reverse")->put(false); } // replace the dimensions field's shared_vector // (Remember to freeze first) dimField->replace(freeze(dimVector)); }
epics::pvData::PVStructurePtr HelloService::request( epics::pvData::PVStructurePtr const & pvArgument ) throw (pvAccess::RPCRequestException) { // Extract the arguments. Just one in this case. // Report an error by throwing a RPCRequestException epics::pvData::PVStringPtr nameField = pvArgument->getStringField("personsname"); if (!nameField) { throw pvAccess::RPCRequestException(Status::STATUSTYPE_ERROR, "PVString field with name 'personsname' expected."); } // Create the result structure of the data interface. PVStructurePtr result( getPVDataCreate()->createPVStructure(makeResponseStructure())); // Extract from the constructed data interface the value of // "greeting" field. The value we'll return, is "Hello" concatenated // to the value of the input parameter called "personsname". PVStringPtr greetingValueField = result->getStringField("greeting"); greetingValueField->put("Hello " + nameField->get()); return result; }
PowerSupplyRecordPtr PowerSupplyRecord::create( string const & recordName) { FieldCreatePtr fieldCreate = getFieldCreate(); StandardFieldPtr standardField = getStandardField(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> add("alarm",standardField->alarm()) -> add("timeStamp",standardField->timeStamp()) -> addNestedStructure("power") -> add("value",pvDouble) -> endNested()-> addNestedStructure("voltage") -> add("value",pvDouble) -> endNested()-> addNestedStructure("current") -> add("value",pvDouble) -> endNested()-> createStructure(); PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); PowerSupplyRecordPtr pvRecord( new PowerSupplyRecord(recordName,pvStructure)); if(!pvRecord->init()) pvRecord.reset(); return pvRecord; }
PvaClientRPCPtr PvaClientRPC::create( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel) { StructureConstPtr structure(getFieldCreate()->createStructure()); PVStructurePtr pvRequest(getPVDataCreate()->createPVStructure(structure)); return create(pvaClient,channel,pvRequest); }
PVStructurePtr NTTableBuilder::createPVStructure() { size_t len = labels.size(); shared_vector<string> l(len); for(size_t i=0; i<len; ++i) l[i] = labels[i]; PVStructurePtr s = getPVDataCreate()->createPVStructure(createStructure()); s->getSubField<PVStringArray>("labels")->replace(freeze(l)); return s; }
void ExampleLink::channelGetConnect( const Status& status, ChannelGet::shared_pointer const & channelGet, StructureConstPtr const & structure) { this->status = status; this->channelGet = channelGet; getPVStructure = getPVDataCreate()->createPVStructure(structure); event.signal(); }
RPCService::shared_pointer ExampleHelloRPC::create() { FieldCreatePtr fieldCreate = getFieldCreate(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> add("value",pvString)-> createStructure(); PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); ExampleHelloRPCPtr hello( new ExampleHelloRPC(pvStructure)); return hello; }
PVStringArrayPtr PVDatabase::getRecordNames() { epicsGuard<epics::pvData::Mutex> guard(mutex); PVStringArrayPtr xxx; PVStringArrayPtr pvStringArray = static_pointer_cast<PVStringArray> (getPVDataCreate()->createPVScalarArray(pvString)); size_t len = recordMap.size(); shared_vector<string> names(len); PVRecordMap::iterator iter; size_t i = 0; for(iter = recordMap.begin(); iter!=recordMap.end(); ++iter) { names[i++] = (*iter).first; } shared_vector<const string> temp(freeze(names)); pvStringArray->replace(temp); return pvStringArray; }
PVStructure::PVStructure(StructureConstPtr const & structurePtr) : PVField(structurePtr), structurePtr(structurePtr), extendsStructureName("") { size_t numberFields = structurePtr->getNumberFields(); FieldConstPtrArray fields = structurePtr->getFields(); StringArray fieldNames = structurePtr->getFieldNames(); // PVFieldPtrArray * xxx = const_cast<PVFieldPtrArray *>(&pvFields); pvFields.reserve(numberFields); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for(size_t i=0; i<numberFields; i++) { pvFields.push_back(pvDataCreate->createPVField(fields[i])); } for(size_t i=0; i<numberFields; i++) { pvFields[i]->setParentAndName(this,fieldNames[i]); } }
size_t PVUnionArray::append(size_t number) { checkLength(value.size()+number); svector data(reuse()); data.resize(data.size()+number); UnionConstPtr punion = unionArray->getUnion(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); for(svector::reverse_iterator it = data.rbegin(); number; ++it, --number) *it = pvDataCreate->createPVUnion(punion); size_t newLength = data.size(); const_svector cdata(freeze(data)); swap(cdata); return newLength; }
PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) : structure(structure), pvStructure(getPVDataCreate()->createPVStructure(structure)), bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields()))) { messagePrefix = ""; size_t nfields = pvStructure->getNumberFields(); postHandler.resize(nfields); PVFieldPtr pvField; for(size_t i =0; i<nfields; ++i) { postHandler[i] = PostHandlerPtr(new PvaClientPostHandlerPvt(this, i)); if(i==0) { pvField = pvStructure; } else { pvField = pvStructure->getSubField(i); } pvField->setPostHandler(postHandler[i]); } pvValue = pvStructure->getSubField("value"); }
RecordListRecordPtr RecordListRecord::create( std::string const & recordName) { FieldCreatePtr fieldCreate = getFieldCreate(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> addNestedStructure("argument")-> add("database",pvString)-> add("regularExpression",pvString)-> endNested()-> addNestedStructure("result") -> add("status",pvString) -> addArray("names",pvString) -> endNested()-> createStructure(); PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); RecordListRecordPtr pvRecord( new RecordListRecord(recordName,pvStructure)); if(!pvRecord->init()) pvRecord.reset(); return pvRecord; }
ExampleHelloPtr ExampleHello::create( string const & recordName) { StandardFieldPtr standardField = getStandardField(); FieldCreatePtr fieldCreate = getFieldCreate(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); StructureConstPtr topStructure = fieldCreate->createFieldBuilder()-> addNestedStructure("argument")-> add("value",pvString)-> endNested()-> addNestedStructure("result") -> add("value",pvString) -> add("timeStamp",standardField->timeStamp()) -> endNested()-> createStructure(); PVStructurePtr pvStructure = pvDataCreate->createPVStructure(topStructure); ExampleHelloPtr pvRecord( new ExampleHello(recordName,pvStructure)); if(!pvRecord->init()) pvRecord.reset(); return pvRecord; }
/** * Creates an NTURI request. * * @param path the value of the NTURI path field * @param fieldnames the names of fields in the NTURI query * @return values the values of fields in the NTURI query */ PVStructurePtr createRequest(const std::string & path, const std::vector<std::string> & fieldnames, const std::vector<std::string> & values) { StructureConstPtr archiverStructure = makeRequestStructure(*getFieldCreate(), fieldnames); PVStructurePtr request(getPVDataCreate()->createPVStructure(archiverStructure)); // set scheme. request->getStringField("scheme")->put("pva"); // set path. request->getStringField("path")->put(path); // Set query. PVStructurePtr query = request->getStructureField("query"); for (size_t i = 0; i < fieldnames.size(); ++i) { query->getStringField(fieldnames[i])->put(values[i]); } return request; }
PVStructurePtr createPowerSupply() { FieldCreatePtr fieldCreate = getFieldCreate(); StandardFieldPtr standardField = getStandardField(); PVDataCreatePtr pvDataCreate = getPVDataCreate(); return pvDataCreate->createPVStructure( fieldCreate->createFieldBuilder()-> add("alarm",standardField->alarm()) -> add("timeStamp",standardField->timeStamp()) -> addNestedStructure("power") -> add("value",pvDouble) -> add("alarm",standardField->alarm()) -> endNested()-> addNestedStructure("voltage") -> add("value",pvDouble) -> add("alarm",standardField->alarm()) -> endNested()-> addNestedStructure("current") -> add("value",pvDouble) -> add("alarm",standardField->alarm()) -> endNested()-> createStructure()); }
namespace epics { namespace pvaClient { static ConvertPtr convert = getConvert(); static FieldCreatePtr fieldCreate = getFieldCreate(); static PVDataCreatePtr pvDataCreate = getPVDataCreate(); static StandardFieldPtr standardField = getStandardField(); PvaClientMultiMonitorDoublePtr PvaClientMultiMonitorDouble::create( PvaClientMultiChannelPtr const &pvaMultiChannel, PvaClientChannelArray const &pvaClientChannelArray) { PvaClientMultiMonitorDoublePtr pvaClientMultiMonitorDouble( new PvaClientMultiMonitorDouble(pvaMultiChannel,pvaClientChannelArray)); return pvaClientMultiMonitorDouble; } PvaClientMultiMonitorDouble::PvaClientMultiMonitorDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray) : pvaClientMultiChannel(pvaClientMultiChannel), pvaClientChannelArray(pvaClientChannelArray), nchannel(pvaClientChannelArray.size()), doubleValue(shared_vector<double>(nchannel,epicsNAN)), pvaClientMonitor(std::vector<PvaClientMonitorPtr>(nchannel,PvaClientMonitorPtr())), isMonitorConnected(false), isDestroyed(false) { } PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble() { destroy(); } void PvaClientMultiMonitorDouble::destroy() { { Lock xx(mutex); if(isDestroyed) return; isDestroyed = true; } pvaClientChannelArray.clear(); } void PvaClientMultiMonitorDouble::connect() { shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected(); string request = "value"; for(size_t i=0; i<nchannel; ++i) { if(isConnected[i]) { pvaClientMonitor[i] = pvaClientChannelArray[i]->createMonitor(request); pvaClientMonitor[i]->issueConnect(); } } for(size_t i=0; i<nchannel; ++i) { if(isConnected[i]) { Status status = pvaClientMonitor[i]->waitConnect(); if(status.isOK()) continue; string message = string("channel ") + pvaClientChannelArray[i]->getChannelName() + " PvaChannelMonitor::waitConnect " + status.getMessage(); throw std::runtime_error(message); } } for(size_t i=0; i<nchannel; ++i) { if(isConnected[i]) pvaClientMonitor[i]->start(); } isMonitorConnected = true; } bool PvaClientMultiMonitorDouble::poll() { if(!isMonitorConnected){ connect(); epicsThreadSleep(.01); } bool result = false; shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; i<nchannel; ++i) { if(isConnected[i]) { if(pvaClientMonitor[i]->poll()) { doubleValue[i] = pvaClientMonitor[i]->getData()->getDouble(); pvaClientMonitor[i]->releaseEvent(); result = true; } } } return result; } bool PvaClientMultiMonitorDouble::waitEvent(double waitForEvent) { if(poll()) return true; TimeStamp start; start.getCurrent(); TimeStamp now; while(true) { epicsThreadSleep(.1); if(poll()) return true; now.getCurrent(); double diff = TimeStamp::diff(now,start); if(diff>=waitForEvent) break; } return false; } epics::pvData::shared_vector<double> PvaClientMultiMonitorDouble::get() { return doubleValue; } }}
PVStructurePtr NTScalarBuilder::createPVStructure() { return getPVDataCreate()->createPVStructure(createStructure()); }
namespace epics { namespace pvaClient { static ConvertPtr convert = getConvert(); static FieldCreatePtr fieldCreate = getFieldCreate(); static PVDataCreatePtr pvDataCreate = getPVDataCreate(); static StandardFieldPtr standardField = getStandardField(); static CreateRequest::shared_pointer createRequest = CreateRequest::create(); PvaClientMultiPutDoublePtr PvaClientMultiPutDouble::create( PvaClientMultiChannelPtr const &pvaMultiChannel, PvaClientChannelArray const &pvaClientChannelArray) { PvaClientMultiPutDoublePtr pvaClientMultiPutDouble( new PvaClientMultiPutDouble(pvaMultiChannel,pvaClientChannelArray)); return pvaClientMultiPutDouble; } PvaClientMultiPutDouble::PvaClientMultiPutDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray) : pvaClientMultiChannel(pvaClientMultiChannel), pvaClientChannelArray(pvaClientChannelArray), nchannel(pvaClientChannelArray.size()), pvaClientPut(std::vector<PvaClientPutPtr>(nchannel,PvaClientPutPtr())), isPutConnected(false), isDestroyed(false) { } PvaClientMultiPutDouble::~PvaClientMultiPutDouble() { destroy(); } void PvaClientMultiPutDouble::destroy() { { Lock xx(mutex); if(isDestroyed) return; isDestroyed = true; } pvaClientChannelArray.clear(); } void PvaClientMultiPutDouble::connect() { shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; i<nchannel; ++i) { if(isConnected[i]) { pvaClientPut[i] = pvaClientChannelArray[i]->createPut(); pvaClientPut[i]->issueConnect(); } } for(size_t i=0; i<nchannel; ++i) { if(isConnected[i]) { Status status = pvaClientPut[i]->waitConnect(); if(status.isOK()) continue; string message = string("channel ") + pvaClientChannelArray[i]->getChannelName() + " PvaChannelPut::waitConnect " + status.getMessage(); throw std::runtime_error(message); } } isPutConnected = true; } void PvaClientMultiPutDouble::put(epics::pvData::shared_vector<double> const &data) { if(!isPutConnected) connect(); if(data.size()!=nchannel) { throw std::runtime_error("data has wrong size"); } shared_vector<epics::pvData::boolean> isConnected = pvaClientMultiChannel->getIsConnected(); for(size_t i=0; i<nchannel; ++i) { if(isConnected[i]) { PVStructurePtr pvTop = pvaClientPut[i]->getData()->getPVStructure(); PVScalarPtr pvValue = pvTop->getSubField<PVScalar>("value"); convert->fromDouble(pvValue,data[i]); pvaClientPut[i]->issuePut(); } if(isConnected[i]) { Status status = pvaClientPut[i]->waitPut(); if(status.isOK()) continue; string message = string("channel ") + pvaClientChannelArray[i]->getChannelName() + " PvaChannelPut::waitPut " + status.getMessage(); throw std::runtime_error(message); } } } }}
PVStructurePtr NTNDArrayBuilder::createPVStructure() { return getPVDataCreate()->createPVStructure(createStructure()); }
namespace epics { namespace nt { static NTFieldPtr ntField = NTField::get(); namespace detail { static FieldCreatePtr fieldCreate = getFieldCreate(); static PVDataCreatePtr pvDataCreate = getPVDataCreate(); static Mutex mutex; StructureConstPtr NTNDArrayBuilder::createStructure() { 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; Lock xx(mutex); static StructureConstPtr ntndarrayStruc[NUMBER_OF_STRUCTURES]; static UnionConstPtr valueType; static StructureConstPtr codecStruc; static StructureConstPtr dimensionStruc; static StructureConstPtr attributeStruc; StructureConstPtr returnedStruc; size_t index = 0; if (descriptor) index |= 1 << DISCRIPTOR_INDEX; if (timeStamp) index |= 1 << TIMESTAMP_INDEX; if (alarm) index |= 1 << ALARM_INDEX; if (display) index |= 1 << DISPLAY_INDEX; bool isExtended = !extraFieldNames.empty(); if (isExtended || !ntndarrayStruc[index]) { StandardFieldPtr standardField = getStandardField(); FieldBuilderPtr fb = fieldCreate->createFieldBuilder(); if (!valueType) { 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(); } if (!codecStruc) { codecStruc = fb->setId("codec_t")-> add("name", pvString)-> add("parameters", fieldCreate->createVariantUnion())-> createStructure(); } if (!dimensionStruc) { dimensionStruc = fb->setId("dimension_t")-> add("size", pvInt)-> add("offset", pvInt)-> add("fullSize", pvInt)-> add("binning", pvInt)-> add("reverse", pvBoolean)-> createStructure(); } if (!attributeStruc) { attributeStruc = NTNDArrayAttribute::createBuilder()->createStructure(); } fb->setId(NTNDArray::URI)-> add("value", valueType)-> add("codec", codecStruc)-> add("compressedSize", pvLong)-> add("uncompressedSize", pvLong)-> addArray("dimension", dimensionStruc)-> add("uniqueId", pvInt)-> add("dataTimeStamp", standardField->timeStamp())-> addArray("attribute", attributeStruc); if (descriptor) fb->add("descriptor", pvString); if (alarm) fb->add("alarm", standardField->alarm()); if (timeStamp) fb->add("timeStamp", standardField->timeStamp()); if (display) fb->add("display", standardField->display()); size_t extraCount = extraFieldNames.size(); for (size_t i = 0; i< extraCount; i++) fb->add(extraFieldNames[i], extraFields[i]); returnedStruc = fb->createStructure(); if (!isExtended) ntndarrayStruc[index] = returnedStruc; } else { return ntndarrayStruc[index]; } return returnedStruc; } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addDescriptor() { descriptor = true; return shared_from_this(); } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addAlarm() { alarm = true; return shared_from_this(); } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addTimeStamp() { timeStamp = true; return shared_from_this(); } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addDisplay() { display = true; return shared_from_this(); } PVStructurePtr NTNDArrayBuilder::createPVStructure() { return getPVDataCreate()->createPVStructure(createStructure()); } NTNDArrayPtr NTNDArrayBuilder::create() { return NTNDArrayPtr(new NTNDArray(createPVStructure())); } NTNDArrayBuilder::NTNDArrayBuilder() { reset(); } void NTNDArrayBuilder::reset() { descriptor = false; timeStamp = false; alarm = false; display = false; extraFieldNames.clear(); extraFields.clear(); } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::add(string const & name, FieldConstPtr const & field) { extraFields.push_back(field); extraFieldNames.push_back(name); return shared_from_this(); } } const std::string NTNDArray::URI("epics:nt/NTNDArray:1.0"); const std::string ntAttrStr("epics:nt/NTAttribute:1.0"); static FieldCreatePtr fieldCreate = getFieldCreate(); static PVDataCreatePtr pvDataCreate = getPVDataCreate(); class NTValueType { public: static bool isCompatible(UnionConstPtr const &u) { if(!u.get()) return false; if (u->getID() != Union::defaultId()) return false; if (u->isVariant()) return false; for (int i = pvBoolean; i != pvString; ++i) { ScalarType scalarType = static_cast<ScalarType>(i); std::string name(ScalarTypeFunc::name(scalarType)); name += "Value"; ScalarArrayConstPtr scalarField = u->getField<ScalarArray>(name); if (scalarField.get() == 0 || scalarField->getElementType() != scalarType) return false; } return true; } }; class NTCodec { public: static bool isCompatible(StructureConstPtr const &structure) { if(!structure.get()) return false; if (structure->getID() != "codec_t") return false; ScalarConstPtr scalarField = structure->getField<Scalar>("name"); if (scalarField.get() == 0 || scalarField->getScalarType() != pvString) return false; UnionConstPtr paramField = structure->getField<Union>("parameters"); if (paramField.get() == 0 || !paramField->isVariant()) return false; return true; } }; class NTDimension { public: static bool isCompatible(StructureConstPtr const &structure) { if(!structure.get()) return false; if (structure->getID() != "dimension_t") return false; ScalarConstPtr scalarField = structure->getField<Scalar>("size"); if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt) return false; scalarField = structure->getField<Scalar>("offset"); if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt) return false; scalarField = structure->getField<Scalar>("fullSize"); if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt) return false; scalarField = structure->getField<Scalar>("binning"); if (scalarField.get() == 0 || scalarField->getScalarType() != pvInt) return false; scalarField = structure->getField<Scalar>("reverse"); if (scalarField.get() == 0 || scalarField->getScalarType() != pvBoolean) return false; return true; } }; NTNDArray::shared_pointer NTNDArray::wrap(PVStructurePtr const & pvStructure) { if(!isCompatible(pvStructure)) return shared_pointer(); return wrapUnsafe(pvStructure); } NTNDArray::shared_pointer NTNDArray::wrapUnsafe(PVStructurePtr const & pvStructure) { return shared_pointer(new NTNDArray(pvStructure)); } bool NTNDArray::is_a(StructureConstPtr const & structure) { return NTUtils::is_a(structure->getID(), URI); } bool NTNDArray::isCompatible(StructureConstPtr const &structure) { if(!structure.get()) return false; UnionConstPtr valueField = structure->getField<Union>("value"); if(!NTValueType::isCompatible(valueField)) return false; StructureConstPtr codecField = structure->getField<Structure>("codec"); if(!NTCodec::isCompatible(codecField)) return false; ScalarConstPtr compressedSizeField = structure->getField<Scalar>("compressedSize"); if (compressedSizeField.get() == 0) return false; if (compressedSizeField->getScalarType() != pvLong) return false; ScalarConstPtr uncompressedSizeField = structure->getField<Scalar>("uncompressedSize"); if (uncompressedSizeField.get() == 0) return false; if (uncompressedSizeField->getScalarType() != pvLong) return false; StructureArrayConstPtr dimensionField = structure->getField<StructureArray>("dimension"); if (dimensionField.get() == 0) return false; StructureConstPtr dimElementStruc = dimensionField->getStructure(); if(!NTDimension::isCompatible(dimElementStruc)) return false; NTFieldPtr ntField = NTField::get(); StructureConstPtr dataTimeStampField = structure->getField<Structure>( "dataTimeStamp"); if (dataTimeStampField.get() == 0 || !ntField->isTimeStamp(dataTimeStampField)) return false; ScalarConstPtr uniqueIdField = structure->getField<Scalar>("uniqueId"); if (uniqueIdField.get() == 0) return false; if (uniqueIdField->getScalarType() != pvInt) return false; StructureArrayConstPtr attributeField = structure->getField<StructureArray>( "attribute"); StructureConstPtr attributeElementStruc = attributeField->getStructure(); if (!NTNDArrayAttribute::isCompatible(attributeElementStruc)) return false; FieldConstPtr field = structure->getField("descriptor"); if (field.get()) { ScalarConstPtr descriptorField = structure->getField<Scalar>("descriptor"); if (!descriptorField.get() || descriptorField->getScalarType() != pvString) return false; } field = structure->getField("alarm"); if (field.get() && !ntField->isAlarm(field)) return false; field = structure->getField("timeStamp"); if (field.get() && !ntField->isTimeStamp(field)) return false; field = structure->getField("display"); if (field.get() && !ntField->isDisplay(field)) return false; return true; } bool NTNDArray::isCompatible(PVStructurePtr const & pvStructure) { if(!pvStructure.get()) return false; return isCompatible(pvStructure->getStructure()); } bool NTNDArray::isValid() { int64 valueSize = getValueSize(); int64 compressedSize = getCompressedDataSize()->get(); if (valueSize != compressedSize) return false; long expectedUncompressed = getExpectedUncompressedSize(); long uncompressedSize = getUncompressedDataSize()->get(); if (uncompressedSize != expectedUncompressed) return false; std::string codecName = getCodec()->getSubField<PVString>("name")->get(); if (codecName == "" && valueSize < uncompressedSize) return false; return true; } int64 NTNDArray::getExpectedUncompressedSize() { int64 size = 0; PVStructureArrayPtr pvDim = getDimension(); if (pvDim->getLength() != 0) { PVStructureArray::const_svector data = pvDim->view(); size = getValueTypeSize(); for (PVStructureArray::const_svector::const_iterator it = data.begin(); it != data.end(); ++it ) { PVStructurePtr dim = *it; size *= dim->getSubField<PVInt>("size")->get(); } } return size; } int64 NTNDArray::getValueSize() { int64 size = 0; PVScalarArrayPtr storedValue = getValue()->get<PVScalarArray>(); if (!storedValue.get()) { size = storedValue->getLength()*getValueTypeSize(); } return size; } int64 NTNDArray::getValueTypeSize() { int64 typeSize = 0; PVScalarArrayPtr storedValue = getValue()->get<PVScalarArray>(); if (storedValue.get()) { switch (storedValue->getScalarArray()->getElementType()) { case pvBoolean: case pvByte: case pvUByte: typeSize = 1; break; case pvShort: case pvUShort: typeSize = 2; break; case pvInt: case pvUInt: case pvFloat: typeSize = 4; break; case pvLong: case pvULong: case pvDouble: typeSize = 8; break; default: break; } } return typeSize; } NTNDArrayBuilderPtr NTNDArray::createBuilder() { return NTNDArrayBuilderPtr(new detail::NTNDArrayBuilder()); } 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; } bool NTNDArray::attachDisplay(PVDisplay &pvDisplay) const { PVStructurePtr dp = getDisplay(); if (dp) return pvDisplay.attach(dp); else return false; } PVStructurePtr NTNDArray::getPVStructure() const { return pvNTNDArray; } PVUnionPtr NTNDArray::getValue() const { return pvNTNDArray->getSubField<PVUnion>("value"); } PVStructurePtr NTNDArray::getCodec() const { return pvNTNDArray->getSubField<PVStructure>("codec"); } PVLongPtr NTNDArray::getCompressedDataSize() const { return pvNTNDArray->getSubField<PVLong>("compressedSize"); } PVLongPtr NTNDArray::getUncompressedDataSize() const { return pvNTNDArray->getSubField<PVLong>("uncompressedSize"); } PVStructureArrayPtr NTNDArray::getDimension() const { return pvNTNDArray->getSubField<PVStructureArray>("dimension"); } PVIntPtr NTNDArray::getUniqueId() const { return pvNTNDArray->getSubField<PVInt>("uniqueId"); } PVStructurePtr NTNDArray::getDataTimeStamp() const { return pvNTNDArray->getSubField<PVStructure>("dataTimeStamp"); } PVStructureArrayPtr NTNDArray::getAttribute() const { return pvNTNDArray->getSubField<PVStructureArray>("attribute"); } 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"); } PVStructurePtr NTNDArray::getDisplay() const { return pvNTNDArray->getSubField<PVStructure>("display"); } NTNDArray::NTNDArray(PVStructurePtr const & pvStructure) : pvNTNDArray(pvStructure) {} }}
PVStructurePtr NTMatrixBuilder::createPVStructure() { return getPVDataCreate()->createPVStructure(createStructure()); }
namespace detail { static FieldCreatePtr fieldCreate = getFieldCreate(); static PVDataCreatePtr pvDataCreate = getPVDataCreate(); static Mutex mutex; StructureConstPtr NTNDArrayBuilder::createStructure() { 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; Lock xx(mutex); static StructureConstPtr ntndarrayStruc[NUMBER_OF_STRUCTURES]; static UnionConstPtr valueType; static StructureConstPtr codecStruc; static StructureConstPtr dimensionStruc; static StructureConstPtr attributeStruc; StructureConstPtr returnedStruc; size_t index = 0; if (descriptor) index |= 1 << DISCRIPTOR_INDEX; if (timeStamp) index |= 1 << TIMESTAMP_INDEX; if (alarm) index |= 1 << ALARM_INDEX; if (display) index |= 1 << DISPLAY_INDEX; bool isExtended = !extraFieldNames.empty(); if (isExtended || !ntndarrayStruc[index]) { StandardFieldPtr standardField = getStandardField(); FieldBuilderPtr fb = fieldCreate->createFieldBuilder(); if (!valueType) { 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(); } if (!codecStruc) { codecStruc = fb->setId("codec_t")-> add("name", pvString)-> add("parameters", fieldCreate->createVariantUnion())-> createStructure(); } if (!dimensionStruc) { dimensionStruc = fb->setId("dimension_t")-> add("size", pvInt)-> add("offset", pvInt)-> add("fullSize", pvInt)-> add("binning", pvInt)-> add("reverse", pvBoolean)-> createStructure(); } if (!attributeStruc) { attributeStruc = NTNDArrayAttribute::createBuilder()->createStructure(); } fb->setId(NTNDArray::URI)-> add("value", valueType)-> add("codec", codecStruc)-> add("compressedSize", pvLong)-> add("uncompressedSize", pvLong)-> addArray("dimension", dimensionStruc)-> add("uniqueId", pvInt)-> add("dataTimeStamp", standardField->timeStamp())-> addArray("attribute", attributeStruc); if (descriptor) fb->add("descriptor", pvString); if (alarm) fb->add("alarm", standardField->alarm()); if (timeStamp) fb->add("timeStamp", standardField->timeStamp()); if (display) fb->add("display", standardField->display()); size_t extraCount = extraFieldNames.size(); for (size_t i = 0; i< extraCount; i++) fb->add(extraFieldNames[i], extraFields[i]); returnedStruc = fb->createStructure(); if (!isExtended) ntndarrayStruc[index] = returnedStruc; } else { return ntndarrayStruc[index]; } return returnedStruc; } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addDescriptor() { descriptor = true; return shared_from_this(); } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addAlarm() { alarm = true; return shared_from_this(); } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addTimeStamp() { timeStamp = true; return shared_from_this(); } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::addDisplay() { display = true; return shared_from_this(); } PVStructurePtr NTNDArrayBuilder::createPVStructure() { return getPVDataCreate()->createPVStructure(createStructure()); } NTNDArrayPtr NTNDArrayBuilder::create() { return NTNDArrayPtr(new NTNDArray(createPVStructure())); } NTNDArrayBuilder::NTNDArrayBuilder() { reset(); } void NTNDArrayBuilder::reset() { descriptor = false; timeStamp = false; alarm = false; display = false; extraFieldNames.clear(); extraFields.clear(); } NTNDArrayBuilder::shared_pointer NTNDArrayBuilder::add(string const & name, FieldConstPtr const & field) { extraFields.push_back(field); extraFieldNames.push_back(name); return shared_from_this(); } }
PVStructurePtr NTNameValueBuilder::createPVStructure() { return getPVDataCreate()->createPVStructure(createStructure()); }
namespace epics { namespace nt { static FieldCreatePtr fieldCreate = getFieldCreate(); static PVDataCreatePtr pvDataCreate = getPVDataCreate(); static NTFieldPtr ntField = NTField::get(); namespace detail { NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::value(UnionConstPtr valuePtr) { valueType = valuePtr; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addDescriptor() { descriptor = true; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addAlarm() { alarm = true; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addTimeStamp() { timeStamp = true; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addSeverity() { severity = true; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addStatus() { status = true; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addMessage() { message = true; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addSecondsPastEpoch() { secondsPastEpoch = true; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addNanoseconds() { nanoseconds = true; return shared_from_this(); } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::addUserTag() { userTag = true; return shared_from_this(); } StructureConstPtr NTMultiChannelBuilder::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"; if(valueType) { fields[ind++] = fieldCreate->createUnionArray(valueType); } else { fields[ind++] = fieldCreate->createVariantUnionArray(); } names[ind] = "channelName"; fields[ind++] = fieldCreate->createScalarArray(pvString); names[ind] = "isConnected"; fields[ind++] = fieldCreate->createScalarArray(pvBoolean); if(timeStamp) { names[ind] = "timeStamp"; fields[ind++] = standardField->timeStamp(); } if(alarm) { names[ind] = "alarm"; fields[ind++] = standardField->alarm(); } if(descriptor) { names[ind] = "descriptor"; fields[ind++] = fieldCreate->createScalar(pvString); } 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(NTMultiChannel::URI,names,fields); reset(); return st; } PVStructurePtr NTMultiChannelBuilder::createPVStructure() { return pvDataCreate->createPVStructure(createStructure()); } NTMultiChannelPtr NTMultiChannelBuilder::create() { return NTMultiChannelPtr(new NTMultiChannel(createPVStructure())); } NTMultiChannelBuilder::NTMultiChannelBuilder() { reset(); } void NTMultiChannelBuilder::reset() { valueType.reset(); extraFieldNames.clear(); extraFields.clear(); descriptor = false; alarm = false; timeStamp = false; severity = false; status = false; message = false; secondsPastEpoch = false; nanoseconds = false; userTag = false; } NTMultiChannelBuilder::shared_pointer NTMultiChannelBuilder::add(string const & name, FieldConstPtr const & field) { extraFields.push_back(field); extraFieldNames.push_back(name); return shared_from_this(); } } const std::string NTMultiChannel::URI("epics:nt/NTMultiChannel:1.0"); NTMultiChannel::shared_pointer NTMultiChannel::wrap(PVStructurePtr const & structure) { if(!isCompatible(structure)) return shared_pointer(); return wrapUnsafe(structure); } NTMultiChannel::shared_pointer NTMultiChannel::wrapUnsafe(PVStructurePtr const & structure) { return shared_pointer(new NTMultiChannel(structure)); } bool NTMultiChannel::is_a(StructureConstPtr const &structure) { return NTUtils::is_a(structure->getID(), URI); } bool NTMultiChannel::isCompatible(PVStructurePtr const &pvStructure) { if(!pvStructure) return false; PVUnionArrayPtr pvValue = pvStructure->getSubField<PVUnionArray>("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; } NTMultiChannelBuilderPtr NTMultiChannel::createBuilder() { return NTMultiChannelBuilderPtr(new detail::NTMultiChannelBuilder()); } NTMultiChannel::NTMultiChannel(PVStructurePtr const & pvStructure) : pvNTMultiChannel(pvStructure), pvTimeStamp(pvStructure->getSubField<PVStructure>("timeStamp")), pvAlarm(pvStructure->getSubField<PVStructure>("alarm")), pvValue(pvStructure->getSubField<PVUnionArray>("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 NTMultiChannel::attachTimeStamp(PVTimeStamp &pv) const { if(!pvTimeStamp) return; pv.attach(pvTimeStamp); } void NTMultiChannel::attachAlarm(PVAlarm &pv) const { if(!pvAlarm) return; pv.attach(pvAlarm); } }}
StandardPVField::StandardPVField() : standardField(getStandardField()), fieldCreate(getFieldCreate()), pvDataCreate(getPVDataCreate()), notImplemented("not implemented") {}
PVStructurePtr NTAttributeBuilder::createPVStructure() { return getPVDataCreate()->createPVStructure(createStructure()); }
PVStructurePtr NTHistogramBuilder::createPVStructure() { return getPVDataCreate()->createPVStructure(createStructure()); }