diff --git a/src/factory/PVStructure.cpp b/src/factory/PVStructure.cpp index 5d61056..12afbb8 100644 --- a/src/factory/PVStructure.cpp +++ b/src/factory/PVStructure.cpp @@ -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(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(pvField->getField()); - if(pscalarArray->getElementType()!=elementType) { - return nullPVScalarArray; - } - return std::tr1::static_pointer_cast(pvField); - }catch(...){ + PVScalarArrayPtr arrayField = getSubField(fieldName); + if (arrayField.get() && + arrayField->getScalarArray()->getElementType()!=elementType) + { return nullPVScalarArray; - } + } + return arrayField; } PVStructureArrayPtr PVStructure::getStructureArrayField( diff --git a/src/pv/pvData.h b/src/pv/pvData.h index 7384cac..6dc27dc 100644 --- a/src/pv/pvData.h +++ b/src/pv/pvData.h @@ -712,7 +712,7 @@ public: } private: - PVField *GetAsImpl(const char *name) const; + PVField *GetAsImpl(const char *name, bool throws = true) const; public: /**