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;
}
bool NTTable::isCompatible(PVStructurePtr const & pvStructure)
{
    if(!pvStructure) return false;
    PVFieldPtr pvField = pvStructure->getSubField("alarm");
    if(pvField && !ntField->isAlarm(pvField->getField())) return false;
    pvField = pvStructure->getSubField("timeStamp");
    if(pvField && !ntField->isTimeStamp(pvField->getField())) return false;
    PVStringArrayPtr pvLabel = pvStructure->getSubField<PVStringArray>("labels");
    if(!pvLabel) return false;
    return true;
}
bool ExampleLink::init()
{
    initPVRecord();

    PVStructurePtr pvStructure = getPVRecordStructure()->getPVStructure();
    pvTimeStamp.attach(pvStructure->getSubField("timeStamp"));
    pvAlarm.attach(pvStructure->getSubField("alarm"));
    pvValue = pvStructure->getSubField<PVDoubleArray>("value");
    if(!pvValue) {
        return false;
    }
    ChannelProvider::shared_pointer provider =
        getChannelProviderRegistry()->getProvider(providerName);
    if(!provider) {
        cout << getRecordName() << " provider "
             << providerName << " does not exist" << endl;
        return false;
    }
    ChannelRequester::shared_pointer channelRequester =
        dynamic_pointer_cast<ChannelRequester>(getPtrSelf());
    channel = provider->createChannel(channelName,channelRequester);
    event.wait();
    if(!status.isOK()) {
        cout << getRecordName() << " createChannel failed "
             << status.getMessage() << endl;
        return false;
    }
    ChannelGetRequester::shared_pointer channelGetRequester =
        dynamic_pointer_cast<ChannelGetRequester>(getPtrSelf());
    PVStructurePtr pvRequest = CreateRequest::create()->createRequest(
                                   "value,alarm,timeStamp");
    channelGet = channel->createChannelGet(channelGetRequester,pvRequest);
    event.wait();
    if(!status.isOK()) {
        cout << getRecordName() << " createChannelGet failed "
             << status.getMessage() << endl;
        return false;
    }
    getPVValue = getPVStructure->getSubField<PVDoubleArray>("value");
    if(!getPVValue) {
        cout << getRecordName() << " get value not  PVDoubleArray" << endl;
        return false;
    }
    MonitorRequester::shared_pointer  monitorRequester =
        dynamic_pointer_cast<MonitorRequester>(getPtrSelf());
    monitor = channel->createMonitor(monitorRequester,pvRequest);
    return true;
}
string PvaClientData::getString()
{
    if(PvaClient::getDebug()) cout << "PvaClientData::getString\n";
    PVScalarPtr pvScalar;
    PVStructurePtr pvStructure = getPVStructure();
    PVFieldPtr pvValue  = pvStructure->getSubField("value");
    if(pvValue) {
        Type type = pvValue->getField()->getType();
        if(type==scalar) pvScalar = static_pointer_cast<PVScalar>(pvValue);
    }
    if(!pvScalar) {
        while(true) {
             const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
             if(fieldPtrArray.size()!=1) {
                  throw std::logic_error(
                      "PvaClientData::getString() pvRequest for multiple fields");
             }
             PVFieldPtr pvField(fieldPtrArray[0]);
             Type type = pvField->getField()->getType();
             if(type==scalar) {
                 pvScalar = static_pointer_cast<PVScalar>(pvField);
                 break;
             }
             if(pvField->getField()->getType()!=epics::pvData::structure) break;
             pvStructure = static_pointer_cast<PVStructure>(pvField);
        }
    }
    if(!pvScalar) {
        throw std::logic_error(
            "PvaClientData::getString() did not find a scalar field");
    }
    return convert->toString(pvScalar);
}
bool NTScalar::isCompatible(PVStructurePtr const & pvStructure)
{
    if(!pvStructure) return false;
    PVScalarPtr pvValue = pvStructure->getSubField<PVScalar>("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("display");
    if(pvField && !ntField->isDisplay(pvField->getField())) return false;
    pvField = pvStructure->getSubField("control");
    if(pvField && !ntField->isControl(pvField->getField())) return false;
    return true;
}
bool PowerSupply::init()
{
    initPVRecord();
    PVStructurePtr pvStructure = getPVStructure();
    PVFieldPtr pvField;
    bool result;
    pvField = pvStructure->getSubField("timeStamp");
    if(!pvField) {
        cerr << "no timeStamp" << endl;
        return false;
    }
    result = pvTimeStamp.attach(pvField);
    if(!result) {
        cerr << "no timeStamp" << endl;
        return false;
    }
    pvField = pvStructure->getSubField("alarm");
    if(!pvField) {
        cerr << "no alarm" << endl;
        return false;
    }
    result = pvAlarm.attach(pvField);
    if(!result) {
        cerr << "no alarm" << endl;
        return false;
    }
    pvCurrent = pvStructure->getSubField<PVDouble>("current.value");
    if(!pvCurrent) {
        cerr << "no current\n";
        return false;
    }
    pvVoltage = pvStructure->getSubField<PVDouble>("voltage.value");
    if(!pvVoltage) {
        cerr << "no current\n";
        return false;
    }
    pvPower = pvStructure->getSubField<PVDouble>("power.value");
    if(!pvPower) {
        cerr << "no powert\n";
        return false;
    }
    return true;
}
static bool checkBitSetPVField(
    PVFieldPtr const &pvField,BitSetPtr const &bitSet,int32 initialOffset)
{
    int32 offset = initialOffset;
    int32 nbits = static_cast<int32>(pvField->getNumberFields());
    if(nbits==1) return bitSet->get(offset);
    int32 nextSetBit = bitSet->nextSetBit(offset);
    if(nextSetBit>=(offset+nbits)) return false;
    if(nextSetBit<0) return false;
    if(bitSet->get(offset)) {
        if(nbits>1) {
            for(int32 i=offset+1; i<offset+nbits; i++) bitSet->clear(i);
        }
        return true;
    }

    bool atLeastOneBitSet = false;
    bool allBitsSet = true;
    PVStructurePtr pvStructure = static_pointer_cast<PVStructure>(pvField);
    offset = static_cast<int32>(pvStructure->getFieldOffset()) + 1;
    while(offset<initialOffset + nbits) {
        PVFieldPtr pvSubField = pvStructure->getSubField(offset);
        int32 nbitsNow = static_cast<int32>(pvSubField->getNumberFields());
        if(nbitsNow==1) {
            if(bitSet->get(offset)) {
                atLeastOneBitSet = true;
            } else {
                allBitsSet = false;
            }
            offset++;
        } else {
            bool result = checkBitSetPVField(pvSubField,bitSet,offset);
            if(result) {
                atLeastOneBitSet = true;
                if(!bitSet->get(offset)) {
                    allBitsSet = false;
                }
            } else {
                allBitsSet = false;
            }
            offset += static_cast<int32>(pvSubField->getNumberFields());
        }
    }
    if(allBitsSet) {
        if(nbits>1) {
            for(int32 i=initialOffset+1; i<initialOffset+nbits; i++) {
                bitSet->clear(i);
            }
        }
        bitSet->set(initialOffset);
    }
    return atLeastOneBitSet;
}
void PowerSupplyRecord::initPvt()
{
    initPVRecord();
    PVStructurePtr pvStructure = getPVStructure();
    PVFieldPtr pvField;
    pvField = pvStructure->getSubField("alarm");
    pvAlarm.attach(pvField);
    pvCurrent = pvStructure->getSubField<PVDouble>("current.value");
    pvVoltage = pvStructure->getSubField<PVDouble>("voltage.value");
    pvPower = pvStructure->getSubField<PVDouble>("power.value");
    alarm.setMessage("bad voltage");
    alarm.setSeverity(majorAlarm);
    pvAlarm.set(alarm);
}
shared_vector<const double> PvaClientData::getDoubleArray()
{
    if(PvaClient::getDebug()) cout << "PvaClientData::getDoubleArray\n";
    PVScalarArrayPtr pvScalarArray;
    PVStructurePtr pvStructure = getPVStructure();
    PVFieldPtr pvValue  = pvStructure->getSubField("value");
    if(pvValue) {
        Type type = pvValue->getField()->getType();
        if(type==scalarArray) {
            pvScalarArray = static_pointer_cast<PVScalarArray>(pvValue);
        }
    }
    if(!pvScalarArray) {
        while(true) {
             const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields());
             if(fieldPtrArray.size()!=1) {
                  throw std::logic_error(
                      "PvaClientData::getDoubleArray() pvRequest for multiple fields");
             }
             PVFieldPtr pvField(fieldPtrArray[0]);
             Type type = pvField->getField()->getType();
             if(type==scalarArray) {
                 pvScalarArray = static_pointer_cast<PVScalarArray>(pvField);
                 break;
             }
             if(pvField->getField()->getType()!=epics::pvData::structure) break;
             pvStructure = static_pointer_cast<PVStructure>(pvField);
        }
    }
    if(!pvScalarArray) {
        throw std::logic_error(
            "PvaClientData::getDoubleArray() did not find a scalarArray field");
    }
    ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType();
    if(!ScalarTypeFunc::isNumeric(scalarType)) {
        throw std::logic_error(
            "PvaClientData::getDoubleArray() did not find a numeric scalarArray field");
    }
    shared_vector<const double> retValue;
    pvScalarArray->getAs<const double>(retValue);
    return retValue;
}
bool RecordListRecord::init()
{
    initPVRecord();
    PVStructurePtr pvStructure = getPVStructure();
    database = pvStructure->getStringField("argument.database");
    if(database.get()==NULL) return false;
    regularExpression = pvStructure->getStringField(
        "argument.regularExpression");
    if(regularExpression.get()==NULL) return false;
    status = pvStructure->getStringField("result.status");
    if(status.get()==NULL) return false;
    PVFieldPtr pvField = pvStructure->getSubField("result.names");
    if(pvField.get()==NULL) {
        std::cerr << "no result.names" << std::endl;
        return false;
    }
    name = static_pointer_cast<PVStringArray>(
         pvStructure->getScalarArrayField("result.names",pvString));
    if(name.get()==NULL) return false;
    return true;
}
bool PowerSupplyRecord::init()
{
    initPVRecord();
    PVStructurePtr pvStructure = getPVStructure();
    PVFieldPtr pvField;
    bool result;
    pvField = pvStructure->getSubField("alarm");
    if(!pvField) {
        cerr << "no alarm" << endl;
        return false;
    }
    result = pvAlarm.attach(pvField);
    if(!result) {
        cerr << "no alarm" << endl;
        return false;
    }
    pvCurrent = pvStructure->getSubField<PVDouble>("current.value");
    if(!pvCurrent) {
        cerr << "no current\n";
        return false;
    }
    pvVoltage = pvStructure->getSubField<PVDouble>("voltage.value");
    if(!pvVoltage) {
        cerr << "no current\n";
        return false;
    }
    pvPower = pvStructure->getSubField<PVDouble>("power.value");
    if(!pvPower) {
        cerr << "no power\n";
        return false;
    }
    alarm.setMessage("bad voltage");
    alarm.setSeverity(majorAlarm);
    pvAlarm.set(alarm);
    return true;
}
static void testPVScalar(
    string const & valueNameRecord,
    string const & valueNameCopy,
    PVRecordPtr const & pvRecord,
    PVCopyPtr const & pvCopy)
{
    PVStructurePtr pvStructureRecord;
    PVStructurePtr pvStructureCopy;
    PVFieldPtr pvField;
    PVScalarPtr pvValueRecord;
    PVScalarPtr pvValueCopy;
    BitSetPtr bitSet;
    size_t offset;
    ConvertPtr convert = getConvert();

    cout << endl;
    pvStructureRecord = pvRecord->getPVRecordStructure()->getPVStructure();
    pvField = pvStructureRecord->getSubField(valueNameRecord);
    pvValueRecord = static_pointer_cast<PVScalar>(pvField);
    convert->fromDouble(pvValueRecord,.04);
    StructureConstPtr structure = pvCopy->getStructure();
    cout << "structure from copy" << endl << *structure << endl;
    pvStructureCopy = pvCopy->createPVStructure();
    pvField = pvStructureCopy->getSubField(valueNameCopy);
    pvValueCopy = static_pointer_cast<PVScalar>(pvField);
    bitSet = BitSetPtr(new BitSet(pvStructureCopy->getNumberFields()));
    pvCopy->initCopy(pvStructureCopy, bitSet);
    cout << "after initCopy pvValueCopy " << convert->toDouble(pvValueCopy);
    cout << endl;
    convert->fromDouble(pvValueRecord,.06);
    pvCopy->updateCopySetBitSet(pvStructureCopy,bitSet);
    cout << "after put(.06) pvValueCopy " << convert->toDouble(pvValueCopy);
    cout << " bitSet " << *bitSet;
    cout << endl;
    offset = pvCopy->getCopyOffset(pvValueRecord);
    cout << "getCopyOffset() " << offset;
    cout << " pvValueCopy->getOffset() " << pvValueCopy->getFieldOffset();
    cout << " pvValueRecord->getOffset() " << pvValueRecord->getFieldOffset();
    cout << " bitSet " << *bitSet;
    cout << endl;
    bitSet->clear();
    convert->fromDouble(pvValueRecord,1.0);
    cout << "before updateCopyFromBitSet";
    cout << " recordValue " << convert->toDouble(pvValueRecord);
    cout << " copyValue " << convert->toDouble(pvValueCopy);
    cout << " bitSet " << *bitSet;
    cout << endl;
    bitSet->set(0);
    pvCopy->updateCopyFromBitSet(pvStructureCopy,bitSet);
    cout << "after updateCopyFromBitSet";
    cout << " recordValue " << convert->toDouble(pvValueRecord);
    cout << " copyValue " << convert->toDouble(pvValueCopy);
    cout << " bitSet " << *bitSet;
    cout << endl;
    convert->fromDouble(pvValueCopy,2.0);
    bitSet->set(0);
    cout << "before updateMaster";
    cout << " recordValue " << convert->toDouble(pvValueRecord);
    cout << " copyValue " << convert->toDouble(pvValueCopy);
    cout << " bitSet " << *bitSet;
    cout << endl;
    pvCopy->updateMaster(pvStructureCopy,bitSet);
    cout << "after updateMaster";
    cout << " recordValue " << convert->toDouble(pvValueRecord);
    cout << " copyValue " << convert->toDouble(pvValueCopy);
    cout << " bitSet " << *bitSet;
    cout << endl;
}
Exemple #13
0
static void test()
{
    std::ostringstream oss;
    
    if(debug) printf("\ntestBitSetUtil\n");
    StringArray fieldNames;
    PVFieldPtrArray pvFields;
    fieldNames.reserve(5);
    pvFields.reserve(5);
    fieldNames.push_back("timeStamp");
    fieldNames.push_back("alarm");
    fieldNames.push_back("voltage");
    fieldNames.push_back("power");
    fieldNames.push_back("current");
    pvFields.push_back(
        pvDataCreate->createPVStructure(standardField->timeStamp()));
    pvFields.push_back(
        pvDataCreate->createPVStructure(standardField->alarm()));
    pvFields.push_back(
        pvDataCreate->createPVStructure(
            standardField->scalar(pvDouble,"alarm")));
    pvFields.push_back(
        pvDataCreate->createPVStructure(
            standardField->scalar(pvDouble,"alarm")));
    pvFields.push_back(
        pvDataCreate->createPVStructure(
            standardField->scalar(pvDouble,"alarm")));
    PVStructurePtr pvs =  pvDataCreate->createPVStructure(
         fieldNames,pvFields);
    if(debug) {
        oss.clear();
        oss << "pvs" << std::endl;
        oss << *pvs << std::endl;
        std::cout << oss.str();
    }     
    int32 nfields = (int32)pvs->getNumberFields();
    BitSetPtr bitSet = BitSet::create(nfields);
    for(int32 i=0; i<nfields; i++) bitSet->set(i);
    if(debug) {
        oss.clear();
        oss << "bitSet" << std::endl;
        oss << *bitSet << std::endl;
        std::cout << oss.str();
    }     
    BitSetUtil::compress(bitSet,pvs);
    if(debug) {
        oss.clear();
        oss << "bitSet" << std::endl;
        oss << *bitSet << std::endl;
        std::cout << oss.str();
    }     
    bitSet->clear();
    PVFieldPtr pvField = pvs->getSubField("timeStamp");
    int32 offsetTimeStamp = (int32)pvField->getFieldOffset();
    pvField = pvs->getSubField("timeStamp.secondsPastEpoch");
    int32 offsetSeconds = (int32)pvField->getFieldOffset();
    pvField = pvs->getSubField("timeStamp.nanoseconds");
    int32 offsetNano = (int32)pvField->getFieldOffset();
    pvField = pvs->getSubField("timeStamp.userTag");
    int32 offsetUserTag = (int32)pvField->getFieldOffset();
    bitSet->set(offsetSeconds);
    BitSetUtil::compress(bitSet,pvs);
    testOk1(bitSet->get(offsetSeconds)==true);
    bitSet->set(offsetNano);
    bitSet->set(offsetUserTag);
    if(debug) {
        oss.clear();
        oss << "bitSet" << std::endl;
        oss << *bitSet << std::endl;
        std::cout << oss.str();
    }     
    BitSetUtil::compress(bitSet,pvs);
    testOk1(bitSet->get(offsetSeconds)==false);
    testOk1(bitSet->get(offsetTimeStamp)==true);
    if(debug) {
        oss.clear();
        oss << "bitSet" << std::endl;
        oss << *bitSet << std::endl;
        std::cout << oss.str();
    }     
    bitSet->clear();

    pvField = pvs->getSubField("current");
    int32 offsetCurrent = (int32)pvField->getFieldOffset();
    pvField = pvs->getSubField("current.value");
    int32 offsetValue = (int32)pvField->getFieldOffset();
    pvField = pvs->getSubField("current.alarm");
    int32 offsetAlarm = (int32)pvField->getFieldOffset();
    pvField = pvs->getSubField("current.alarm.severity");
    int32 offsetSeverity = (int32)pvField->getFieldOffset();
    pvField = pvs->getSubField("current.alarm.status");
    int32 offsetStatus = (int32)pvField->getFieldOffset();
    pvField = pvs->getSubField("current.alarm.message");
    int32 offsetMessage = (int32)pvField->getFieldOffset();
    bitSet->set(offsetValue);
    bitSet->set(offsetSeverity);
    bitSet->set(offsetStatus);
    bitSet->set(offsetMessage);
    if(debug) {
        oss.clear();
        oss << "bitSet" << std::endl;
        oss << *bitSet << std::endl;
        std::cout << oss.str();
    }     
    BitSetUtil::compress(bitSet,pvs);
    if(debug) {
        oss.clear();
        oss << "bitSet" << std::endl;
        oss << *bitSet << std::endl;
        std::cout << oss.str();
    }     
    testOk1(bitSet->get(offsetCurrent)==true);
    bitSet->clear();
    bitSet->set(offsetSeverity);
    bitSet->set(offsetStatus);
    bitSet->set(offsetMessage);
    if(debug) {
        oss.clear();
        oss << "bitSet" << std::endl;
        oss << *bitSet << std::endl;
        std::cout << oss.str();
    }     
    BitSetUtil::compress(bitSet,pvs);
    if(debug) {
        oss.clear();
        oss << "bitSet" << std::endl;
        oss << *bitSet << std::endl;
        std::cout << oss.str();
    }     
    testOk1(bitSet->get(offsetAlarm)==true);
    bitSet->clear();
    printf("testBitSetUtil PASSED\n");
}