Add serialization for bios-settings-manager

Tested: Restarted the biosconfig-manager application and
        BaseBIOSTable and PendingAttributes were restored.

Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
Change-Id: Iddbe69ed45a6895a324d236a14b6f21586315c62
diff --git a/src/manager.cpp b/src/manager.cpp
index c4c660d..c173ee4 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -15,6 +15,7 @@
 */
 #include "manager.hpp"
 
+#include "manager_serialize.hpp"
 #include "xyz/openbmc_project/BIOSConfig/Common/error.hpp"
 #include "xyz/openbmc_project/Common/error.hpp"
 
@@ -93,7 +94,9 @@
 Manager::BaseTable Manager::baseBIOSTable(BaseTable value)
 {
     pendingAttributes({});
-    return Base::baseBIOSTable(value, false);
+    auto baseTable = Base::baseBIOSTable(value, false);
+    serialize(*this, biosFile);
+    return baseTable;
 }
 
 Manager::PendingAttributes Manager::pendingAttributes(PendingAttributes value)
@@ -101,7 +104,9 @@
     // Clear the pending attributes
     if (value.empty())
     {
-        return Base::pendingAttributes({}, false);
+        auto pendingAttrs = Base::pendingAttributes({}, false);
+        serialize(*this, biosFile);
+        return pendingAttrs;
     }
 
     // Validate all the BIOS attributes before setting PendingAttributes
@@ -255,7 +260,10 @@
         pendingAttribute.emplace(std::make_pair(pair.first, pair.second));
     }
 
-    return Base::pendingAttributes(pendingAttribute, false);
+    auto pendingAttrs = Base::pendingAttributes(pendingAttribute, false);
+    serialize(*this, biosFile);
+
+    return pendingAttrs;
 }
 
 Manager::Manager(sdbusplus::asio::object_server& objectServer,
@@ -263,7 +271,12 @@
     sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager(*systemBus,
                                                                  objectPath),
     objServer(objectServer), systemBus(systemBus)
-{}
+{
+    fs::path biosDir(BIOS_PERSIST_PATH);
+    fs::create_directories(biosDir);
+    biosFile = biosDir / biosPersistFile;
+    deserialize(biosFile, *this);
+}
 
 } // namespace bios_config
 
diff --git a/src/manager_serialize.cpp b/src/manager_serialize.cpp
new file mode 100644
index 0000000..ef7b1b4
--- /dev/null
+++ b/src/manager_serialize.cpp
@@ -0,0 +1,92 @@
+#include "manager_serialize.hpp"

+

+#include <cereal/archives/binary.hpp>

+#include <cereal/cereal.hpp>

+#include <cereal/types/map.hpp>

+#include <cereal/types/string.hpp>

+#include <cereal/types/tuple.hpp>

+#include <cereal/types/variant.hpp>

+#include <cereal/types/vector.hpp>

+#include <phosphor-logging/log.hpp>

+

+#include <fstream>

+

+namespace bios_config

+{

+

+using namespace phosphor::logging;

+

+/** @brief Function required by Cereal to perform serialization.

+ *

+ *  @tparam Archive - Cereal archive type (binary in this case).

+ *  @param[in] archive - reference to cereal archive.

+ *  @param[in] entry- const reference to bios manager object

+ *  @param[in] version - Class version that enables handling a serialized data

+ *                       across code levels

+ */

+template <class Archive>

+void save(Archive& archive, const Manager& entry,

+          const std::uint32_t /*version*/)

+{

+    archive(entry.sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager::

+                baseBIOSTable(),

+            entry.sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager::

+                pendingAttributes());

+}

+

+/** @brief Function required by Cereal to perform deserialization.

+ *

+ *  @tparam Archive - Cereal archive type (binary in our case).

+ *  @param[in] archive - reference to cereal archive.

+ *  @param[out] entry - reference to bios manager object

+ *  @param[in] version - Class version that enables handling a serialized data

+ *                       across code levels

+ */

+template <class Archive>

+void load(Archive& archive, Manager& entry, const std::uint32_t /*version*/)

+{

+    Manager::BaseTable baseTable;

+    Manager::PendingAttributes pendingAttrs;

+

+    archive(baseTable, pendingAttrs);

+    entry.sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager::

+        baseBIOSTable(baseTable, true);

+    entry.sdbusplus::xyz::openbmc_project::BIOSConfig::server::Manager::

+        pendingAttributes(pendingAttrs, true);

+}

+

+void serialize(const Manager& obj, const fs::path& path)

+{

+    std::ofstream os(path.c_str(), std::ios::out | std::ios::binary);

+    cereal::BinaryOutputArchive oarchive(os);

+    oarchive(obj);

+}

+

+bool deserialize(const fs::path& path, Manager& entry)

+{

+    try

+    {

+        if (fs::exists(path))

+        {

+            std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);

+            cereal::BinaryInputArchive iarchive(is);

+            iarchive(entry);

+            return true;

+        }

+        return false;

+    }

+    catch (cereal::Exception& e)

+    {

+        log<level::ERR>(e.what());

+        fs::remove(path);

+        return false;

+    }

+    catch (const std::length_error& e)

+    {

+        log<level::ERR>(e.what());

+        fs::remove(path);

+        return false;

+    }

+}

+

+} // namespace bios_config
\ No newline at end of file