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 {
getStoragePath(const std::string & path,const std::string & iface)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 */
serializephosphor::inventory::manager::SerialOps40 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>
serializephosphor::inventory::manager::SerialOps54 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
deserializephosphor::inventory::manager::SerialOps64 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>
deserializephosphor::inventory::manager::SerialOps76 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