diff --git a/testApp/remote/eget.cpp b/testApp/remote/eget.cpp index d9f729f..940b450 100644 --- a/testApp/remote/eget.cpp +++ b/testApp/remote/eget.cpp @@ -262,18 +262,80 @@ void formatNTTable(std::ostream& o, PVStructurePtr const & pvStruct) } + +void formatNTMatrix(std::ostream& o, PVStructurePtr const & pvStruct) +{ + PVDoubleArrayPtr value = dynamic_pointer_cast(pvStruct->getScalarArrayField("value", pvDouble)); + if (value.get() == 0) + { + std::cerr << "no double[] 'value' column in NTMatrix" << std::endl; + return; + } + + int32 rows, cols; + + PVIntArrayPtr dim = dynamic_pointer_cast(pvStruct->getScalarArrayField("dim", pvInt)); + if (dim.get() != 0) + { + // dim[] = { rows, columns } + size_t dims = dim->getLength(); + if (dims != 1 && dims != 2) + { + std::cerr << "malformed NTMatrix, dim[] must contain 1 or 2 elements instead of " << dims << std::endl; + return; + } + + IntArrayData data; + dim->get(0, dims, data); + rows = data.data[0]; + cols = (dims == 2) ? data.data[1] : 1; + + if (rows <= 0 || cols <= 0) + { + std::cerr << "malformed NTMatrix, dim[] must contain elements >= 0" << std::endl; + return; + } + } + else + { + rows = value->getLength(); + cols = 1; + } + + o << std::left; + + size_t len = static_cast(rows*cols); + if (len != value->getLength()) + { + std::cerr << "malformed NTMatrix, values[] must contain " << len << " elements instead of " << value->getLength() << std::endl; + return; + } + + size_t ix = 0; + for (int32 r = 0; r < rows; r++) + { + for (int32 c = 0; c < cols; c++) + { + o << std::setw(16); + value->dumpValue(o, ix++); + } + o << std::endl; + } +} + typedef void(*NTFormatterFunc)(std::ostream& o, PVStructurePtr const & pvStruct); typedef map NTFormatterLUTMap; NTFormatterLUTMap ntFormatterLUT; void initializeNTFormatterLUT() { - ntFormatterLUT["NTTable"] = formatNTTable; ntFormatterLUT["NTScalar"] = formatNTScalar; ntFormatterLUT["NTScalarArray"] = formatNTScalarArray; + ntFormatterLUT["NTTable"] = formatNTTable; + ntFormatterLUT["NTMatrix"] = formatNTMatrix; ntFormatterLUT["NTAny"] = formatNTAny; - // bug in StandardPV + // StandardPV "support" ntFormatterLUT["scalar_t"] = formatNTScalar; ntFormatterLUT["scalarArray_t"] = formatNTScalarArray; } diff --git a/testApp/remote/testServer.cpp b/testApp/remote/testServer.cpp index 6d83065..bdebdc9 100644 --- a/testApp/remote/testServer.cpp +++ b/testApp/remote/testServer.cpp @@ -413,11 +413,9 @@ class MockChannelRPC : public ChannelRPC else { int i = 0; - int totalFields = 1 + 1 + atoi(columns->get().c_str()); // normativeType, labels, + int totalFields = 1 + atoi(columns->get().c_str()); // labels, StringArray fieldNames(totalFields); FieldConstPtrArray fields(totalFields); - //fieldNames[i] = "normativeType"; - //fields[i++] = getFieldCreate()->createScalar(pvString); fieldNames[i] = "labels"; fields[i++] = getFieldCreate()->createScalarArray(pvString); char sbuf[16]; @@ -454,7 +452,48 @@ class MockChannelRPC : public ChannelRPC m_channelRPCRequester->requestDone(Status::Ok, result); } } - else + else if (m_channelName == "rpcNTMatrix") + { + // TODO type check, getStringField is verbose + PVStringPtr rows = static_pointer_cast(pvArgument->getSubField("rows")); + PVStringPtr columns = static_pointer_cast(pvArgument->getSubField("columns")); + if (rows.get() == 0 || columns.get() == 0) + { + PVStructure::shared_pointer nullPtr; + Status errorStatus(Status::STATUSTYPE_ERROR, "no rows and columns specified"); + m_channelRPCRequester->requestDone(errorStatus, nullPtr); + } + else + { + int i = 0; + int totalFields = 2; // value[], dim + StringArray fieldNames(totalFields); + FieldConstPtrArray fields(totalFields); + fieldNames[i] = "value"; + fields[i++] = getFieldCreate()->createScalarArray(pvDouble); + fieldNames[i] = "dim"; + fields[i++] = getFieldCreate()->createScalarArray(pvInt); + + PVStructure::shared_pointer result( + new PVStructure(getFieldCreate()->createStructure("NTMatrix", fieldNames, fields))); + + int32 rowsVal = atoi(rows->get().c_str()); + int32 colsVal = atoi(columns->get().c_str()); + int32 dimValues[] = { rowsVal, colsVal }; + static_pointer_cast(result->getScalarArrayField("dim", pvInt))->put(0, 2, &dimValues[0], 0); + + srand ( time(NULL) ); + + int32 len = rowsVal * colsVal; + vector mv(len); + for (int r = 0; r < len; r++) + mv[r] = (rand()-RAND_MAX/2)/(double)(RAND_MAX/2); + static_pointer_cast(result->getScalarArrayField("value", pvDouble))->put(0, len, &mv[0], 0); + + m_channelRPCRequester->requestDone(Status::Ok, result); + } + } + else { /* std::string s;