/* pvaClientPutData.cpp */ /** * Copyright - See the COPYRIGHT that is included with this distribution. * EPICS pvData is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. */ /** * @author mrk * @date 2015.02 */ #include #include #include #include #define epicsExportSharedSymbols #include using std::tr1::static_pointer_cast; using namespace epics::pvData; using namespace epics::pvAccess; using namespace std; namespace epics { namespace pvaClient { static ConvertPtr convert = getConvert(); static string notCompatibleScalar("value is not a compatible scalar"); static string notDoubleArray("value is not a doubleArray"); static string notStringArray("value is not a stringArray"); class PvaClientPostHandlerPvt: public PostHandler { PvaClientPutData * putData; size_t fieldNumber; public: PvaClientPostHandlerPvt(PvaClientPutData *putData,size_t fieldNumber) : putData(putData),fieldNumber(fieldNumber){} void postPut() { putData->postPut(fieldNumber);} }; PvaClientPutDataPtr PvaClientPutData::create(StructureConstPtr const & structure) { if(PvaClient::getDebug()) cout << "PvaClientPutData::create\n"; PvaClientPutDataPtr epv(new PvaClientPutData(structure)); return epv; } PvaClientPutData::PvaClientPutData(StructureConstPtr const & structure) : PvaClientData(structure) { if(PvaClient::getDebug()) cout << "PvaClientPutData::PvaClientPutData\n"; PVStructurePtr pvStructure(getPVDataCreate()->createPVStructure(structure)); BitSetPtr bitSet(BitSetPtr(new BitSet(pvStructure->getNumberFields()))); setData(pvStructure,bitSet); size_t nfields = pvStructure->getNumberFields(); postHandler.resize(nfields); PVFieldPtr pvField; for(size_t i =0; igetSubField(i); } pvField->setPostHandler(postHandler[i]); } } void PvaClientPutData::putDouble(double value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putDouble\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(pvValue); } if(!pvScalar) { while(true) { const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); if(fieldPtrArray.size()!=1) { throw std::logic_error( "PvaClientData::putDouble() pvRequest for multiple fields"); } PVFieldPtr pvField(fieldPtrArray[0]); Type type = pvField->getField()->getType(); if(type==scalar) { pvScalar = static_pointer_cast(pvField); break; } if(pvField->getField()->getType()!=epics::pvData::structure) break; pvStructure = static_pointer_cast(pvField); } } if(!pvScalar) { throw std::logic_error( "PvaClientData::putDouble() did not find a scalar field"); } ScalarType scalarType = pvScalar->getScalar()->getScalarType(); if(scalarType==pvDouble) { PVDoublePtr pvDouble = static_pointer_cast(pvScalar); pvDouble->put(value); return; } if(!ScalarTypeFunc::isNumeric(scalarType)) { throw std::logic_error( "PvaClientData::putDouble() did not find a numeric scalar field"); } convert->fromDouble(pvScalar,value); } void PvaClientPutData::putString(std::string const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putString\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(pvValue); } if(!pvScalar) { while(true) { const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); if(fieldPtrArray.size()!=1) { throw std::logic_error( "PvaClientData::putString() pvRequest for multiple fields"); } PVFieldPtr pvField(fieldPtrArray[0]); Type type = pvField->getField()->getType(); if(type==scalar) { pvScalar = static_pointer_cast(pvField); break; } if(pvField->getField()->getType()!=epics::pvData::structure) break; pvStructure = static_pointer_cast(pvField); } } if(!pvScalar) { throw std::logic_error( "PvaClientData::putString() did not find a scalar field"); } convert->fromString(pvScalar,value); } void PvaClientPutData::putDoubleArray(shared_vector const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putDoubleArray\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(pvValue); } } if(!pvScalarArray) { while(true) { const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); if(fieldPtrArray.size()!=1) { throw std::logic_error( "PvaClientData::putDoubleArray() pvRequest for multiple fields"); } PVFieldPtr pvField(fieldPtrArray[0]); Type type = pvField->getField()->getType(); if(type==scalarArray) { PVScalarArrayPtr pvScalarArray = static_pointer_cast(pvField); break; } if(pvField->getField()->getType()!=epics::pvData::structure) break; pvStructure = static_pointer_cast(pvField); } } if(!pvScalarArray) { throw std::logic_error( "PvaClientData::putDoubleArray() did not find a scalarArray field"); } ScalarType scalarType = pvScalarArray->getScalarArray()->getElementType(); if(!ScalarTypeFunc::isNumeric(scalarType)) { throw std::logic_error( "PvaClientData::putDoubleArray() did not find a numeric scalarArray field"); } pvScalarArray->putFrom(value); } void PvaClientPutData::putStringArray(shared_vector const & value) { if(PvaClient::getDebug()) cout << "PvaClientPutData::putStringArray\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(pvValue); } } if(!pvScalarArray) { while(true) { const PVFieldPtrArray fieldPtrArray(pvStructure->getPVFields()); if(fieldPtrArray.size()!=1) { throw std::logic_error( "PvaClientData::putStringArray() pvRequest for multiple fields"); } PVFieldPtr pvField(fieldPtrArray[0]); Type type = pvField->getField()->getType(); if(type==scalarArray) { pvScalarArray = static_pointer_cast(pvField); break; } if(pvField->getField()->getType()!=epics::pvData::structure) break; pvStructure = static_pointer_cast(pvField); } } if(!pvScalarArray) { throw std::logic_error( "PvaClientData::putStringArray() did not find a scalarArray field"); } pvScalarArray->putFrom(value); return; } void PvaClientPutData::putStringArray(std::vector const & value) { size_t length = value.size(); shared_vector val(length); for(size_t i=0; i < length; ++i) val[i] = value[i]; putStringArray(freeze(val)); return; } void PvaClientPutData::postPut(size_t fieldNumber) { if(PvaClient::getDebug()) cout << "PvaClientPutData::postPut\n"; getChangedBitSet()->set(fieldNumber); } }}