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; }
static PVStructure::shared_pointer createPVStructure(CAChannel::shared_pointer const & channel, string const & properties) { PVStructure::shared_pointer pvStructure = getPVDataCreate()->createPVStructure(createStructure(channel, properties)); if (channel->getNativeType() == DBR_ENUM) { PVScalarArrayPtr pvScalarArray = pvStructure->getScalarArrayField("value.choices", pvString); // TODO avoid getting labels if DBR_GR_ENUM or DBR_CTRL_ENUM is used in subsequent get int result = ca_array_get_callback(DBR_GR_ENUM, 1, channel->getChannelID(), ca_get_labels_handler, pvScalarArray.get()); if (result == ECA_NORMAL) { ca_flush_io(); // NOTE: we do not wait here, since all subsequent request (over TCP) is serialized // and will guarantee that ca_get_labels_handler is called first } else { // TODO better error handling std::cerr << "failed to get labels for enum " << channel->getChannelName() << ": " << ca_message(result) << std::endl; } } return pvStructure; }
void copy_DBR_CTRL(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) { const T* data = static_cast<const T*>(dbr); PVStructure::shared_pointer alarm = pvStructure->getSubField<PVStructure>("alarm"); alarm->getSubField<PVInt>("status")->put(0); alarm->getSubField<PVInt>("severity")->put(data->severity); alarm->getSubField<PVString>("message")->put(dbrStatus2alarmMessage[data->status]); PVStructure::shared_pointer disp = pvStructure->getSubField<PVStructure>("display"); disp->getSubField<PVString>("units")->put(std::string(data->units)); disp->getSubField<PVDouble>("limitHigh")->put(data->upper_disp_limit); disp->getSubField<PVDouble>("limitLow")->put(data->lower_disp_limit); copy_format<T>(dbr, disp); PVStructure::shared_pointer va = pvStructure->getSubField<PVStructure>("valueAlarm"); std::tr1::static_pointer_cast<sF>(va->getSubField("highAlarmLimit"))->put(data->upper_alarm_limit); std::tr1::static_pointer_cast<sF>(va->getSubField("highWarningLimit"))->put(data->upper_warning_limit); std::tr1::static_pointer_cast<sF>(va->getSubField("lowWarningLimit"))->put(data->lower_warning_limit); std::tr1::static_pointer_cast<sF>(va->getSubField("lowAlarmLimit"))->put(data->lower_alarm_limit); PVStructure::shared_pointer ctrl = pvStructure->getSubField<PVStructure>("control"); ctrl->getSubField<PVDouble>("limitHigh")->put(data->upper_ctrl_limit); ctrl->getSubField<PVDouble>("limitLow")->put(data->lower_ctrl_limit); copy_DBR<pT, sT, sF, aF>(&data->value, count, pvStructure); }
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; } }
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; } }
void printValue(std::string const & channelName, PVStructure::shared_pointer const & pv) { if (mode == ValueOnlyMode) { PVField::shared_pointer value = pv->getSubField("value"); if (value.get() == 0) { std::cerr << "no 'value' field" << std::endl; //std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; pvutil_ostream myos(std::cout.rdbuf()); myos << channelName << std::endl << *(pv.get()) << std::endl << std::endl; } else { Type valueType = value->getField()->getType(); if (valueType != scalar && valueType != scalarArray) { // switch to structure mode, unless it's T-type if (valueType == structure && isTType(static_pointer_cast<PVStructure>(value))) { std::cout << std::setw(30) << std::left << channelName; std::cout << fieldSeparator; formatTType(std::cout, static_pointer_cast<PVStructure>(value)); std::cout << std::endl; } else { //std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; pvutil_ostream myos(std::cout.rdbuf()); myos << channelName << std::endl << *(pv.get()) << std::endl << std::endl; } } else { if (fieldSeparator == ' ' && value->getField()->getType() == scalar) std::cout << std::setw(30) << std::left << channelName; else std::cout << channelName; std::cout << fieldSeparator; terse(std::cout, value) << std::endl; } } } else if (mode == TerseMode) terseStructure(std::cout, pv) << std::endl; else { //std::cout << channelName << std::endl << *(pv.get()) << std::endl << std::endl; pvutil_ostream myos(std::cout.rdbuf()); myos << channelName << std::endl << *(pv.get()) << std::endl << std::endl; } }
PVStructure::shared_pointer request(PVStructure::shared_pointer const & args) throw (RPCRequestException) { // TODO error handling double a = atof(args->getStringField("a")->get().c_str()); double b = atof(args->getStringField("b")->get().c_str()); PVStructure::shared_pointer result = getPVDataCreate()->createPVStructure(resultStructure); result->getDoubleField("c")->put(a+b); return result; }
void copy_DBR_STS(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) { const T* data = static_cast<const T*>(dbr); PVStructure::shared_pointer alarm = pvStructure->getStructureField("alarm"); // no mapping needed alarm->getIntField("status")->put(0); alarm->getIntField("severity")->put(data->severity); alarm->getStringField("message")->put(dbrStatus2alarmMessage[data->status]); copy_DBR<pT, sT, sF, aF>(&data->value, count, pvStructure); }
void copy_DBR_TIME(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) { const T* data = static_cast<const T*>(dbr); PVStructure::shared_pointer ts = pvStructure->getStructureField("timeStamp"); epics::pvData::int64 spe = data->stamp.secPastEpoch; spe += 7305*86400; ts->getLongField("secondsPastEpoch")->put(spe); ts->getIntField("nanoseconds")->put(data->stamp.nsec); copy_DBR_STS<T, pT, sT, sF, aF>(dbr, count, pvStructure); }
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; }
void copy_DBR<dbr_long_t, pvInt, PVInt, PVIntArray>(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) { if (count == 1) { std::tr1::shared_ptr<PVInt> value = std::tr1::static_pointer_cast<PVInt>(pvStructure->getSubField("value")); value->put(static_cast<const int32*>(dbr)[0]); } else { std::tr1::shared_ptr<PVIntArray> value = std::tr1::static_pointer_cast<PVIntArray>(pvStructure->getScalarArrayField("value", pvInt)); PVIntArray::svector temp(value->reuse()); temp.resize(count); std::copy(static_cast<const int32*>(dbr), static_cast<const int32*>(dbr) + count, temp.begin()); value->replace(freeze(temp)); } }
void copy_DBR(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) { if (count == 1) { std::tr1::shared_ptr<sF> value = std::tr1::static_pointer_cast<sF>(pvStructure->getSubField("value")); value->put(static_cast<const pT*>(dbr)[0]); } else { std::tr1::shared_ptr<aF> value = std::tr1::static_pointer_cast<aF>(pvStructure->getScalarArrayField("value", sT)); typename aF::svector temp(value->reuse()); temp.resize(count); std::copy(static_cast<const pT*>(dbr), static_cast<const pT*>(dbr) + count, temp.begin()); value->replace(freeze(temp)); } }
void copy_DBR<dbr_enum_t, pvString, PVString, PVStringArray>(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) { if (count == 1) { std::tr1::shared_ptr<PVInt> value = std::tr1::static_pointer_cast<PVInt>(pvStructure->getSubField("value.index")); value->put(static_cast<const dbr_enum_t*>(dbr)[0]); } else { // not supported std::cerr << "caChannel: array of enums not supported" << std::endl; } }
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; } }
void MyChannelGetRequester::getDone(const Status& status, ChannelGet::shared_pointer const & channelGet, PVStructure::shared_pointer const & pvStructure, BitSet::shared_pointer const & bitSet) { cout << "ChannelGet for " << channelGet->getChannel()->getChannelName() << " finished, " << status << endl; if (status.isSuccess()) { pvStructure->dumpValue(cout); done_event.signal(); } }
void copy_DBR<string, pvString, PVString, PVStringArray>(const void * dbr, unsigned count, PVStructure::shared_pointer const & pvStructure) { if (count == 1) { std::tr1::shared_ptr<PVString> value = std::tr1::static_pointer_cast<PVString>(pvStructure->getSubField("value")); value->put(std::string(static_cast<const char*>(dbr))); } else { std::tr1::shared_ptr<PVStringArray> value = std::tr1::static_pointer_cast<PVStringArray>(pvStructure->getScalarArrayField("value", pvString)); const dbr_string_t* dbrStrings = static_cast<const dbr_string_t*>(dbr); PVStringArray::svector sA(value->reuse()); sA.resize(count); std::copy(dbrStrings, dbrStrings + count, sA.begin()); value->replace(freeze(sA)); } }
int main (int argc, char *argv[]) { int opt; // getopt() current option std::string testFile; setvbuf(stdout,NULL,_IOLBF,BUFSIZ); // Set stdout to line buffering while ((opt = getopt(argc, argv, ":hr:w:i:c:s:l:f:v")) != -1) { switch (opt) { case 'h': // Print usage usage(); return 0; case 'w': // Set PVA timeout value if((epicsScanDouble(optarg, &timeOut)) != 1) { fprintf(stderr, "'%s' is not a valid timeout value " "- ignored. ('cainfo -h' for help.)\n", optarg); timeOut = DEFAULT_TIMEOUT; } break; case 'r': // pvRequest string request = optarg; break; case 'i': // iterations iterations = atoi(optarg); break; case 'c': // channels channels = atoi(optarg); break; case 's': // arraySize arraySize = atoi(optarg); break; case 'l': // runs runs = atoi(optarg); break; case 'f': // testFile testFile = optarg; break; case 'v': // testFile verbose = true; break; case '?': fprintf(stderr, "Unrecognized option: '-%c'. ('testGetPerformance -h' for help.)\n", optopt); return 1; case ':': fprintf(stderr, "Option '-%c' requires an argument. ('testGetPerformance -h' for help.)\n", optopt); return 1; default : usage(); return 1; } } // typedef enum {logLevelInfo, logLevelDebug, logLevelError, errlogFatal} errlogSevEnum; SET_LOG_LEVEL(logLevelError); pvRequest = CreateRequest::create()->createRequest(request); if (pvRequest.get() == 0) { printf("failed to parse request string\n"); return 1; } ClientFactory::start(); provider = ChannelProviderRegistry::clients()->getProvider("pva"); if (!testFile.empty()) { ifstream ifs(testFile.c_str(), ifstream::in); if (ifs.good()) { string line; while (true) { getline(ifs, line); if (ifs.good()) { // ignore lines that starts (no trimming) with '#' if (line.find('#') != 0) { // <c> <s> <i> <l> if (sscanf(line.c_str(), "%d %d %d %d", &channels, &arraySize, &iterations, &runs) == 4) { //printf("%d %d %d %d\n", channels, arraySize, iterations, runs); runTest(); // wait a bit for a next test epicsThreadSleep(1.0); } else { fprintf(stderr, "Failed to parse line '%s', ignoring...\n", line.c_str()); } } } else break; } } else { fprintf(stderr, "Failed to open file '%s'\n", testFile.c_str()); return 2; } ifs.close(); } else { // in non-file mode, verbose is true by default verbose = true; runTest(); } //ClientFactory::stop(); return 0; }
void copy_format<dbr_time_string>(const void * /*dbr*/, PVStructure::shared_pointer const & pvDisplayStructure) { pvDisplayStructure->getStringField("format")->put("%s"); }