blob: 45a49fe7349e618581f6e7048097f8c9c512aaab [file] [log] [blame]
Tom Joseph0c6d22c2019-06-26 09:58:41 +05301#include "file_table.hpp"
2
Tom Joseph0c6d22c2019-06-26 09:58:41 +05303#include <fstream>
Sampa Misraaa8ae722019-12-12 03:20:40 -06004#include <iostream>
Tom Joseph0c6d22c2019-06-26 09:58:41 +05305
George Liu077fea22020-04-08 16:47:14 +08006#include "libpldm/utils.h"
7
Tom Joseph0c6d22c2019-06-26 09:58:41 +05308namespace pldm
9{
10
11namespace filetable
12{
13
Tom Joseph0c6d22c2019-06-26 09:58:41 +053014FileTable::FileTable(const std::string& fileTableConfigPath)
15{
16 std::ifstream jsonFile(fileTableConfigPath);
17 if (!jsonFile.is_open())
18 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060019 std::cerr << "File table config file does not exist, FILE="
20 << fileTableConfigPath.c_str() << "\n";
Tom Joseph0c6d22c2019-06-26 09:58:41 +053021 return;
22 }
23
24 auto data = Json::parse(jsonFile, nullptr, false);
25 if (data.is_discarded())
26 {
Sampa Misraaa8ae722019-12-12 03:20:40 -060027 std::cerr << "Parsing config file failed"
28 << "\n";
Tom Joseph0c6d22c2019-06-26 09:58:41 +053029 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
George Liu077fea22020-04-08 16:47:14 +0800103 checkSum = crc32(fileTable.data(), fileTable.size());
Tom Joseph0c6d22c2019-06-26 09:58:41 +0530104}
105
106Table FileTable::operator()() const
107{
108 Table table(fileTable);
109 table.resize(fileTable.size() + sizeof(checkSum));
110 auto iter = table.begin() + fileTable.size();
111 std::copy_n(reinterpret_cast<const uint8_t*>(&checkSum), sizeof(checkSum),
112 iter);
113 return table;
114}
115
116FileTable& buildFileTable(const std::string& fileTablePath)
117{
118 static FileTable table;
119 if (table.isEmpty())
120 {
121 table = std::move(FileTable(fileTablePath));
122 }
123 return table;
124}
125
126} // namespace filetable
127} // namespace pldm