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