diff --git a/src/factory/PVStructure.cpp b/src/factory/PVStructure.cpp index 9568b07..be65a9e 100644 --- a/src/factory/PVStructure.cpp +++ b/src/factory/PVStructure.cpp @@ -89,7 +89,8 @@ PVFieldPtr PVStructure::getSubFieldImpl(size_t fieldOffset, bool throws) const const PVStructure *current = this; recurse: - if(fieldOffset<=current->getFieldOffset() || fieldOffset>current->getNextFieldOffset()) { + // we don't permit self lookup + if(fieldOffset<=current->getFieldOffset() || fieldOffset>=current->getNextFieldOffset()) { if(throws) { std::stringstream ss; ss << "Failed to get field with offset " @@ -104,7 +105,7 @@ recurse: const PVFieldPtr& pvField = current->pvFields[i]; if(pvField->getFieldOffset()==fieldOffset) { - return pvFields[i]; + return pvField; } else if(pvField->getNextFieldOffset()<=fieldOffset) { continue; diff --git a/testApp/pv/testPVData.cpp b/testApp/pv/testPVData.cpp index e465fa1..b8f2410 100644 --- a/testApp/pv/testPVData.cpp +++ b/testApp/pv/testPVData.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -625,21 +626,77 @@ static void testFieldAccess() } } +static void testSubField() +{ + PVStructurePtr value(ValueBuilder() + .add("a", 0) + .addNested("B") + .add("b", 0) + .addNested("C") + .add("c", 0) + .add("d", 0) + .endNested() + .add("e", 0) + .endNested() + .add("z", 0) + .buildPVStructure()); + +#define SHOW(FLD) testDiag("index '" FLD "' -> %u", unsigned(value->getSubFieldT(FLD)->getFieldOffset())) + SHOW("a"); + SHOW("B"); + SHOW("B.b"); + SHOW("B.C"); + SHOW("B.C.c"); + SHOW("B.C.d"); + SHOW("B.e"); + SHOW("z"); +#undef SHOW + +#define SHOW(IDX) testDiag("index " #IDX " -> %s", value->getSubFieldT(IDX)->getFullName().c_str()) + SHOW(1); + SHOW(2); + SHOW(3); + SHOW(4); + SHOW(5); + SHOW(6); + SHOW(7); + SHOW(8); +#undef SHOW + +#define CHECK(FLD) testOk1(value->getSubFieldT(FLD)==value->getSubFieldT(value->getSubFieldT(FLD)->getFieldOffset())) + CHECK("a"); + CHECK("B"); + CHECK("B.b"); + CHECK("B.C"); + CHECK("B.C.c"); + CHECK("B.C.d"); + CHECK("B.e"); + CHECK("z"); +#undef CHECK + +} + MAIN(testPVData) { - testPlan(243); - fieldCreate = getFieldCreate(); - pvDataCreate = getPVDataCreate(); - standardField = getStandardField(); - standardPVField = getStandardPVField(); - convert = getConvert(); - testCreatePVStructure(); - testCreatePVStructureWithInvalidName(); - testPVScalar(); - testScalarArray(); - testRequest(); - testCopy(); - testFieldAccess(); + testPlan(251); + try{ + fieldCreate = getFieldCreate(); + pvDataCreate = getPVDataCreate(); + standardField = getStandardField(); + standardPVField = getStandardPVField(); + convert = getConvert(); + testCreatePVStructure(); + testCreatePVStructureWithInvalidName(); + testPVScalar(); + testScalarArray(); + testRequest(); + testCopy(); + testFieldAccess(); + testSubField(); + }catch(std::exception& e){ + PRINT_EXCEPTION(e); + testAbort("Unhandled Exception: %s", e.what()); + } return testDone(); }