diff --git a/testApp/remote/testServer.cpp b/testApp/remote/testServer.cpp index 843925a..90eba81 100644 --- a/testApp/remote/testServer.cpp +++ b/testApp/remote/testServer.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -254,7 +255,7 @@ public: -static epics::pvData::PVStructure::shared_pointer createNTTable(int columnsCount) +static epics::pvData::PVStructure::shared_pointer createNTTable(int columnsCount, bool timeStamp = false) { StringArray fieldNames(columnsCount); FieldConstPtrArray fields(columnsCount); @@ -272,12 +273,18 @@ static epics::pvData::PVStructure::shared_pointer createNTTable(int columnsCount getFieldCreate()->createStructure(fieldNames, fields) ); - StringArray tableFieldNames(2); - FieldConstPtrArray tableFields(2); + size_t nfields = timeStamp ? 3 : 2; + StringArray tableFieldNames(nfields); + FieldConstPtrArray tableFields(nfields); tableFieldNames[0] = "labels"; tableFields[0] = getFieldCreate()->createScalarArray(pvString); tableFieldNames[1] = "value"; tableFields[1] = valueStructure; + if (timeStamp) + { + tableFieldNames[2] = "timeStamp"; + tableFields[2] = getStandardField()->timeStamp(); + } PVStructure::shared_pointer result( getPVDataCreate()->createPVStructure( @@ -290,7 +297,7 @@ static epics::pvData::PVStructure::shared_pointer createNTTable(int columnsCount return result; } -static epics::pvData::PVStructure::shared_pointer createNTNameValue(int columnsCount) +static epics::pvData::PVStructure::shared_pointer createNTNameValue(int columnsCount, bool timeStamp = false) { StringArray fieldNames(columnsCount); FieldConstPtrArray fields(columnsCount); @@ -304,12 +311,18 @@ static epics::pvData::PVStructure::shared_pointer createNTNameValue(int columnsC labels[i] = sbuf; } - StringArray tableFieldNames(2); - FieldConstPtrArray tableFields(2); + size_t nfields = timeStamp ? 3 : 2; + StringArray tableFieldNames(nfields); + FieldConstPtrArray tableFields(nfields); tableFieldNames[0] = "name"; tableFields[0] = getFieldCreate()->createScalarArray(pvString); tableFieldNames[1] = "value"; tableFields[1] = getFieldCreate()->createScalarArray(pvDouble); + if (timeStamp) + { + tableFieldNames[2] = "timeStamp"; + tableFields[2] = getStandardField()->timeStamp(); + } PVStructure::shared_pointer result( getPVDataCreate()->createPVStructure( @@ -381,17 +394,53 @@ static void generateNTNameValueDoubleValues(epics::pvData::PVStructure::shared_p arr->replace(freeze(temp)); } +static void setTimeStamp(PVStructure::shared_pointer const & ts) +{ + PVTimeStamp timeStamp; + timeStamp.attach(ts); + TimeStamp current; + current.getCurrent(); + timeStamp.set(current); +} + static void generateNTAggregateValues(epics::pvData::PVStructure::shared_pointer result) { - double value = rand()/((double)RAND_MAX+1); - result->getSubField("value")->put(value); - result->getSubField("min")->put(value); - result->getSubField("max")->put(value); - result->getSubField("first")->put(value); - result->getSubField("last")->put(value); - result->getSubField("dispersion")->put(0.0); - result->getSubField("N")->put(1); + setTimeStamp(result->getStructureField("firstTimeStamp")); +#define N 1024 + double values[N]; + for (int r = 0; r < N; r++) + values[r] = rand()/((double)RAND_MAX+1); + double sum = 0; + double min = 1; + double max = -1; + for (int r = 0; r < N; r++) + { + sum += values[r]; + if (values[r] < min) min = values[r]; + if (values[r] > max) max = values[r]; + } + double avg = sum/N; + + sum = 0.0; + for (int r = 0; r < N; r++) + { + double t = (values[r] - avg); + sum += t*t; + } + double stddev = sqrt(sum/N); + + + result->getSubField("value")->put(avg); + result->getSubField("min")->put(min); + result->getSubField("max")->put(max); + result->getSubField("first")->put(values[0]); + result->getSubField("last")->put(values[N-1]); + result->getSubField("dispersion")->put(stddev); + result->getSubField("N")->put(N); +#undef ROWS + + setTimeStamp(result->getStructureField("lastTimeStamp")); } @@ -640,6 +689,9 @@ protected: { PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelProcess); + PVFieldPtr ts = pvStructure->getSubField("timeStamp"); + if (ts) m_timeStamp.attach(ts); + ChannelProcess::shared_pointer thisPtr; // we return null = static_pointer_cast(shared_from_this()); PVFieldPtr field = pvStructure->getSubField("value"); if (field.get() == 0) @@ -661,9 +713,6 @@ protected: } m_valueField = dynamic_pointer_cast(field); - - PVFieldPtr ts = pvStructure->getSubField("timeStamp"); - if (ts) m_timeStamp.attach(ts); } public: @@ -777,13 +826,13 @@ public: break; } } - - if (m_timeStamp.isAttached()) - { - TimeStamp current; - current.getCurrent(); - m_timeStamp.set(current); - } + } + + if (m_timeStamp.isAttached()) + { + TimeStamp current; + current.getCurrent(); + m_timeStamp.set(current); } m_channelProcessRequester->processDone(Status::Ok); @@ -1938,12 +1987,12 @@ protected: } else if (m_name.find("testTable") == 0) { - m_pvStructure = createNTTable(5); // 5 columns + m_pvStructure = createNTTable(5, true); // 5 columns w/ timeStamp generateNTTableDoubleValues(m_pvStructure); } else if (m_name.find("testNameValue") == 0) { - m_pvStructure = createNTNameValue(5); // 5 columns + m_pvStructure = createNTNameValue(5, true); // 5 columns w/ timeStamp generateNTNameValueDoubleValues(m_pvStructure); } else if (m_name.find("testAggregate") == 0)