1 #include "config.h"
2 
3 #include "snmp_serialize.hpp"
4 
5 #include "snmp_client.hpp"
6 
7 #include <cereal/archives/binary.hpp>
8 #include <cereal/types/string.hpp>
9 #include <cereal/types/vector.hpp>
10 #include <phosphor-logging/lg2.hpp>
11 
12 #include <fstream>
13 
14 // Register class version
15 // From cereal documentation;
16 // "This macro should be placed at global scope"
17 CEREAL_CLASS_VERSION(phosphor::network::snmp::Client, CLASS_VERSION);
18 
19 namespace phosphor
20 {
21 namespace network
22 {
23 namespace snmp
24 {
25 
26 /** @brief Function required by Cereal to perform serialization.
27  *  @tparam Archive - Cereal archive type (binary in our case).
28  *  @param[in] archive - reference to Cereal archive.
29  *  @param[in] manager - const reference to snmp manager info.
30  *  @param[in] version - Class version that enables handling
31  *                       a serialized data across code levels
32  */
33 template <class Archive>
34 void save(Archive& archive, const Client& manager,
35           const std::uint32_t /*version*/)
36 {
37     archive(manager.address(), manager.port());
38 }
39 
40 /** @brief Function required by Cereal to perform deserialization.
41  *  @tparam Archive - Cereal archive type (binary in our case).
42  *  @param[in] archive - reference to Cereal archive.
43  *  @param[in] manager - reference to snmp manager info.
44  *  @param[in] version - Class version that enables handling
45  *                       a serialized data across code levels
46  */
47 template <class Archive>
48 void load(Archive& archive, Client& manager, const std::uint32_t /*version*/)
49 {
50     std::string ipaddress{};
51     uint16_t port{};
52 
53     archive(ipaddress, port);
54 
55     manager.address(ipaddress);
56     manager.port(port);
57 }
58 
59 fs::path serialize(Id id, const Client& manager, const fs::path& dir)
60 {
61     fs::path fileName = dir;
62     fs::create_directories(dir);
63     fileName /= std::to_string(id);
64 
65     std::ofstream os(fileName.string(), std::ios::binary);
66     cereal::BinaryOutputArchive oarchive(os);
67     oarchive(manager);
68     return fileName;
69 }
70 
71 bool deserialize(const fs::path& path, Client& manager)
72 {
73     try
74     {
75         if (fs::exists(path))
76         {
77             std::ifstream is(path.c_str(), std::ios::in | std::ios::binary);
78             cereal::BinaryInputArchive iarchive(is);
79             iarchive(manager);
80             return true;
81         }
82         return false;
83     }
84     catch (const cereal::Exception& e)
85     {
86         lg2::error("Deserialization failed: {ERROR}", "ERROR", e);
87         std::error_code ec;
88         fs::remove(path, ec);
89         return false;
90     }
91     catch (const fs::filesystem_error& e)
92     {
93         return false;
94     }
95 }
96 
97 } // namespace snmp
98 } // namespace network
99 } // namespace phosphor
100