| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 1 | #include "file_table.hpp" | 
 | 2 |  | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 3 | #include <fstream> | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 4 | #include <iostream> | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 5 |  | 
| George Liu | 077fea2 | 2020-04-08 16:47:14 +0800 | [diff] [blame] | 6 | #include "libpldm/utils.h" | 
 | 7 |  | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 8 | namespace pldm | 
 | 9 | { | 
 | 10 |  | 
 | 11 | namespace filetable | 
 | 12 | { | 
 | 13 |  | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 14 | FileTable::FileTable(const std::string& fileTableConfigPath) | 
 | 15 | { | 
 | 16 |     std::ifstream jsonFile(fileTableConfigPath); | 
 | 17 |     if (!jsonFile.is_open()) | 
 | 18 |     { | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 19 |         std::cerr << "File table config file does not exist, FILE=" | 
 | 20 |                   << fileTableConfigPath.c_str() << "\n"; | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 21 |         return; | 
 | 22 |     } | 
 | 23 |  | 
 | 24 |     auto data = Json::parse(jsonFile, nullptr, false); | 
 | 25 |     if (data.is_discarded()) | 
 | 26 |     { | 
| Sampa Misra | aa8ae72 | 2019-12-12 03:20:40 -0600 | [diff] [blame] | 27 |         std::cerr << "Parsing config file failed" | 
 | 28 |                   << "\n"; | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 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 | 
| George Liu | 077fea2 | 2020-04-08 16:47:14 +0800 | [diff] [blame] | 103 |     checkSum = crc32(fileTable.data(), fileTable.size()); | 
| Tom Joseph | 0c6d22c | 2019-06-26 09:58:41 +0530 | [diff] [blame] | 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 |