1 #pragma once 2 3 #include "config.h" 4 5 #include <cereal/archives/json.hpp> 6 #include <phosphor-logging/lg2.hpp> 7 8 #include <filesystem> 9 #include <fstream> 10 11 namespace phosphor 12 { 13 namespace inventory 14 { 15 namespace manager 16 { 17 18 namespace fs = std::filesystem; 19 20 namespace detail 21 { 22 inline fs::path getStoragePath(const std::string& path, 23 const std::string& iface) 24 { 25 auto p = fs::path(PIM_PERSIST_PATH); 26 p /= fs::path(path).relative_path(); 27 p /= fs::path(iface).relative_path(); 28 return p; 29 } 30 } // namespace detail 31 32 struct SerialOps 33 { 34 /** @brief Serialize inventory item path 35 * Serializing only path for an empty interface to be consistent 36 * interfaces. 37 * @param[in] path - DBus object path 38 * @param[in] iface - Inventory interface name 39 */ 40 static void serialize(const std::string& path, const std::string& iface) 41 { 42 auto p = detail::getStoragePath(path, iface); 43 fs::create_directories(p.parent_path()); 44 std::ofstream os(p, std::ios::binary); 45 } 46 47 /** @brief Serialize inventory item 48 * 49 * @param[in] path - DBus object path 50 * @param[in] iface - Inventory interface name 51 * @param[in] object - Object to be serialized 52 */ 53 template <typename T> 54 static void serialize(const std::string& path, const std::string& iface, 55 const T& object) 56 { 57 auto p = detail::getStoragePath(path, iface); 58 fs::create_directories(p.parent_path()); 59 std::ofstream os(p, std::ios::binary); 60 cereal::JSONOutputArchive oarchive(os); 61 oarchive(object); 62 } 63 64 static void deserialize(const std::string&, const std::string&) 65 { 66 // This is intentionally a noop. 67 } 68 69 /** @brief Deserialize inventory item 70 * 71 * @param[in] path - DBus object path 72 * @param[in] iface - Inventory interface name 73 * @param[in] object - Object to be serialized 74 */ 75 template <typename T> 76 static void deserialize(const std::string& path, const std::string& iface, 77 T& object) 78 { 79 auto p = detail::getStoragePath(path, iface); 80 try 81 { 82 if (fs::exists(p)) 83 { 84 std::ifstream is(p, std::ios::in | std::ios::binary); 85 cereal::JSONInputArchive iarchive(is); 86 iarchive(object); 87 } 88 } 89 catch (const cereal::Exception& e) 90 { 91 lg2::error("Deserialization failed: {ERROR}", "ERROR", e); 92 fs::remove(p); 93 } 94 } 95 }; 96 } // namespace manager 97 } // namespace inventory 98 } // namespace phosphor 99