diff --git a/src/lib/ebus/data.cpp b/src/lib/ebus/data.cpp index d05e0efd..6b21a183 100644 --- a/src/lib/ebus/data.cpp +++ b/src/lib/ebus/data.cpp @@ -997,6 +997,29 @@ string DataFieldSet::getName(ssize_t fieldIndex) const { return ostream.str(); } +const SingleDataField* DataFieldSet::getField(ssize_t fieldIndex) const { + if (fieldIndex < (ssize_t)m_ignoredCount) { + return nullptr; + } + if ((size_t)fieldIndex + m_ignoredCount >= m_fields.size()) { + return nullptr; + } + if (m_ignoredCount == 0) { + return m_fields[fieldIndex]; + } + ssize_t remain = fieldIndex; + for (const auto field : m_fields) { + if (field->isIgnored()) { + continue; + } + remain--; + if (remain == 0) { + return field; + } + } + return nullptr; +} + result_t DataFieldSet::derive(const string& name, PartType partType, int divisor, const map& values, map* attributes, vector* fields) const { diff --git a/src/lib/ebus/data.h b/src/lib/ebus/data.h index 3622a1d3..bd56ac17 100755 --- a/src/lib/ebus/data.h +++ b/src/lib/ebus/data.h @@ -270,6 +270,13 @@ class DataField : public AttributedItem { */ virtual string getName(ssize_t fieldIndex) const = 0; + /** + * Get the specified field. + * @param fieldIndex the index of the field (excluding ignored fields). + * @return the field, or @a nullptr if not available. + */ + virtual const SingleDataField* getField(ssize_t fieldIndex) const = 0; + /** * Dump the field settings to the output. * @param prependFieldSeparator whether to start with a @a FIELD_SEPARATOR. @@ -417,6 +424,20 @@ class SingleDataField : public DataField { return isIgnored() || fieldIndex > 0 ? "" : m_name; } + // @copydoc + virtual const SingleDataField* getField(ssize_t fieldIndex) const { + if (isIgnored() || fieldIndex > 0) { + return nullptr; + } + return const_cast(this); + } + + /** + * Return the data type definition. + * @return the data type definition. + */ + const DataType* getDataType() const { return m_dataType; } + /** * Dump the common prefix field settings to the output (name and part type). * @param prependFieldSeparator whether to start with a @a FIELD_SEPARATOR. @@ -658,6 +679,9 @@ class DataFieldSet : public DataField { // @copydoc string getName(ssize_t fieldIndex) const override; + // @copydoc + const SingleDataField* getField(ssize_t fieldIndex) const override; + // @copydoc result_t derive(const string& name, PartType partType, int divisor, const map& values, map* attributes, diff --git a/src/lib/ebus/message.h b/src/lib/ebus/message.h index 353267fc..e94eece2 100644 --- a/src/lib/ebus/message.h +++ b/src/lib/ebus/message.h @@ -285,6 +285,13 @@ class Message : public AttributedItem { */ string getFieldName(ssize_t fieldIndex) const { return m_data->getName(fieldIndex); } + /** + * Get the specified field. + * @param fieldIndex the index of the field (excluding ignored fields). + * @return the field, or @a nullptr if not available. + */ + const SingleDataField* getField(ssize_t fieldIndex) const { return m_data->getField(fieldIndex); } + /** * Get whether this is a write message. * @return whether this is a write message.