reduce # of PVStructure::getSubField overloads
This commit is contained in:
@@ -84,50 +84,41 @@ const PVFieldPtrArray & PVStructure::getPVFields() const
|
||||
return pvFields;
|
||||
}
|
||||
|
||||
PVFieldPtr PVStructure::getSubField(const char * fieldName) const
|
||||
PVFieldPtr PVStructure::getSubFieldImpl(size_t fieldOffset, bool throws) const
|
||||
{
|
||||
PVField * field = getSubFieldImpl(fieldName, false);
|
||||
if (field)
|
||||
return field->shared_from_this();
|
||||
else
|
||||
return PVFieldPtr();
|
||||
}
|
||||
const PVStructure *current = this;
|
||||
|
||||
|
||||
PVFieldPtr PVStructure::getSubField(size_t fieldOffset) const
|
||||
{
|
||||
if(fieldOffset<=getFieldOffset()) {
|
||||
return PVFieldPtr();
|
||||
}
|
||||
if(fieldOffset>getNextFieldOffset()) return PVFieldPtr();
|
||||
size_t numFields = pvFields.size();
|
||||
for(size_t i=0; i<numFields; i++) {
|
||||
PVFieldPtr pvField = pvFields[i];
|
||||
if(pvField->getFieldOffset()==fieldOffset) return pvFields[i];
|
||||
if(pvField->getNextFieldOffset()<=fieldOffset) continue;
|
||||
if(pvField->getField()->getType()==structure) {
|
||||
PVStructure *pvStructure = static_cast<PVStructure *>(pvField.get());
|
||||
return pvStructure->getSubField(fieldOffset);
|
||||
recurse:
|
||||
if(fieldOffset<=current->getFieldOffset() || fieldOffset>current->getNextFieldOffset()) {
|
||||
if(throws) {
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field with offset "
|
||||
<< fieldOffset << " (Invalid offset)" ;
|
||||
throw std::runtime_error(ss.str());
|
||||
} else {
|
||||
return PVFieldPtr();
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i=0, numFields = current->pvFields.size(); i<numFields; i++) {
|
||||
const PVFieldPtr& pvField = current->pvFields[i];
|
||||
|
||||
if(pvField->getFieldOffset()==fieldOffset) {
|
||||
return pvFields[i];
|
||||
|
||||
} else if(pvField->getNextFieldOffset()<=fieldOffset) {
|
||||
continue;
|
||||
|
||||
} else if(pvField->getField()->getType()==structure) {
|
||||
current = static_cast<PVStructure *>(pvField.get());
|
||||
goto recurse;
|
||||
}
|
||||
}
|
||||
// the first test against current->getNextFieldOffset() would avoid this
|
||||
throw std::logic_error("PVStructure.getSubField: Logic error");
|
||||
}
|
||||
|
||||
PVFieldPtr PVStructure::getSubFieldT(std::size_t fieldOffset) const
|
||||
{
|
||||
PVFieldPtr pvField = getSubField(fieldOffset);
|
||||
if (pvField.get())
|
||||
return pvField;
|
||||
else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field with offset "
|
||||
<< fieldOffset << "(Invalid offset)" ;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
PVField* PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
PVFieldPtr PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
{
|
||||
const PVStructure *parent = this;
|
||||
if(!name)
|
||||
@@ -135,7 +126,7 @@ PVField* PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
if (throws)
|
||||
throw std::invalid_argument("Failed to get field: (Field name is NULL string)");
|
||||
else
|
||||
return NULL;
|
||||
return PVFieldPtr();
|
||||
}
|
||||
const char *fullName = name;
|
||||
while(true) {
|
||||
@@ -151,7 +142,7 @@ PVField* PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return PVFieldPtr();
|
||||
}
|
||||
size_t N = sep-name;
|
||||
if(N==0)
|
||||
@@ -164,7 +155,7 @@ PVField* PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return PVFieldPtr();
|
||||
}
|
||||
|
||||
const PVFieldPtrArray& pvFields = parent->getPVFields();
|
||||
@@ -191,7 +182,7 @@ PVField* PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
return PVFieldPtr();
|
||||
}
|
||||
|
||||
if(*sep) {
|
||||
@@ -215,11 +206,25 @@ PVField* PVStructure::getSubFieldImpl(const char *name, bool throws) const
|
||||
// loop around to new parent
|
||||
|
||||
} else {
|
||||
return child;
|
||||
return child->shared_from_this();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PVStructure::throwBadFieldType(const char *name)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "Failed to get field: " << name << " (Field has wrong type)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void PVStructure::throwBadFieldType(std::size_t fieldOffset)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field with offset "
|
||||
<< fieldOffset << " (Field has wrong type)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
void PVStructure::serialize(ByteBuffer *pbuffer,
|
||||
SerializableControl *pflusher) const {
|
||||
|
||||
122
src/pv/pvData.h
122
src/pv/pvData.h
@@ -778,17 +778,6 @@ public:
|
||||
* @return The array.
|
||||
*/
|
||||
const PVFieldPtrArray & getPVFields() const;
|
||||
/**
|
||||
* Get the subfield with the specified name.
|
||||
* @param fieldName The name of the field.
|
||||
* @return Pointer to the field or null if field does not exist.
|
||||
*/
|
||||
FORCE_INLINE PVFieldPtr getSubField(std::string const &fieldName) const
|
||||
{
|
||||
return getSubField(fieldName.c_str());
|
||||
}
|
||||
|
||||
PVFieldPtr getSubField(const char *fieldName) const;
|
||||
|
||||
/**
|
||||
* Get a subfield with the specified name.
|
||||
@@ -798,20 +787,16 @@ public:
|
||||
* PVIntPtr ptr = pvStruct->getSubField<PVInt>("substruct.leaffield");
|
||||
* @endcode
|
||||
*/
|
||||
template<typename PVT>
|
||||
template<typename PVT = PVField>
|
||||
FORCE_INLINE std::tr1::shared_ptr<PVT> getSubField(std::string const &fieldName) const
|
||||
{
|
||||
return this->getSubField<PVT>(fieldName.c_str());
|
||||
}
|
||||
|
||||
template<typename PVT>
|
||||
template<typename PVT = PVField>
|
||||
std::tr1::shared_ptr<PVT> getSubField(const char *name) const
|
||||
{
|
||||
PVField *raw = getSubFieldImpl(name, false);
|
||||
if (raw)
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(raw->shared_from_this());
|
||||
else
|
||||
return std::tr1::shared_ptr<PVT>();
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(getSubFieldImpl(name, false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -819,32 +804,10 @@ public:
|
||||
* @param fieldOffset The offset.
|
||||
* @return Pointer to the field or null if field does not exist.
|
||||
*/
|
||||
PVFieldPtr getSubField(std::size_t fieldOffset) const;
|
||||
|
||||
/**
|
||||
* Get the subfield with the specified offset.
|
||||
* @param fieldOffset The offset.
|
||||
* @return Pointer to the field or null if field does not exist.
|
||||
*/
|
||||
template<typename PVT>
|
||||
template<typename PVT = PVField>
|
||||
std::tr1::shared_ptr<PVT> getSubField(std::size_t fieldOffset) const
|
||||
{
|
||||
PVFieldPtr pvField = getSubField(fieldOffset);
|
||||
if (pvField.get())
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(pvField);
|
||||
else
|
||||
return std::tr1::shared_ptr<PVT>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a subfield with the specified name.
|
||||
* @param fieldName a '.' separated list of child field names (no whitespace allowed)
|
||||
* @returns A reference to the sub-field (never NULL)
|
||||
* @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type
|
||||
*/
|
||||
FORCE_INLINE PVFieldPtr getSubFieldT(std::string const &fieldName) const
|
||||
{
|
||||
return getSubFieldImpl(fieldName.c_str())->shared_from_this();
|
||||
return std::tr1::dynamic_pointer_cast<PVT>(getSubFieldImpl(fieldOffset, false));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -856,22 +819,29 @@ public:
|
||||
* PVIntPtr ptr = pvStruct->getSubFieldT<PVInt>("substruct.leaffield");
|
||||
* @endcode
|
||||
*/
|
||||
template<typename PVT>
|
||||
template<typename PVT = PVField>
|
||||
FORCE_INLINE std::tr1::shared_ptr<PVT> getSubFieldT(std::string const &fieldName) const
|
||||
{
|
||||
return this->getSubFieldT<PVT>(fieldName.c_str());
|
||||
}
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubFieldT(const char *name) const;
|
||||
private:
|
||||
static void throwBadFieldType(const char *name);
|
||||
public:
|
||||
|
||||
/**
|
||||
* Get the subfield with the specified offset.
|
||||
* @param fieldOffset The offset.
|
||||
* @returns A reference to the sub-field (never NULL)
|
||||
* @throws std::runtime_error if the requested sub-field doesn't exist
|
||||
*/
|
||||
PVFieldPtr getSubFieldT(std::size_t fieldOffset) const;
|
||||
template<typename PVT = PVField>
|
||||
std::tr1::shared_ptr<PVT> getSubFieldT(const char *name) const
|
||||
{
|
||||
std::tr1::shared_ptr<PVT> pvField(std::tr1::dynamic_pointer_cast<PVT>(
|
||||
getSubFieldImpl(name, true)));
|
||||
if(!pvField)
|
||||
throwBadFieldType(name);
|
||||
return pvField;
|
||||
}
|
||||
|
||||
private:
|
||||
static void throwBadFieldType(std::size_t fieldOffset);
|
||||
public:
|
||||
|
||||
/**
|
||||
* Get the subfield with the specified offset.
|
||||
@@ -879,8 +849,16 @@ public:
|
||||
* @returns A reference to the sub-field (never NULL)
|
||||
* @throws std::runtime_error if the requested sub-field doesn't exist, or has a different type
|
||||
*/
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> getSubFieldT(std::size_t fieldOffset) const;
|
||||
template<typename PVT = PVField>
|
||||
std::tr1::shared_ptr<PVT> getSubFieldT(std::size_t fieldOffset) const
|
||||
{
|
||||
std::tr1::shared_ptr<PVT> pvField = std::tr1::dynamic_pointer_cast<PVT>(
|
||||
getSubFieldImpl(fieldOffset, true));
|
||||
if(!pvField)
|
||||
throwBadFieldType(fieldOffset);
|
||||
return pvField;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Serialize.
|
||||
@@ -932,7 +910,8 @@ public:
|
||||
void copyUnchecked(const PVStructure& from, const BitSet& maskBitSet, bool inverse = false);
|
||||
|
||||
private:
|
||||
PVField *getSubFieldImpl(const char *name, bool throws = true) const;
|
||||
PVFieldPtr getSubFieldImpl(const char *name, bool throws) const;
|
||||
PVFieldPtr getSubFieldImpl(std::size_t fieldOffset, bool throws) const;
|
||||
|
||||
PVFieldPtrArray pvFields;
|
||||
StructureConstPtr structurePtr;
|
||||
@@ -940,39 +919,6 @@ private:
|
||||
friend class PVDataCreate;
|
||||
};
|
||||
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> PVStructure::getSubFieldT(const char *name) const
|
||||
{
|
||||
std::tr1::shared_ptr<PVT> pvField = std::tr1::dynamic_pointer_cast<PVT>(
|
||||
getSubFieldImpl(name)->shared_from_this());
|
||||
|
||||
if (pvField.get())
|
||||
return pvField;
|
||||
else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field: " << name << " (Field has wrong type)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename PVT>
|
||||
std::tr1::shared_ptr<PVT> PVStructure::getSubFieldT(std::size_t fieldOffset) const
|
||||
{
|
||||
std::tr1::shared_ptr<PVT> pvField = std::tr1::dynamic_pointer_cast<PVT>(
|
||||
getSubFieldT(fieldOffset));
|
||||
if (pvField.get())
|
||||
return pvField;
|
||||
else
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "Failed to get field with offset "
|
||||
<< fieldOffset << " (Field has wrong type)";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PVUnion has a single subfield.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user