bios: Implement BIOSAttribute

BIOS tables are built based on json entry. When a bios attribute
is set by pldm, the corresponding dbus backend should be synchronized.

Then, the BIOSAttribute class is abstracted, and it provides the following two
interfaces

1. constructEntry: Construct the entry of the attribute/attribute-value table
2. setAttrValueOnDbus: Update the corresponding dbus backend

Specific types of attributes are implemented based on BIOSAttribute. eg
BIOSStringAttribute, BIOSEnumAttribute, BIOSIntegerAttribute.

Once the BIOS Handler is loaded, all attributes would be constructed from json.
We use BIOSConfig(class) to persist all attributes in ram.

BIOSConfig provides the following methods.

- buildTables: Build tables
- removeTables: Remove the persistent tables
- setAttrValue: Set attribute value on dbus and update the bios table
- getBIOSTable: Get bios table by table type

After we implemented BIOSConfig/BIOSSIntegerAttribute/BIOSStringAttribute/BIOSEnumAttribute,
we will use the new interface(BIOSConfig) in BIOS Handler.

It will have the following advantages

1. Different types of attribute implementations are placed in different files, improving readability
2. Logic to operate bios tables is no longer coupled with BIOS Handler.

In addition, added a c++ wrapper for string table. After
completing this refactor, will move the implementation to a common
place. It's useful for pldmtool.

Signed-off-by: John Wang <wangzqbj@inspur.com>
Change-Id: I11e304c470360ca5fde23e4969494bb03de475c0
diff --git a/libpldmresponder/bios_attribute.hpp b/libpldmresponder/bios_attribute.hpp
new file mode 100644
index 0000000..d63b331
--- /dev/null
+++ b/libpldmresponder/bios_attribute.hpp
@@ -0,0 +1,79 @@
+#pragma once
+
+#include "bios_table.hpp"
+#include "utils.hpp"
+
+#include <cstdint>
+#include <filesystem>
+#include <memory>
+#include <nlohmann/json.hpp>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include "bios_table.h"
+
+namespace pldm
+{
+namespace responder
+{
+namespace bios
+{
+
+using Json = nlohmann::json;
+using namespace pldm::utils;
+
+/** @class BIOSAttribute
+ *  @brief Provide interfaces to implement specific types of attributes
+ */
+class BIOSAttribute
+{
+  public:
+    /** @brief Construct a bios attribute
+     *  @param[in] entry - Json Object
+     *  @param[in] dbusHandler - Dbus Handler
+     */
+    BIOSAttribute(const Json& entry, DBusHandler* const dbusHandler);
+
+    /** Virtual destructor
+     */
+    virtual ~BIOSAttribute() = default;
+
+    /** @brief Set Attribute value On Dbus according to the attribute value
+     * entry
+     *  @param[in] attrValueEntry - The attribute value entry
+     *  @param[in] attrEntry - The attribute entry corresponding to the
+     *                         attribute value entry
+     *  @param[in] stringTable - The string table
+     */
+    virtual void
+        setAttrValueOnDbus(const pldm_bios_attr_val_table_entry* attrValueEntry,
+                           const pldm_bios_attr_table_entry* attrEntry,
+                           const BIOSStringTable& stringTable) = 0;
+
+    /** @brief Construct corresponding entries at the end of the attribute table
+     *         and attribute value tables
+     *  @param[in] stringTable - The string Table
+     *  @param[in,out] attrTable - The attribute table
+     *  @param[in,out] attrValueTable - The attribute value table
+     */
+    virtual void constructEntry(const BIOSStringTable& stringTable,
+                                Table& attrTable, Table& attrValueTable) = 0;
+
+    /** @brief Name of this attribute */
+    const std::string name;
+
+    /** Weather this attribute is read-only */
+    const bool readOnly;
+
+  protected:
+    /** @brief dbus backend, nullopt if this attribute is read-only*/
+    std::optional<DBusMapping> dBusMap;
+
+    /** @brief dbus handler */
+    DBusHandler* const dbusHandler;
+};
+
+} // namespace bios
+} // namespace responder
+} // namespace pldm
\ No newline at end of file