1 #include "file_table.hpp" 2 3 #include "libpldm/utils.h" 4 5 #include <fstream> 6 #include <iostream> 7 8 namespace pldm 9 { 10 11 namespace filetable 12 { 13 14 FileTable::FileTable(const std::string& fileTableConfigPath) 15 { 16 std::ifstream jsonFile(fileTableConfigPath); 17 if (!jsonFile.is_open()) 18 { 19 std::cerr << "File table config file does not exist, FILE=" 20 << fileTableConfigPath.c_str() << "\n"; 21 return; 22 } 23 24 auto data = Json::parse(jsonFile, nullptr, false); 25 if (data.is_discarded()) 26 { 27 std::cerr << "Parsing config file failed" 28 << "\n"; 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 checkSum = crc32(fileTable.data(), fileTable.size()); 104 } 105 106 Table 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 116 FileTable& 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 128