static chtype getDBRType(PVStructure::shared_pointer const & pvRequest, chtype nativeType) { // get "field" sub-structure PVStructure::shared_pointer fieldSubField = std::tr1::dynamic_pointer_cast<PVStructure>(pvRequest->getSubField("field")); if (!fieldSubField) fieldSubField = pvRequest; Structure::const_shared_pointer fieldStructure = fieldSubField->getStructure(); // no fields or control -> DBR_CTRL_<type> if (fieldStructure->getNumberFields() == 0 || fieldStructure->getField("control")) return static_cast<chtype>(static_cast<int>(nativeType) + DBR_CTRL_STRING); // display/valueAlarm -> DBR_GR_<type> if (fieldStructure->getField("display") || fieldStructure->getField("valueAlarm")) return static_cast<chtype>(static_cast<int>(nativeType) + DBR_GR_STRING); // timeStamp -> DBR_TIME_<type> // NOTE: that only DBR_TIME_<type> type holds timestamp, therefore if you request for // the fields above, you will never get timestamp if (fieldStructure->getField("timeStamp")) return static_cast<chtype>(static_cast<int>(nativeType) + DBR_TIME_STRING); // alarm -> DBR_STS_<type> if (fieldStructure->getField("alarm")) return static_cast<chtype>(static_cast<int>(nativeType) + DBR_STS_STRING); return nativeType; }
int doPut_pvStructure<dbr_enum_t, pvString, PVString, PVStringArray>(CAChannel::shared_pointer const & channel, void *usrArg, PVStructure::shared_pointer const & pvStructure) { bool isScalarValue = pvStructure->getStructure()->getField("value")->getType() == structure; if (isScalarValue) { std::tr1::shared_ptr<PVInt> value = std::tr1::static_pointer_cast<PVInt>(pvStructure->getSubField("value.index")); dbr_enum_t val = value->get(); int result = ca_array_put_callback(channel->getNativeType(), 1, channel->getChannelID(), &val, ca_put_handler, usrArg); if (result == ECA_NORMAL) { ca_flush_io(); } return result; } else { // no enum arrays in V3 return ECA_NOSUPPORT; } }
PVStructure::shared_pointer request(PVStructure::shared_pointer const & pvArguments) { // NTURI support PVStructure::shared_pointer args( (starts_with(pvArguments->getStructure()->getID(), "epics:nt/NTURI:1.")) ? pvArguments->getSubField<PVStructure>("query") : pvArguments ); // get fields and check their existence PVScalar::shared_pointer af = args->getSubField<PVScalar>("a"); PVScalar::shared_pointer bf = args->getSubField<PVScalar>("b"); if (!af || !bf) throw RPCRequestException(Status::STATUSTYPE_ERROR, "scalar 'a' and 'b' fields are required"); // get the numbers (and convert if neccessary) double a, b; try { a = af->getAs<double>(); b = bf->getAs<double>(); } catch (std::exception &e) { throw RPCRequestException(Status::STATUSTYPE_ERROR, std::string("failed to convert arguments to double: ") + e.what()); } // create return structure and set data PVStructure::shared_pointer result = getPVDataCreate()->createPVStructure(resultStructure); result->getSubFieldT<PVDouble>("c")->put(a+b); return result; }
int doPut_pvStructure<string, pvString, PVString, PVStringArray>(CAChannel::shared_pointer const & channel, void *usrArg, PVStructure::shared_pointer const & pvStructure) { bool isScalarValue = pvStructure->getStructure()->getField("value")->getType() == scalar; if (isScalarValue) { std::tr1::shared_ptr<PVString> value = std::tr1::static_pointer_cast<PVString>(pvStructure->getSubField("value")); string val = value->get(); int result = ca_array_put_callback(channel->getNativeType(), 1, channel->getChannelID(), val.c_str(), ca_put_handler, usrArg); if (result == ECA_NORMAL) { ca_flush_io(); } return result; } else { std::tr1::shared_ptr<PVStringArray> value = std::tr1::static_pointer_cast<PVStringArray>(pvStructure->getScalarArrayField("value", pvString)); PVStringArray::const_svector stringArray(value->view()); size_t arraySize = stringArray.size(); size_t ca_stringBufferSize = arraySize * MAX_STRING_SIZE; char* ca_stringBuffer = new char[ca_stringBufferSize]; memset(ca_stringBuffer, 0, ca_stringBufferSize); char *p = ca_stringBuffer; for(size_t i = 0; i < arraySize; i++) { string value = stringArray[i]; size_t len = value.length(); if (len >= MAX_STRING_SIZE) len = MAX_STRING_SIZE - 1; memcpy(p, value.c_str(), len); p += MAX_STRING_SIZE; } int result = ca_array_put_callback(channel->getNativeType(), arraySize, channel->getChannelID(), ca_stringBuffer, ca_put_handler, usrArg); delete[] ca_stringBuffer; if (result == ECA_NORMAL) { ca_flush_io(); } return result; } }
PVStructure::shared_pointer request(PVStructure::shared_pointer const & pvArguments) { // requires NTURI as argument if (pvArguments->getStructure()->getID() != "epics:nt/NTURI:1.0") throw RPCRequestException(Status::STATUSTYPE_ERROR, "RPC argument must be a NTURI normative type"); std::string channelName = pvArguments->getSubField<PVString>("path")->get(); // create return structure and set data PVStructure::shared_pointer result = getPVDataCreate()->createPVStructure(resultStructure); result->getSubField<PVString>("channelName")->put(channelName); return result; }
int doPut_pvStructure(CAChannel::shared_pointer const & channel, void *usrArg, PVStructure::shared_pointer const & pvStructure) { bool isScalarValue = pvStructure->getStructure()->getField("value")->getType() == scalar; if (isScalarValue) { std::tr1::shared_ptr<sF> value = std::tr1::static_pointer_cast<sF>(pvStructure->getSubField("value")); pT val = value->get(); int result = ca_array_put_callback(channel->getNativeType(), 1, channel->getChannelID(), &val, ca_put_handler, usrArg); if (result == ECA_NORMAL) { ca_flush_io(); } return result; } else { std::tr1::shared_ptr<aF> value = std::tr1::static_pointer_cast<aF>(pvStructure->getScalarArrayField("value", sT)); const pT* val = value->view().data(); int result = ca_array_put_callback(channel->getNativeType(), static_cast<unsigned long>(value->getLength()), channel->getChannelID(), val, ca_put_handler, usrArg); if (result == ECA_NORMAL) { ca_flush_io(); } return result; } }