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