add request2mask()
This commit is contained in:
@@ -57,6 +57,7 @@ LIB_SRCS += util.cpp
|
||||
LIB_SRCS += bitmask.cpp
|
||||
LIB_SRCS += type.cpp
|
||||
LIB_SRCS += data.cpp
|
||||
LIB_SRCS += pvrequest.cpp
|
||||
LIB_SRCS += dataencode.cpp
|
||||
LIB_SRCS += nt.cpp
|
||||
LIB_SRCS += evhelper.cpp
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* pvxs is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
|
||||
#include "pvrequest.h"
|
||||
#include "dataimpl.h"
|
||||
|
||||
namespace pvxs {
|
||||
namespace impl {
|
||||
|
||||
BitMask request2mask(const FieldDesc* desc, const Value& pvRequest)
|
||||
{
|
||||
auto fields = pvRequest["field"];
|
||||
// pre-select top wildcard bit, which will always be permitted
|
||||
BitMask ret({0u}, desc->size());
|
||||
// have we found at least one requested field?
|
||||
bool foundrequested = false;
|
||||
|
||||
if(fields.type()==TypeCode::Struct) {
|
||||
auto rdesc = Value::Helper::desc(fields);
|
||||
|
||||
if(rdesc->mlookup.empty())
|
||||
foundrequested = true; // empty is wildcard
|
||||
|
||||
// iterate pvRequest fields
|
||||
for(auto& pair : rdesc->mlookup) {
|
||||
auto crdesc = rdesc + pair.second;
|
||||
|
||||
if(crdesc->code==TypeCode::Struct) {
|
||||
// attempt to match up with actual structure
|
||||
auto it = desc->mlookup.find(pair.first);
|
||||
if(it!=desc->mlookup.end()) {
|
||||
// match found
|
||||
auto cdesc = desc + it->second;
|
||||
|
||||
ret[it->second] = true;
|
||||
foundrequested = true;
|
||||
|
||||
if(crdesc->mlookup.empty() && cdesc->code==TypeCode::Struct) {
|
||||
// implicit select of all fields sub-struct
|
||||
|
||||
for(auto& pair2 : cdesc->mlookup)
|
||||
ret[it->second + pair2.second] = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
// request of non-existant field
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if(!fields.valid()) {
|
||||
foundrequested = true;
|
||||
|
||||
} else {
|
||||
// .fields isn't a sub-struct
|
||||
}
|
||||
|
||||
if(!foundrequested)
|
||||
throw std::runtime_error("pvRequest selects no fields");
|
||||
|
||||
if(ret.findSet(1)==ret.size()) {
|
||||
// empty mask is wildcard
|
||||
for(auto bit : range(desc->size()))
|
||||
ret[bit] = true;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
}} // namespace pvxs::impl
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* pvxs is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#ifndef PVREQUEST_H
|
||||
#define PVREQUEST_H
|
||||
|
||||
#include "utilpvt.h"
|
||||
#include <pvxs/bitmask.h>
|
||||
#include <pvxs/data.h>
|
||||
|
||||
namespace pvxs {
|
||||
namespace impl {
|
||||
|
||||
PVXS_API
|
||||
BitMask request2mask(const FieldDesc* desc, const Value& pvRequest);
|
||||
|
||||
}} // namespace pvxs::impl
|
||||
|
||||
#endif // PVREQUEST_H
|
||||
+51
-1
@@ -14,6 +14,7 @@
|
||||
#include "utilpvt.h"
|
||||
#include "pvaproto.h"
|
||||
#include "dataimpl.h"
|
||||
#include "pvrequest.h"
|
||||
|
||||
using namespace pvxs;
|
||||
namespace {
|
||||
@@ -509,11 +510,59 @@ void testIter()
|
||||
testMarked(6u)<<"mark sub-struct";
|
||||
}
|
||||
|
||||
void testPvRequest()
|
||||
{
|
||||
namespace M = members;
|
||||
|
||||
testDiag("%s", __func__);
|
||||
|
||||
auto def = nt::NTScalar{TypeCode::String}.build();
|
||||
auto val = def.create();
|
||||
testShow()<<val;
|
||||
|
||||
{
|
||||
auto rdef = TypeDef(TypeCode::Struct, {
|
||||
M::Struct("field", {})
|
||||
});
|
||||
|
||||
auto mask = request2mask(Value::Helper::desc(val), rdef.create());
|
||||
|
||||
testEq(mask, BitMask({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 10u));
|
||||
}
|
||||
|
||||
{
|
||||
auto rdef = TypeDef(TypeCode::Struct, {
|
||||
M::Struct("field", {
|
||||
M::Struct("value", {}),
|
||||
})
|
||||
});
|
||||
|
||||
auto mask = request2mask(Value::Helper::desc(val), rdef.create());
|
||||
|
||||
testEq(mask, BitMask({0, 1}, 10u));
|
||||
}
|
||||
|
||||
{
|
||||
auto rdef = TypeDef(TypeCode::Struct, {
|
||||
M::Struct("field", {
|
||||
M::Struct("timeStamp", {}),
|
||||
M::Struct("alarm", {
|
||||
M::Struct("status", {}),
|
||||
}),
|
||||
})
|
||||
});
|
||||
|
||||
auto mask = request2mask(Value::Helper::desc(val), rdef.create());
|
||||
|
||||
testEq(mask, BitMask({0, 2, 4, 6, 7, 8, 9}, 10u));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(testdata)
|
||||
{
|
||||
testPlan(76);
|
||||
testPlan(79);
|
||||
testSerialize1();
|
||||
testDeserialize1();
|
||||
testSimpleDef();
|
||||
@@ -523,6 +572,7 @@ MAIN(testdata)
|
||||
testAssign();
|
||||
testName();
|
||||
testIter();
|
||||
testPvRequest();
|
||||
cleanup_for_valgrind();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user