blob: d0b06bcf3117213fbd5a6a3108d96298fa8776fa [file] [log] [blame]
Tom Joseph0c6d22c2019-06-26 09:58:41 +05301#include "file_table.hpp"
2
George Liuc453e162022-12-21 17:16:23 +08003#include <libpldm/utils.h>
George Liu6492f522020-06-16 10:34:05 +08004
Riya Dixit49cfb132023-03-02 04:26:53 -06005#include <phosphor-logging/lg2.hpp>
6
Tom Joseph0c6d22c2019-06-26 09:58:41 +05307#include <fstream>
Tom Joseph0c6d22c2019-06-26 09:58:41 +05308
Riya Dixit49cfb132023-03-02 04:26:53 -06009PHOSPHOR_LOG2_USING;
10
Tom Joseph0c6d22c2019-06-26 09:58:41 +053011namespace pldm
12{
Tom Joseph0c6d22c2019-06-26 09:58:41 +053013namespace filetable
14{
Tom Joseph0c6d22c2019-06-26 09:58:41 +053015FileTable::FileTable(const std::string& fileTableConfigPath)
16{
17 std::ifstream jsonFile(fileTableConfigPath);
18 if (!jsonFile.is_open())
19 {
Riya Dixitfc84f632024-04-06 14:00:02 -050020 error("File table config file '{PATH}' does not exist", "PATH",
21 fileTableConfigPath);
Tom Joseph0c6d22c2019-06-26 09:58:41 +053022 return;
23 }
24
25 auto data = Json::parse(jsonFile, nullptr, false);
26 if (data.is_discarded())
27 {
Riya Dixitfc84f632024-04-06 14:00:02 -050028 error("Failed to parse config file '{PATH}'", "PATH",
29 fileTableConfigPath);
Tom Joseph0c6d22c2019-06-26 09:58:41 +053030 return;
31 }
32
33 uint16_t fileNameLength = 0;
34 uint32_t fileSize = 0;
35 uint32_t traits = 0;
36 size_t tableSize = 0;
37 Handle handle = 0;
38 auto iter = fileTable.begin();
39
40 // Iterate through each JSON object in the config file
41 for (const auto& record : data)
42 {
43 constexpr auto path = "path";
44 constexpr auto fileTraits = "file_traits";
45
46 std::string filepath = record.value(path, "");
47 traits = static_cast<uint32_t>(record.value(fileTraits, 0));
48
Christian Geddes3249a902021-05-08 16:27:57 -050049 // Split the filepath string using ',' as a delimiter
50 // as the json can define multiple paths to try and use
51 // in order of priority
52 std::istringstream stringstream(filepath);
53 std::string path_substr;
54 fs::path fsPath;
55 while (std::getline(stringstream, path_substr, ','))
56 {
57 fsPath.assign(path_substr);
58 if (fs::exists(fsPath))
59 {
60 break;
61 }
62 }
63
64 // Skip file table entry if it is not a regular file
Tom Joseph0c6d22c2019-06-26 09:58:41 +053065 if (!fs::is_regular_file(fsPath))
66 {
67 continue;
68 }
69
70 fileNameLength =
71 static_cast<uint16_t>(fsPath.filename().string().size());
72 fileSize = static_cast<uint32_t>(fs::file_size(fsPath));
73 tableSize = fileTable.size();
74
75 fileTable.resize(tableSize + sizeof(handle) + sizeof(fileNameLength) +
76 fileNameLength + sizeof(fileSize) + sizeof(traits));
77 iter = fileTable.begin() + tableSize;
78
79 // Populate the file table with the contents of the JSON entry
80 std::copy_n(reinterpret_cast<uint8_t*>(&handle), sizeof(handle), iter);
81 std::advance(iter, sizeof(handle));
82
83 std::copy_n(reinterpret_cast<uint8_t*>(&fileNameLength),
84 sizeof(fileNameLength), iter);
85 std::advance(iter, sizeof(fileNameLength));
86
87 std::copy_n(reinterpret_cast<const uint8_t*>(fsPath.filename().c_str()),
88 fileNameLength, iter);
89 std::advance(iter, fileNameLength);
90
91 std::copy_n(reinterpret_cast<uint8_t*>(&fileSize), sizeof(fileSize),
92 iter);
93 std::advance(iter, sizeof(fileSize));
94
95 std::copy_n(reinterpret_cast<uint8_t*>(&traits), sizeof(traits), iter);
96 std::advance(iter, sizeof(traits));
97
98 // Create the file entry for the JSON entry
99 FileEntry entry{};
100 entry.handle = handle;
101 entry.fsPath = std::move(fsPath);
102 entry.traits.value = traits;
103
104 // Insert the file entries in the map
105 tableEntries.emplace(handle, std::move(entry));
106 handle++;
107 }
108
109 constexpr uint8_t padWidth = 4;
110 tableSize = fileTable.size();
111 // Add pad bytes
112 if ((tableSize % padWidth) != 0)
113 {
114 padCount = padWidth - (tableSize % padWidth);
115 fileTable.resize(tableSize + padCount, 0);
116 }
117
118 // Calculate the checksum
George Liu077fea22020-04-08 16:47:14 +0800119 checkSum = crc32(fileTable.data(), fileTable.size());
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530120}
121
122Table FileTable::operator()() const
123{
124 Table table(fileTable);
125 table.resize(fileTable.size() + sizeof(checkSum));
126 auto iter = table.begin() + fileTable.size();
127 std::copy_n(reinterpret_cast<const uint8_t*>(&checkSum), sizeof(checkSum),
128 iter);
129 return table;
130}
131
132FileTable& buildFileTable(const std::string& fileTablePath)
133{
134 static FileTable table;
135 if (table.isEmpty())
136 {
137 table = std::move(FileTable(fileTablePath));
138 }
139 return table;
140}
141
142} // namespace filetable
143} // namespace pldm