Create Filters class to store filter functions
Enhanced the generated code to now store the filter functions within an
array contained in a struct similar to other configured parameters.
This allows the generated property watches to use an index within that
array to access a pointer to a Filters class containing a given set of
filter functions. The set of filter functions would then be applied
against all the properties being watched.
Tested:
Generated code provides structure needed to access filter functions
Filter functions filter property values that fail the filter(s)
Change-Id: I8f1f882704de521f2ab393530ad7ef096314975d
Signed-off-by: Matthew Barth <msbarth@us.ibm.com>
diff --git a/src/filters.hpp b/src/filters.hpp
new file mode 100644
index 0000000..c7a5bcf
--- /dev/null
+++ b/src/filters.hpp
@@ -0,0 +1,88 @@
+#pragma once
+
+#include "data_types.hpp"
+
+#include <algorithm>
+#include <functional>
+
+namespace phosphor
+{
+namespace dbus
+{
+namespace monitoring
+{
+
+/** @class Filters
+ * @brief Filter interface
+ *
+ * Filters of any type can be applied to property value changes.
+ */
+class Filters
+{
+ public:
+ Filters() = default;
+ Filters(const Filters&) = delete;
+ Filters(Filters&&) = default;
+ Filters& operator=(const Filters&) = delete;
+ Filters& operator=(Filters&&) = default;
+ virtual ~Filters() = default;
+
+ /** @brief Apply filter operations to a property value. */
+ virtual bool operator()(const any_ns::any& value) = 0;
+};
+
+/** @class OperandFilters
+ * @brief Filter property values utilzing operand based functions.
+ *
+ * When configured, an operand filter is applied to a property value each
+ * time it changes to determine if that property value should be filtered
+ * from being stored or used within a given callback function.
+ */
+template <typename T>
+class OperandFilters : public Filters
+{
+ public:
+ OperandFilters() = delete;
+ OperandFilters(const OperandFilters&) = delete;
+ OperandFilters(OperandFilters&&) = default;
+ OperandFilters& operator=(const OperandFilters&) = delete;
+ OperandFilters& operator=(OperandFilters&&) = default;
+ virtual ~OperandFilters() = default;
+ explicit OperandFilters(const std::vector<std::function<bool(T)>>& _ops) :
+ Filters(), ops(std::move(_ops))
+ {
+ }
+
+ bool operator()(const any_ns::any& value) override
+ {
+ for (const auto& filterOps : ops)
+ {
+ try
+ {
+ // Apply filter operand to property value
+ if (!filterOps(any_ns::any_cast<T>(value)))
+ {
+ // Property value should be filtered
+ return true;
+ }
+ }
+ catch (const any_ns::bad_any_cast& bac)
+ {
+ // Unable to cast property value to filter value type
+ // to check filter, continue to next filter op
+ continue;
+ }
+ }
+
+ // Property value should not be filtered
+ return false;
+ }
+
+ private:
+ /** @brief List of operand based filter functions. */
+ const std::vector<std::function<bool(T)>> ops;
+};
+
+} // namespace monitoring
+} // namespace dbus
+} // namespace phosphor