add PVRequestMapper
utility to having pvRequest .field mangling Warn if requesting some non-existant fields. Error if no requested fields exist. PVRequestMapper mode enum to select between two "styles" of interpretation.
This commit is contained in:
@@ -434,14 +434,380 @@ static void testMask()
|
||||
.set(V->getSubField("A")->getFieldOffset()));
|
||||
}
|
||||
|
||||
static
|
||||
void testMapper(PVRequestMapper::mode_t mode)
|
||||
{
|
||||
testDiag("=== %s mode==%d", CURRENT_FUNCTION, (int)mode);
|
||||
{
|
||||
testDiag("Map full structure");
|
||||
|
||||
PVStructurePtr base(getPVDataCreate()->createPVStructure(maskingType));
|
||||
PVRequestMapper mapper(*base, *createRequest(""), mode);
|
||||
|
||||
testEqual(mapper.requested(), maskingType);
|
||||
|
||||
testEqual(mapper.requestedMask(), BitSet().set(0)
|
||||
.set(base->getSubFieldT("A")->getFieldOffset())
|
||||
.set(base->getSubFieldT("B")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.D")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
|
||||
PVStructurePtr req(getPVDataCreate()->createPVStructure(mapper.requested()));
|
||||
|
||||
base->getSubFieldT<PVInt>("A")->put(1);
|
||||
base->getSubFieldT<PVInt>("B")->put(42);
|
||||
|
||||
BitSet output;
|
||||
mapper.copyBaseToRequested(*base, BitSet().set(0), *req, output);
|
||||
|
||||
testFieldEqual<PVInt>(req, "A", 1);
|
||||
testFieldEqual<PVInt>(req, "B", 42);
|
||||
|
||||
req->getSubFieldT<PVInt>("A")->put(2);
|
||||
req->getSubFieldT<PVInt>("B")->put(43);
|
||||
|
||||
mapper.copyBaseFromRequested(*base, output, *req, BitSet().set(0));
|
||||
|
||||
testFieldEqual<PVInt>(req, "A", 2);
|
||||
testFieldEqual<PVInt>(req, "B", 43);
|
||||
testEqual(mapper.requestedMask(), BitSet().set(0).set(1).set(2).set(3).set(4).set(5).set(6));
|
||||
}
|
||||
{
|
||||
testDiag("Map single leaf field");
|
||||
|
||||
PVStructurePtr base(getPVDataCreate()->createPVStructure(maskingType));
|
||||
PVRequestMapper mapper(*base, *createRequest("field(B)"), mode);
|
||||
|
||||
if(mode==PVRequestMapper::Slice)
|
||||
testNotEqual(mapper.requested(), maskingType);
|
||||
else
|
||||
testEqual(mapper.requested(), maskingType);
|
||||
|
||||
testEqual(mapper.requestedMask(), BitSet().set(0)
|
||||
.set(base->getSubFieldT("B")->getFieldOffset()));
|
||||
|
||||
PVStructurePtr req(getPVDataCreate()->createPVStructure(mapper.requested()));
|
||||
|
||||
if(mode==PVRequestMapper::Slice)
|
||||
testOk1(!req->getSubField("A"));
|
||||
|
||||
base->getSubFieldT<PVScalar>("A")->putFrom<int32>(11);
|
||||
base->getSubFieldT<PVScalar>("B")->putFrom<int32>(42);
|
||||
|
||||
BitSet output;
|
||||
mapper.copyBaseToRequested(*base, BitSet().set(0), *req, output);
|
||||
|
||||
if(mode!=PVRequestMapper::Slice)
|
||||
testFieldEqual<PVInt>(req, "A", 0);
|
||||
testFieldEqual<PVInt>(req, "B", 42);
|
||||
|
||||
req->getSubFieldT<PVScalar>("B")->putFrom<int32>(43);
|
||||
|
||||
mapper.copyBaseFromRequested(*base, output, *req, BitSet().set(0));
|
||||
|
||||
testFieldEqual<PVInt>(req, "B", 43);
|
||||
testEqual(mapper.requestedMask(), BitSet().set(0)
|
||||
.set(base->getSubFieldT("B")->getFieldOffset()));
|
||||
|
||||
BitSet cmp;
|
||||
mapper.maskBaseToRequested(BitSet().set(base->getSubFieldT("B")->getFieldOffset()), cmp);
|
||||
testEqual(cmp, BitSet()
|
||||
.set(req->getSubFieldT("B")->getFieldOffset()));
|
||||
|
||||
cmp.clear();
|
||||
mapper.maskBaseFromRequested(cmp, BitSet()
|
||||
.set(req->getSubFieldT("B")->getFieldOffset()));
|
||||
testEqual(cmp, BitSet()
|
||||
.set(base->getSubFieldT("B")->getFieldOffset()));
|
||||
}
|
||||
{
|
||||
testDiag("Map two sub-fields");
|
||||
|
||||
PVStructurePtr base(getPVDataCreate()->createPVStructure(maskingType));
|
||||
PVRequestMapper mapper(*base, *createRequest("B,C.D"), mode);
|
||||
|
||||
if(mode==PVRequestMapper::Slice)
|
||||
testNotEqual(mapper.requested(), maskingType);
|
||||
else
|
||||
testEqual(mapper.requested(), maskingType);
|
||||
|
||||
testEqual(mapper.requestedMask(), BitSet().set(0)
|
||||
.set(base->getSubFieldT("B")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.D")->getFieldOffset()));
|
||||
|
||||
PVStructurePtr req(getPVDataCreate()->createPVStructure(mapper.requested()));
|
||||
|
||||
if(mode==PVRequestMapper::Slice)
|
||||
testOk1(!req->getSubField("A"));
|
||||
|
||||
base->getSubFieldT<PVScalar>("A")->putFrom<int32>(11);
|
||||
base->getSubFieldT<PVScalar>("B")->putFrom<int32>(1);
|
||||
base->getSubFieldT<PVScalar>("C.D")->putFrom<int32>(42);
|
||||
|
||||
BitSet output;
|
||||
mapper.copyBaseToRequested(*base, BitSet().set(0), *req, output);
|
||||
|
||||
if(mode!=PVRequestMapper::Slice)
|
||||
testFieldEqual<PVInt>(req, "A", 0);
|
||||
testFieldEqual<PVInt>(req, "B", 1);
|
||||
testFieldEqual<PVInt>(req, "C.D", 42);
|
||||
|
||||
req->getSubFieldT<PVScalar>("B")->putFrom<int32>(2);
|
||||
req->getSubFieldT<PVScalar>("C.D")->putFrom<int32>(43);
|
||||
|
||||
mapper.copyBaseFromRequested(*base, output, *req, BitSet().set(0));
|
||||
|
||||
testFieldEqual<PVInt>(req, "B", 2);
|
||||
testFieldEqual<PVInt>(req, "C.D", 43);
|
||||
testEqual(mapper.requestedMask(), BitSet().set(0)
|
||||
.set(base->getSubFieldT("B")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.D")->getFieldOffset()));
|
||||
}
|
||||
{
|
||||
testDiag("Map entire sub-structure");
|
||||
|
||||
PVStructurePtr base(getPVDataCreate()->createPVStructure(maskingType));
|
||||
PVRequestMapper mapper(*base, *createRequest("field(C.E)"), mode);
|
||||
|
||||
if(mode==PVRequestMapper::Slice)
|
||||
testNotEqual(mapper.requested(), maskingType);
|
||||
else
|
||||
testEqual(mapper.requested(), maskingType);
|
||||
|
||||
testEqual(mapper.requestedMask(), BitSet().set(0)
|
||||
.set(base->getSubFieldT("C")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
|
||||
|
||||
PVStructurePtr req(getPVDataCreate()->createPVStructure(mapper.requested()));
|
||||
|
||||
if(mode==PVRequestMapper::Slice)
|
||||
testOk1(!req->getSubField("A"));
|
||||
|
||||
base->getSubFieldT<PVScalar>("A")->putFrom<int32>(11);
|
||||
base->getSubFieldT<PVScalar>("C.E.F")->putFrom<int32>(42);
|
||||
|
||||
BitSet output;
|
||||
mapper.copyBaseToRequested(*base, BitSet().set(0), *req, output);
|
||||
|
||||
if(mode!=PVRequestMapper::Slice)
|
||||
testFieldEqual<PVInt>(req, "A", 0);
|
||||
testFieldEqual<PVInt>(req, "C.E.F", 42);
|
||||
|
||||
req->getSubFieldT<PVScalar>("C.E.F")->putFrom<int32>(43);
|
||||
|
||||
mapper.copyBaseFromRequested(*base, output, *req, BitSet().set(0));
|
||||
|
||||
testFieldEqual<PVInt>(req, "C.E.F", 43);
|
||||
testEqual(mapper.requestedMask(), BitSet().set(0)
|
||||
.set(base->getSubFieldT("C")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
|
||||
BitSet cmp;
|
||||
mapper.maskBaseToRequested(BitSet()
|
||||
.set(base->getSubFieldT("C")->getFieldOffset()), cmp);
|
||||
testEqual(cmp, BitSet()
|
||||
.set(req->getSubFieldT("C")->getFieldOffset())
|
||||
.set(req->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(req->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
|
||||
cmp.clear();
|
||||
mapper.maskBaseFromRequested(cmp, BitSet()
|
||||
.set(req->getSubFieldT("C")->getFieldOffset()));
|
||||
testEqual(cmp, BitSet()
|
||||
.set(base->getSubFieldT("C")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
}
|
||||
|
||||
struct MapperMask {
|
||||
PVStructurePtr base, req;
|
||||
BitSet bmask, rmask;
|
||||
PVRequestMapper mapper;
|
||||
|
||||
MapperMask(PVRequestMapper::mode_t mode) {
|
||||
base = getPVDataCreate()->createPVStructure(maskingType);
|
||||
mapper.compute(*base, *createRequest("field(B,C.E)"), mode);
|
||||
req = getPVDataCreate()->createPVStructure(mapper.requested());
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
base->getSubFieldT<PVScalar>("B")->putFrom<int32>(1);
|
||||
base->getSubFieldT<PVScalar>("C.E.F")->putFrom<int32>(3);
|
||||
req->getSubFieldT<PVScalar>("B")->putFrom<int32>(11);
|
||||
req->getSubFieldT<PVScalar>("C.E.F")->putFrom<int32>(13);
|
||||
}
|
||||
|
||||
void check(int32 bB, int32 bCEF, int32 rB, int32 rCEF) {
|
||||
testFieldEqual<PVInt>(base, "B", bB);
|
||||
testFieldEqual<PVInt>(base, "C.E.F", bCEF);
|
||||
testFieldEqual<PVInt>(req, "B", rB);
|
||||
testFieldEqual<PVInt>(req, "C.E.F", rCEF);
|
||||
}
|
||||
|
||||
void testEmptyMaskB2R() {
|
||||
mapper.copyBaseToRequested(*base, bmask, *req, rmask);
|
||||
check(1, 3, 11, 13);
|
||||
testEqual(bmask, BitSet());
|
||||
testEqual(rmask, BitSet());
|
||||
}
|
||||
|
||||
void testEmptyMaskR2B() {
|
||||
mapper.copyBaseFromRequested(*base, bmask, *req, rmask);
|
||||
check(1, 3, 11, 13);
|
||||
testEqual(bmask, BitSet());
|
||||
testEqual(rmask, BitSet());
|
||||
}
|
||||
|
||||
void testAllMaskB2R() {
|
||||
bmask.set(0);
|
||||
mapper.copyBaseToRequested(*base, bmask, *req, rmask);
|
||||
check(1, 3, 1, 3);
|
||||
testEqual(rmask, BitSet()
|
||||
.set(0)
|
||||
.set(req->getSubFieldT("B")->getFieldOffset())
|
||||
.set(req->getSubFieldT("C")->getFieldOffset())
|
||||
.set(req->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(req->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testAllMaskR2B() {
|
||||
rmask.set(0);
|
||||
mapper.copyBaseFromRequested(*base, bmask, *req, rmask);
|
||||
check(11, 13, 11, 13);
|
||||
testEqual(bmask, BitSet()
|
||||
.set(0)
|
||||
.set(base->getSubFieldT("B")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testMaskOneB2R() {
|
||||
bmask.set(base->getSubFieldT("B")->getFieldOffset());
|
||||
mapper.copyBaseToRequested(*base, bmask, *req, rmask);
|
||||
check(1, 3, 1, 13);
|
||||
testEqual(rmask, BitSet()
|
||||
.set(req->getSubFieldT("B")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testMaskOneR2B() {
|
||||
rmask.set(req->getSubFieldT("B")->getFieldOffset());
|
||||
mapper.copyBaseFromRequested(*base, bmask, *req, rmask);
|
||||
check(11, 3, 11, 13);
|
||||
testEqual(bmask, BitSet()
|
||||
.set(base->getSubFieldT("B")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testMaskOtherB2R() {
|
||||
bmask.set(base->getSubFieldT("C.E.F")->getFieldOffset());
|
||||
mapper.copyBaseToRequested(*base, bmask, *req, rmask);
|
||||
check(1, 3, 11, 3);
|
||||
testEqual(rmask, BitSet()
|
||||
.set(req->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testMaskOtherR2B() {
|
||||
rmask.set(req->getSubFieldT("C.E.F")->getFieldOffset());
|
||||
mapper.copyBaseFromRequested(*base, bmask, *req, rmask);
|
||||
check(1, 13, 11, 13);
|
||||
testEqual(bmask, BitSet()
|
||||
.set(base->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testMaskSub1B2R() {
|
||||
bmask.set(base->getSubFieldT("C.E")->getFieldOffset());
|
||||
mapper.copyBaseToRequested(*base, bmask, *req, rmask);
|
||||
check(1, 3, 11, 3);
|
||||
testEqual(rmask, BitSet()
|
||||
.set(req->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(req->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testMaskSub1R2B() {
|
||||
rmask.set(req->getSubFieldT("C.E")->getFieldOffset());
|
||||
mapper.copyBaseFromRequested(*base, bmask, *req, rmask);
|
||||
check(1, 13, 11, 13);
|
||||
testEqual(bmask, BitSet()
|
||||
.set(base->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testMaskSub2B2R() {
|
||||
bmask.set(base->getSubFieldT("C")->getFieldOffset());
|
||||
mapper.copyBaseToRequested(*base, bmask, *req, rmask);
|
||||
check(1, 3, 11, 3);
|
||||
testEqual(rmask, BitSet()
|
||||
.set(req->getSubFieldT("C")->getFieldOffset())
|
||||
.set(req->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(req->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
|
||||
void testMaskSub2R2B() {
|
||||
rmask.set(req->getSubFieldT("C")->getFieldOffset());
|
||||
mapper.copyBaseFromRequested(*base, bmask, *req, rmask);
|
||||
check(1, 13, 11, 13);
|
||||
testEqual(bmask, BitSet()
|
||||
.set(base->getSubFieldT("C")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E")->getFieldOffset())
|
||||
.set(base->getSubFieldT("C.E.F")->getFieldOffset()));
|
||||
}
|
||||
};
|
||||
|
||||
void testMaskWarn()
|
||||
{
|
||||
PVStructurePtr base(getPVDataCreate()->createPVStructure(maskingType));
|
||||
PVRequestMapper mapper(*base, *createRequest("field(B,invalid)"), PVRequestMapper::Slice);
|
||||
|
||||
testEqual(mapper.warnings(), "No field 'invalid' ");
|
||||
}
|
||||
|
||||
void testMaskErr()
|
||||
{
|
||||
PVStructurePtr base(getPVDataCreate()->createPVStructure(maskingType));
|
||||
testThrows(std::runtime_error, PVRequestMapper mapper(*base, *createRequest("field(invalid)"), PVRequestMapper::Slice));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(testCreateRequest)
|
||||
{
|
||||
testPlan(141);
|
||||
testPlan(329);
|
||||
testCreateRequestInternal();
|
||||
testBadRequest();
|
||||
testMask();
|
||||
testMapper(PVRequestMapper::Slice);
|
||||
testMapper(PVRequestMapper::Mask);
|
||||
#undef TEST_METHOD
|
||||
#define TEST_METHOD(KLASS, METHOD) \
|
||||
{ \
|
||||
testDiag("------- %s::%s Mask --------", #KLASS, #METHOD); \
|
||||
{ KLASS inst(PVRequestMapper::Mask); inst.METHOD(); } \
|
||||
testDiag("------- %s::%s Slice --------", #KLASS, #METHOD); \
|
||||
{ KLASS inst(PVRequestMapper::Slice); inst.METHOD(); } \
|
||||
}
|
||||
TEST_METHOD(MapperMask, testEmptyMaskB2R);
|
||||
TEST_METHOD(MapperMask, testEmptyMaskR2B);
|
||||
TEST_METHOD(MapperMask, testAllMaskB2R);
|
||||
TEST_METHOD(MapperMask, testAllMaskR2B);
|
||||
TEST_METHOD(MapperMask, testMaskOneB2R);
|
||||
TEST_METHOD(MapperMask, testMaskOneR2B);
|
||||
TEST_METHOD(MapperMask, testMaskOtherB2R);
|
||||
TEST_METHOD(MapperMask, testMaskOtherR2B);
|
||||
TEST_METHOD(MapperMask, testMaskSub1B2R);
|
||||
TEST_METHOD(MapperMask, testMaskSub1R2B);
|
||||
TEST_METHOD(MapperMask, testMaskSub2B2R);
|
||||
TEST_METHOD(MapperMask, testMaskSub2R2B);
|
||||
testMaskWarn();
|
||||
testMaskErr();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user