Implement getSubField functions without using exceptions
Implementation of getSubField (and getScalarArrayField) introduced in the getAs pull request throws an exception then catches it to return a null pointer. Implement without throwing. Signed-off-by: Dave Hickin <david.hickin@diamond.ac.uk>
This commit is contained in:
@@ -107,11 +107,11 @@ const PVFieldPtrArray & PVStructure::getPVFields() const
|
||||
|
||||
PVFieldPtr PVStructure::getSubField(string const &fieldName) const
|
||||
{
|
||||
try{
|
||||
return GetAsImpl(fieldName.c_str())->shared_from_this();
|
||||
}catch(...){
|
||||
return PVFieldPtr();
|
||||
}
|
||||
PVField * field = GetAsImpl(fieldName.c_str(), false);
|
||||
if (field)
|
||||
return field->shared_from_this();
|
||||
else
|
||||
return PVFieldPtr();
|
||||
}
|
||||
|
||||
|
||||
@@ -134,21 +134,34 @@ PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const
|
||||
throw std::logic_error("PVStructure.getSubField: Logic error");
|
||||
}
|
||||
|
||||
PVField* PVStructure::GetAsImpl(const char *name) const
|
||||
PVField* PVStructure::GetAsImpl(const char *name, bool throws) const
|
||||
{
|
||||
const PVStructure *parent = this;
|
||||
if(!name)
|
||||
throw std::invalid_argument("field name is NULL string");
|
||||
|
||||
{
|
||||
if (throws)
|
||||
throw std::invalid_argument("field name is NULL string");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
while(true) {
|
||||
const char *sep=name;
|
||||
while(*sep!='\0' && *sep!='.' && *sep!=' ') sep++;
|
||||
if(*sep==' ')
|
||||
throw std::runtime_error("No spaces allowed in field name");
|
||||
|
||||
{
|
||||
if (throws)
|
||||
throw std::runtime_error("No spaces allowed in field name ");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
size_t N = sep-name;
|
||||
if(N==0)
|
||||
throw std::runtime_error("zero-length field name encountered");
|
||||
{
|
||||
if (throws)
|
||||
throw std::runtime_error("zero-length field name encountered");
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const PVFieldPtrArray& pvFields = parent->getPVFields();
|
||||
|
||||
@@ -165,13 +178,23 @@ PVField* PVStructure::GetAsImpl(const char *name) const
|
||||
}
|
||||
|
||||
if(!child)
|
||||
throw std::runtime_error("field not found"); //TODO: which sub field?
|
||||
{
|
||||
if (throws)
|
||||
throw std::runtime_error("field not found"); //TODO: which sub field?
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(*sep) {
|
||||
// this is not the requested leaf
|
||||
parent = dynamic_cast<PVStructure*>(child);
|
||||
if(!parent)
|
||||
throw std::runtime_error("mid-field is not a PVStructure"); //TODO: which sub field?
|
||||
{
|
||||
if (throws)
|
||||
throw std::runtime_error("mid-field is not a PVStructure"); //TODO: which sub field?
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
child = NULL;
|
||||
name = sep+1; // skip past '.'
|
||||
// loop around to new parent
|
||||
@@ -256,22 +279,13 @@ PVUnionPtr PVStructure::getUnionField(string const &fieldName)
|
||||
PVScalarArrayPtr PVStructure::getScalarArrayField(
|
||||
string const &fieldName,ScalarType elementType)
|
||||
{
|
||||
try{
|
||||
PVFieldPtr pvField = GetAsImpl(fieldName.c_str())->shared_from_this();
|
||||
FieldConstPtr field = pvField->getField();
|
||||
Type type = field->getType();
|
||||
if(type!=scalarArray) {
|
||||
return nullPVScalarArray;
|
||||
}
|
||||
ScalarArrayConstPtr pscalarArray
|
||||
= static_pointer_cast<const ScalarArray>(pvField->getField());
|
||||
if(pscalarArray->getElementType()!=elementType) {
|
||||
return nullPVScalarArray;
|
||||
}
|
||||
return std::tr1::static_pointer_cast<PVScalarArray>(pvField);
|
||||
}catch(...){
|
||||
PVScalarArrayPtr arrayField = getSubField<PVScalarArray>(fieldName);
|
||||
if (arrayField.get() &&
|
||||
arrayField->getScalarArray()->getElementType()!=elementType)
|
||||
{
|
||||
return nullPVScalarArray;
|
||||
}
|
||||
}
|
||||
return arrayField;
|
||||
}
|
||||
|
||||
PVStructureArrayPtr PVStructure::getStructureArrayField(
|
||||
|
||||
@@ -712,7 +712,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
PVField *GetAsImpl(const char *name) const;
|
||||
PVField *GetAsImpl(const char *name, bool throws = true) const;
|
||||
public:
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user