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;
    }
}
Beispiel #3
0
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);
}
Beispiel #8
0
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;
}
Beispiel #11
0
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;
}
Beispiel #12
0
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]);
    }
}
Beispiel #13
0
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;
}


}}
Beispiel #20
0
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);
}

}}
Beispiel #28
0
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());
}