static void setValue(PVUnionPtr const &pvUnion, double value)
{
    UnionConstPtr u = pvUnion->getUnion();
    FieldConstPtr field = u->getField(0);
    Type type = field->getType();
    if(type==scalar) {
         ScalarConstPtr scalar = static_pointer_cast<const Scalar>(field);
         ScalarType scalarType = scalar->getScalarType();
         if(scalarType==pvDouble) {
              PVDoublePtr pvValue = static_pointer_cast<PVDouble>(
                   pvDataCreate->createPVScalar(pvDouble));
              pvValue->put(value);
              pvUnion->set(0,pvValue);
              return;
         }
         if(scalarType==pvString) {
              PVStringPtr pvValue = static_pointer_cast<PVString>(
                   pvDataCreate->createPVScalar(pvString));
              stringstream ss;
              ss << "value" << value;
              pvValue->put(ss.str());
              pvUnion->set(0,pvValue);
              return;
         }
         throw std::runtime_error("only pvDouble and pvString are supported");
    }
    if(type==scalarArray) {
         ScalarArrayConstPtr scalarArray = static_pointer_cast<const ScalarArray>(field);
         ScalarType scalarType = scalarArray->getElementType();
         if(scalarType==pvDouble) {
              size_t num = 5;
              PVDoubleArrayPtr pvValue = static_pointer_cast<PVDoubleArray>(
                   pvDataCreate->createPVScalarArray(pvDouble));
              shared_vector<double> data(num);
              for(size_t i=0; i<num; ++i) data[i] = value +i;
              pvValue->replace(freeze(data));
              pvUnion->set(0,pvValue);
              return;
         }
         if(scalarType==pvString) {
              size_t num = 5;
              PVStringArrayPtr pvValue = static_pointer_cast<PVStringArray>(
                   pvDataCreate->createPVScalarArray(pvString));
              shared_vector<string> data(num);
              for(size_t i=0; i<num; ++i) {
                  stringstream ss;
                  ss << "value" << value << i;
                  data[i] = ss.str();
              }
              pvValue->replace(freeze(data));
              pvUnion->set(0,pvValue);
              return;
         }
         throw std::runtime_error("only pvDouble and pvString are supported");
    }
    throw std::runtime_error("only scalar and scalarArray fields are supported");
}
double PvaClientPutData::getDouble()
{
    PVScalarPtr pvScalar = getScalarValue();
    ScalarType scalarType = pvScalar->getScalar()->getScalarType();
    if(scalarType==pvDouble) {
        PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
        return pvDouble->get();
    }
    if(!ScalarTypeFunc::isNumeric(scalarType)) {
        throw std::runtime_error(messagePrefix  + notCompatibleScalar);
    }
    return convert->toDouble(pvScalar);
}
Esempio n. 3
0
double PvaClientData::getDouble()
{
    if(PvaClient::getDebug()) cout << "PvaClientData::getDouble\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::getDouble() 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::getDouble() did not find a scalar field");
    }
    ScalarType scalarType = pvScalar->getScalar()->getScalarType();
    if(scalarType==pvDouble) {
        PVDoublePtr pvDouble = static_pointer_cast<PVDouble>(pvScalar);
        return pvDouble->get();
    }
    if(!ScalarTypeFunc::isNumeric(scalarType)) {
        throw std::logic_error(
            "PvaClientData::getDouble() did not find a numeric scalar field");
    }
    return convert->toDouble(pvScalar);
}
static void testPostPut()
{
    testDiag("== testPostPut ==");
    StructureConstPtr structure =
       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();

    PvaClientPutDataPtr pvaData = PvaClientPutData::create(structure);
    PVStructurePtr pvStructure = pvaData->getPVStructure();

    BitSetPtr change = pvaData->getChangedBitSet();
    PVDoublePtr powerValue = pvStructure->getSubField<PVDouble>("power.value");
    PVDoublePtr voltageValue = pvStructure->getSubField<PVDouble>("voltage.value");
    PVDoublePtr currentValue = pvStructure->getSubField<PVDouble>("current.value");
    size_t powerOffset = powerValue->getFieldOffset();
    size_t voltageOffset = voltageValue->getFieldOffset();
    size_t currentOffset = currentValue->getFieldOffset();

    change->clear();
    powerValue->put(1.0);
    voltageValue->put(2.0);
    currentValue->put(.5);

    testOk(change->cardinality()==3,"3 fields changed");
    testOk(change->get(powerOffset),"power changed");
    testOk(change->get(voltageOffset),"voltage changed");
    testOk(change->get(currentOffset),"current changed");
}
static void test()
{
    NTMultiChannelBuilderPtr builder = NTMultiChannel::createBuilder();
    testOk(builder.get() != 0, "Got builder");

    NTMultiChannelPtr multiChannel = builder->
            addDescriptor()->
            addAlarm()->
            addTimeStamp()->
            addSeverity() ->
            add("extra1",fieldCreate->createScalar(pvString)) ->
            add("extra2",fieldCreate->createScalarArray(pvString)) ->
            create();
    testOk1(multiChannel.get() != 0);

    PVStructurePtr pvStructure = multiChannel->getPVStructure();
    testOk1(pvStructure.get()!=NULL);
    testOk1(NTMultiChannel::is_a(pvStructure->getStructure()));
    size_t nchan = 3;
    shared_vector<string> names(nchan);
    names[0] = "channel 0";
    names[1] = "channel 1";
    names[2] = "channel 2";
    shared_vector<const string> channelNames(freeze(names));
    PVStringArrayPtr pvChannelName = multiChannel->getChannelName();
    pvChannelName->replace(channelNames);
    if(debug) {cout << *pvStructure << endl;}
    UnionConstPtr unionPtr =
       fieldCreate->createFieldBuilder()->
           add("doubleValue", pvDouble)->
           add("intValue", pvInt)->
           createUnion();
    multiChannel = builder->
            value(unionPtr) ->
            addDescriptor()->
            addAlarm()->
            addTimeStamp()->
            addSeverity() ->
            addIsConnected() ->
            create();
    testOk1(multiChannel.get() != 0);
    pvStructure = multiChannel->getPVStructure();
    if(debug) {cout << *pvStructure << endl;}
    pvChannelName = multiChannel->getChannelName();
    pvChannelName->replace(channelNames);
    PVUnionArrayPtr pvValue = multiChannel->getValue();
    shared_vector<PVUnionPtr> unions(nchan);
    unions[0] = pvDataCreate->createPVUnion(unionPtr);
    unions[1] = pvDataCreate->createPVUnion(unionPtr);
    unions[2] = pvDataCreate->createPVUnion(unionPtr);
    unions[0]->select("doubleValue");
    unions[1]->select("intValue");
    unions[2]->select("intValue");
    PVDoublePtr pvDouble = unions[0]->get<PVDouble>();
    pvDouble->put(1.235);
    PVIntPtr pvInt = unions[1]->get<PVInt>();
    pvInt->put(5);
    pvInt = unions[2]->get<PVInt>();
    pvInt->put(7);
    pvValue->replace(freeze(unions));
    shared_vector<int32> severities(nchan);
    severities[0] = 0;
    severities[1] = 1;
    severities[2] = 2;
    PVIntArrayPtr pvSeverity = multiChannel->getSeverity();
    pvSeverity->replace(freeze(severities));
    if(debug) {cout << *pvStructure << endl;}
    PVBooleanArrayPtr pvIsConnected = multiChannel->getIsConnected();
    shared_vector<const epics::pvData::boolean> isConnected = pvIsConnected->view();
    multiChannel = builder->
            value(unionPtr) ->
            addDescriptor()->
            addAlarm()->
            addTimeStamp()->
            addSeverity() ->
            addStatus() ->
            addMessage() ->
            addSecondsPastEpoch() ->
            addNanoseconds() ->
            addUserTag() ->
            addIsConnected() ->
            create();
    testOk1(multiChannel.get() != 0);
    pvStructure = multiChannel->getPVStructure();
    if(debug) {cout << *pvStructure << endl;}
    testOk1(NTMultiChannel::isCompatible(pvStructure)==true);
    PVStructurePtr pvTimeStamp = multiChannel->getTimeStamp();
    testOk1(pvTimeStamp.get() !=0);
    PVStructurePtr pvAlarm = multiChannel->getAlarm();
    testOk1(pvAlarm.get() !=0);
    pvValue = multiChannel->getValue();
    testOk1(pvValue.get() !=0);
    pvChannelName = multiChannel->getChannelName();
    testOk1(pvChannelName.get() !=0);
    pvIsConnected = multiChannel->getIsConnected();
    testOk1(pvIsConnected.get() !=0);
    pvSeverity = multiChannel->getSeverity();
    testOk1(pvSeverity.get() !=0);
    PVIntArrayPtr pvStatus = multiChannel->getStatus();
    testOk1(pvStatus.get() !=0);
    PVStringArrayPtr pvMessage = multiChannel->getMessage();
    testOk1(pvMessage.get() !=0);
    PVLongArrayPtr pvSecondsPastEpoch = multiChannel->getSecondsPastEpoch();
    testOk1(pvSecondsPastEpoch.get() !=0);
    PVIntArrayPtr pvNanoseconds = multiChannel->getNanoseconds();
    testOk1(pvNanoseconds.get() !=0);
    PVIntArrayPtr pvUserTag = multiChannel->getUserTag();
    testOk1(pvUserTag.get() !=0);
    PVStringPtr pvDescriptor = multiChannel->getDescriptor();
    testOk1(pvDescriptor.get() !=0);
}
Esempio n. 6
0
void MonitorRequesterImpl::ParseScalar(QString fieldName, PVScalarPtr const & pvs, knobData* kPtr)
{
    QString thisFieldName  = QString::fromStdString(pvs->getFieldName());
    //qDebug() << "ParseScalar -- field/subfield" << fieldName << thisFieldName;
    ScalarConstPtr scalar = pvs->getScalar();
    ScalarType scalarType = scalar->getScalarType();

    switch(scalarType) {
    case pvBoolean: {
        PVBooleanPtr data = static_pointer_cast<PVBoolean>(pvs);

        if(thisFieldName.contains("value")) {
            kPtr->edata.fieldtype = caINT;
            kPtr->edata.ivalue = (int)data->get();
        }
    }
        break;
    case pvByte: {
        PVBytePtr data = static_pointer_cast<PVByte>(pvs);

        if(thisFieldName.contains("value")) {
            kPtr->edata.fieldtype = caCHAR;
            kPtr->edata.ivalue = (int)data->get();
        }
    }
        break;
    case pvShort: {
        PVShortPtr data = static_pointer_cast<PVShort>(pvs);

        if(thisFieldName.contains("value")) {
            kPtr->edata.fieldtype = caINT;
            kPtr->edata.rvalue = data->get();
            kPtr->edata.ivalue = (int)data->get();
        }
    }
        break;
    case pvInt: {
        PVIntPtr data = static_pointer_cast<PVInt>(pvs);

        if(fieldName.contains("alarm") && thisFieldName.contains("severity")) {
            kPtr->edata.severity =(int) data->get();
        } else if(fieldName.contains("alarm") && thisFieldName.contains("status")) {
            kPtr->edata.status =  (int) data->get();


        } if(thisFieldName.contains("value")) {
            kPtr->edata.fieldtype = caINT;
            kPtr->edata.rvalue = data->get();
            kPtr->edata.ivalue = (int)data->get();
        }
    }
        break;
    case pvLong: {
        PVLongPtr data = static_pointer_cast<PVLong>(pvs);

        if(thisFieldName.contains("value")) {
            kPtr->edata.fieldtype = caLONG;
            kPtr->edata.rvalue = data->get();
            kPtr->edata.ivalue = (int64)data->get();
        }
    }
        break;
    case pvFloat: {
        PVFloatPtr data = static_pointer_cast<PVFloat>(pvs);

        if(thisFieldName.contains("value")) {
            kPtr->edata.fieldtype = caFLOAT;
            kPtr->edata.rvalue = data->get();
        }
    }
        break;
    case pvDouble: {
        PVDoublePtr data = static_pointer_cast<PVDouble>(pvs);

        if(fieldName.contains("display") && thisFieldName.contains("limitLow")) {
            kPtr->edata.lower_disp_limit = data->get();
        } else if(fieldName.contains("display") && thisFieldName.contains("limitHigh")) {
            kPtr->edata.upper_disp_limit = data->get();

        } else if(fieldName.contains("control") && thisFieldName.contains("limitLow")) {
            kPtr->edata.lower_ctrl_limit = data->get();
        } else if(fieldName.contains("control") && thisFieldName.contains("limitHigh")) {
            kPtr->edata.upper_ctrl_limit = data->get();

        } else if(fieldName.contains("valueAlarm") && thisFieldName.contains("lowAlarmLimit")) {
            kPtr->edata.lower_alarm_limit = data->get();
        } else if(fieldName.contains("valueAlarm") && thisFieldName.contains("highAlarmLimit")) {
            kPtr->edata.upper_alarm_limit = data->get();

        } else if(fieldName.contains("valueAlarm") && thisFieldName.contains("lowWarningLimit")) {
            kPtr->edata.lower_warning_limit = data->get();
        } else if(fieldName.contains("valueAlarm") && thisFieldName.contains("highWarningLimit")) {
            kPtr->edata.upper_warning_limit = data->get();

            // fill value and type
        } else if(thisFieldName.contains("value")) {
            kPtr->edata.precision = 3;  // for the time beeing, set to 3
            kPtr->edata.fieldtype = caDOUBLE;
            kPtr->edata.rvalue = data->get();
        }
    }
        break;
    case pvString: {
        PVStringPtr data = static_pointer_cast<PVString>(pvs);

        // fill units
        if(fieldName.contains("display") && thisFieldName.contains("units")) {
            strcpy(kPtr->edata.units, data->get().c_str());
        } else if(fieldName.contains("display") && thisFieldName.contains("description")) {
        } else if(fieldName.contains("display") && thisFieldName.contains("format")) {  // should use now precision

            // fill value and type
        } else if(thisFieldName.contains("value")) {
            qDebug() << "String :" << data->get().c_str();
        }
    }
        break;
    default:
        qDebug() << "(unknown ScalarType)" << endl;
    }


}
Esempio n. 7
0
static void testPVScalarWithProperties(
    string /*fieldName*/,ScalarType stype)
{
    PVStructurePtr pvStructure;
    bool hasValueAlarm = false;
    bool hasBooleanAlarm = false;
    bool hasDisplayControl = false;
    switch(stype) {
        case pvBoolean: {
             pvStructure = standardPVField->scalar(
                 stype,alarmTimeStampValueAlarm);
             hasBooleanAlarm = true;
             PVBooleanPtr pvField = pvStructure->getSubField<PVBoolean>("value");
             pvField->put(true);
             break;
        }
        case pvByte: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVBytePtr pvField = pvStructure->getSubField<PVByte>("value");
             pvField->put(127);
             break;
        }
        case pvShort: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVShortPtr pvField = pvStructure->getSubField<PVShort>("value");
             pvField->put(32767);
             break;
        }
        case pvInt: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVIntPtr pvField = pvStructure->getSubField<PVInt>("value");
             pvField->put((int32)0x80000000);
             break;
        }
        case pvLong: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVLongPtr pvField = pvStructure->getSubField<PVLong>("value");
             int64 value = 0x80000000;
             value <<= 32;
             value |= 0xffffffff;
             pvField->put(value);
             break;
        }
        case pvUByte: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVUBytePtr pvField = pvStructure->getSubField<PVUByte>("value");
             pvField->put(255);
             break;
        }
        case pvUShort: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVUShortPtr pvField = pvStructure->getSubField<PVUShort>("value");
             pvField->put(65535);
             break;
        }
        case pvUInt: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVUIntPtr pvField = pvStructure->getSubField<PVUInt>("value");
             pvField->put((uint32)0x80000000);
             break;
        }
        case pvULong: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVULongPtr pvField = pvStructure->getSubField<PVULong>("value");
             int64 value = 0x80000000;
             value <<= 32;
             value |= 0xffffffff;
             pvField->put(value);
             break;
        }
        case pvFloat: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVFloatPtr pvField = pvStructure->getSubField<PVFloat>("value");
             pvField->put(1.123e8);
             break;
        }
        case pvDouble: {
             pvStructure = standardPVField->scalar(
                 stype,allProperties);
             hasValueAlarm = true;
             hasDisplayControl = true;
             PVDoublePtr pvField = pvStructure->getSubField<PVDouble>("value");
             pvField->put(1.123e35);
             break;
        }
        case pvString: {
             pvStructure = standardPVField->scalar(
                 stype,alarmTimeStamp);
             PVStringPtr pvField = pvStructure->getSubField<PVString>("value");
             pvField->put(string("this is a string"));
             break;
        }
    }
    PVLongPtr seconds = pvStructure->getSubField<PVLong>(
        string("timeStamp.secondsPastEpoch"));
    testOk1(seconds.get()!=0);
    seconds->put(123456789);
    PVIntPtr nano = pvStructure->getSubField<PVInt>(string("timeStamp.nanoseconds"));
    testOk1(nano.get()!=0);
    nano->put(1000000);
    PVIntPtr severity = pvStructure->getSubField<PVInt>(string("alarm.severity"));
    testOk1(severity.get()!=0);
    severity->put(2);
    PVStringPtr message = pvStructure->getSubField<PVString>(string("alarm.message"));
    testOk1(message.get()!=0);
    message->put(string("messageForAlarm"));
    if(hasDisplayControl) {
        PVStringPtr desc = pvStructure->getSubField<PVString>(
            string("display.description"));
        testOk1(desc.get()!=0);
        desc->put(string("this is a description"));
        PVStringPtr format = pvStructure->getSubField<PVString>(
            string("display.format"));
        testOk1(format.get()!=0);
        format->put(string("f10.2"));
        PVStringPtr units = pvStructure->getSubField<PVString>(
            string("display.units"));
        testOk1(units.get()!=0);
        units->put(string("SomeUnits"));
        PVDoublePtr limit = pvStructure->getSubField<PVDouble>(
            string("display.limitLow"));
        testOk1(limit.get()!=0);
        limit->put(0.0);
        limit = pvStructure->getSubField<PVDouble>(
            string("display.limitHigh"));
        testOk1(limit.get()!=0);
        limit->put(10.0);
        limit = pvStructure->getSubField<PVDouble>(
            string("control.limitLow"));
        testOk1(limit.get()!=0);
        limit->put(1.0);
        limit = pvStructure->getSubField<PVDouble>(
            string("control.limitHigh"));
        testOk1(limit.get()!=0);
        limit->put(9.0);
    }
    if(hasValueAlarm) {
        PVBooleanPtr pvBoolean = pvStructure->getSubField<PVBoolean>("valueAlarm.active");
        pvBoolean->put(true);
        PVScalarPtr pvtemp = pvStructure->getSubField<PVScalar>("valueAlarm.lowAlarmLimit");
        testOk1(pvtemp.get()!=0);
        convert->fromDouble(pvtemp,1.0);
        pvtemp = pvStructure->getSubField<PVScalar>("valueAlarm.highAlarmLimit");
        testOk1(pvtemp.get()!=0);
        convert->fromDouble(pvtemp,9.0);
        severity = pvStructure->getSubField<PVInt>(
            string("valueAlarm.lowAlarmSeverity"));
        testOk1(severity.get()!=0);
        severity->put(2);
        severity = pvStructure->getSubField<PVInt>(
            string("valueAlarm.highAlarmSeverity"));
        testOk1(severity.get()!=0);
        severity->put(2);
        PVBooleanPtr active = pvStructure->getSubField<PVBoolean>(
            string("valueAlarm.active"));
        testOk1(active.get()!=0);
        active->put(true);
    }
    if(hasBooleanAlarm) {
        PVBooleanPtr pvBoolean = pvStructure->getSubField<PVBoolean>("valueAlarm.active");
        pvBoolean->put(true);
        severity = pvStructure->getSubField<PVInt>(
            string("valueAlarm.falseSeverity"));
        testOk1(severity.get()!=0);
        severity->put(0);
        severity = pvStructure->getSubField<PVInt>(
            string("valueAlarm.trueSeverity"));
        testOk1(severity.get()!=0);
        severity->put(2);
        severity = pvStructure->getSubField<PVInt>(
            string("valueAlarm.changeStateSeverity"));
        testOk1(severity.get()!=0);
        severity->put(1);
    }
}
static void testDouble()
{
    testDiag("== testDouble ==");
    StructureConstPtr structure =
        fieldCreate->createFieldBuilder() ->
            add("alarm",standardField->alarm()) ->
            add("timeStamp",standardField->timeStamp()) ->
            add("value",pvDouble) ->
            createStructure();

    PvaClientPutDataPtr pvaData = PvaClientPutData::create(structure);
    PVDoublePtr pvDouble = pvaData->getPVStructure() ->
        getSubField<PVDouble>("value");
    pvDouble->put(5.0);

    BitSetPtr change = pvaData->getChangedBitSet();
    size_t valueOffset = pvDouble->getFieldOffset();
    testOk(change->cardinality()==1,"1 field changed");
    testOk(change->get(valueOffset),"value changed");

    testOk(pvaData->hasValue(),"hasValue");
    testOk(pvaData->isValueScalar(),"isValueScalar");
    testOk(!pvaData->isValueScalarArray(),"!isValueScalarArray");

    try {
        testOk(!!pvaData->getValue(), "getValue");
    } catch (std::runtime_error e) {
        testFail("getValue exception '%s'", e.what());
    }

    try {
        testOk(!!pvaData->getScalarValue(), "getScalarValue");
    } catch (std::runtime_error e) {
        testFail("getScalarValue exception '%s'", e.what());
    }
    try {
        testOk(!pvaData->getArrayValue(), "!getArrayValue");
    } catch (std::runtime_error e) {
        testPass("getArrayValue exception '%s'", e.what());
    }
    try {
        testOk(!pvaData->getScalarArrayValue(), "!getScalarArrayValue");
    } catch (std::runtime_error e) {
        testPass("getScalarArrayValue exception '%s'", e.what());
    }

    try {
        testOk(pvaData->getDouble() == 5.0, "getDouble value");
    } catch (std::runtime_error e) {
        testFail("getDouble exception '%s'", e.what());
    }
    try {
        testOk(pvaData->getString() == "5", "getString value");
    } catch (std::runtime_error e) {
        testFail("getString exception '%s'", e.what());
    }

    try {
        shared_vector<const double> value = pvaData->getDoubleArray();
        testFail("getDoubleArray");
    } catch (std::runtime_error e) {
        testPass("getDoubleArray exception '%s'", e.what());
    }
    try {
        shared_vector<const string> value = pvaData->getStringArray();
        testFail("getStringArray");
    } catch (std::runtime_error e) {
        testPass("getStringArray exception '%s'", e.what());
    }

    try {
        pvaData->putDouble(5.0);
        testPass("putDouble");
    } catch (std::runtime_error e) {
        testFail("putDouble exception '%s'", e.what());
    }
    try {
        pvaData->putString("1e5");
        testPass("putString");
    } catch (std::runtime_error e) {
        testFail("putString exception '%s'", e.what());
    }

    try {
        size_t len = 2;
        shared_vector<double> val(len);
        for (size_t i=0; i<len; ++i)
            val[i] = (i+1) * 10.0;
        pvaData->putDoubleArray(freeze(val));
        testFail("putDoubleArray");
    } catch (std::runtime_error e) {
        testPass("putDoubleArray exception '%s'", e.what());
    }
    try {
        size_t len = 2;
        shared_vector<string> val(len);
        val[0] = "one"; val[1] = "two";
        pvaData->putStringArray(freeze(val));
        testFail("putStringArray");
    } catch (std::runtime_error e) {
        testPass("putStringArray exception '%s'", e.what());
    }
}