blob: 9264f211cf9ceb4ba123e8e914d5c0746ac411e0 [file] [log] [blame]
Tom Joseph0c6d22c2019-06-26 09:58:41 +05301#include "file_table.hpp"
2
3#include <boost/crc.hpp>
4#include <fstream>
5#include <phosphor-logging/log.hpp>
6
7namespace pldm
8{
9
10namespace filetable
11{
12
13using namespace phosphor::logging;
14
15FileTable::FileTable(const std::string& fileTableConfigPath)
16{
17 std::ifstream jsonFile(fileTableConfigPath);
18 if (!jsonFile.is_open())
19 {
20 log<level::ERR>("File table config file does not exist",
21 entry("FILE=%s", fileTableConfigPath.c_str()));
22 return;
23 }
24
25 auto data = Json::parse(jsonFile, nullptr, false);
26 if (data.is_discarded())
27 {
28 log<level::ERR>("Parsing config file failed");
29 return;
30 }
31
32 uint16_t fileNameLength = 0;
33 uint32_t fileSize = 0;
34 uint32_t traits = 0;
35 size_t tableSize = 0;
36 Handle handle = 0;
37 auto iter = fileTable.begin();
38
39 // Iterate through each JSON object in the config file
40 for (const auto& record : data)
41 {
42 constexpr auto path = "path";
43 constexpr auto fileTraits = "file_traits";
44
45 std::string filepath = record.value(path, "");
46 traits = static_cast<uint32_t>(record.value(fileTraits, 0));
47
48 fs::path fsPath(filepath);
49 if (!fs::is_regular_file(fsPath))
50 {
51 continue;
52 }
53
54 fileNameLength =
55 static_cast<uint16_t>(fsPath.filename().string().size());
56 fileSize = static_cast<uint32_t>(fs::file_size(fsPath));
57 tableSize = fileTable.size();
58
59 fileTable.resize(tableSize + sizeof(handle) + sizeof(fileNameLength) +
60 fileNameLength + sizeof(fileSize) + sizeof(traits));
61 iter = fileTable.begin() + tableSize;
62
63 // Populate the file table with the contents of the JSON entry
64 std::copy_n(reinterpret_cast<uint8_t*>(&handle), sizeof(handle), iter);
65 std::advance(iter, sizeof(handle));
66
67 std::copy_n(reinterpret_cast<uint8_t*>(&fileNameLength),
68 sizeof(fileNameLength), iter);
69 std::advance(iter, sizeof(fileNameLength));
70
71 std::copy_n(reinterpret_cast<const uint8_t*>(fsPath.filename().c_str()),
72 fileNameLength, iter);
73 std::advance(iter, fileNameLength);
74
75 std::copy_n(reinterpret_cast<uint8_t*>(&fileSize), sizeof(fileSize),
76 iter);
77 std::advance(iter, sizeof(fileSize));
78
79 std::copy_n(reinterpret_cast<uint8_t*>(&traits), sizeof(traits), iter);
80 std::advance(iter, sizeof(traits));
81
82 // Create the file entry for the JSON entry
83 FileEntry entry{};
84 entry.handle = handle;
85 entry.fsPath = std::move(fsPath);
86 entry.traits.value = traits;
87
88 // Insert the file entries in the map
89 tableEntries.emplace(handle, std::move(entry));
90 handle++;
91 }
92
93 constexpr uint8_t padWidth = 4;
94 tableSize = fileTable.size();
95 // Add pad bytes
96 if ((tableSize % padWidth) != 0)
97 {
98 padCount = padWidth - (tableSize % padWidth);
99 fileTable.resize(tableSize + padCount, 0);
100 }
101
102 // Calculate the checksum
103 boost::crc_32_type result;
104 result.process_bytes(fileTable.data(), fileTable.size());
105 checkSum = result.checksum();
106}
107
108Table FileTable::operator()() const
109{
110 Table table(fileTable);
111 table.resize(fileTable.size() + sizeof(checkSum));
112 auto iter = table.begin() + fileTable.size();
113 std::copy_n(reinterpret_cast<const uint8_t*>(&checkSum), sizeof(checkSum),
114 iter);
115 return table;
116}
117
118FileTable& buildFileTable(const std::string& fileTablePath)
119{
120 static FileTable table;
121 if (table.isEmpty())
122 {
123 table = std::move(FileTable(fileTablePath));
124 }
125 return table;
126}
127
128} // namespace filetable
129} // namespace pldm