1 #include "rde/rde_dictionary_manager.hpp" 2 3 #include <fmt/format.h> 4 5 namespace bios_bmc_smm_error_logger 6 { 7 namespace rde 8 { 9 10 DictionaryManager::DictionaryManager() : validDictionaryCount(0) 11 {} 12 13 void DictionaryManager::startDictionaryEntry( 14 uint32_t resourceId, const std::span<const uint8_t> data) 15 { 16 // Check whether the resourceId is already available. 17 auto itemIt = dictionaries.find(resourceId); 18 if (itemIt == dictionaries.end()) 19 { 20 dictionaries[resourceId] = 21 std::make_unique<DictionaryEntry>(false, data); 22 return; 23 } 24 25 // Since we are creating a new dictionary on an existing entry, invalidate 26 // the existing entry. 27 invalidateDictionaryEntry(*itemIt->second); 28 29 // Flush the existing data. 30 itemIt->second->data.clear(); 31 itemIt->second->data.insert(itemIt->second->data.begin(), data.begin(), 32 data.end()); 33 } 34 35 bool DictionaryManager::markDataComplete(uint32_t resourceId) 36 { 37 auto itemIt = dictionaries.find(resourceId); 38 if (itemIt == dictionaries.end()) 39 { 40 fmt::print(stderr, "Resource ID {} not found.\n", resourceId); 41 return false; 42 } 43 validateDictionaryEntry(*itemIt->second); 44 return true; 45 } 46 47 bool DictionaryManager::addDictionaryData(uint32_t resourceId, 48 const std::span<const uint8_t> data) 49 { 50 auto itemIt = dictionaries.find(resourceId); 51 if (itemIt == dictionaries.end()) 52 { 53 fmt::print(stderr, "Resource ID {} not found.\n", resourceId); 54 return false; 55 } 56 // Since we are modifying an existing entry, invalidate the existing entry. 57 invalidateDictionaryEntry(*itemIt->second); 58 itemIt->second->data.insert(itemIt->second->data.end(), data.begin(), 59 data.end()); 60 return true; 61 } 62 63 std::optional<std::span<const uint8_t>> 64 DictionaryManager::getDictionary(uint32_t resourceId) 65 { 66 auto itemIt = dictionaries.find(resourceId); 67 if (itemIt == dictionaries.end()) 68 { 69 fmt::print(stderr, "Resource ID {} not found.\n", resourceId); 70 return std::nullopt; 71 } 72 73 if (!itemIt->second->valid) 74 { 75 fmt::print(stderr, 76 "Requested an incomplete dictionary. Resource ID {}\n", 77 resourceId); 78 return std::nullopt; 79 } 80 return itemIt->second->data; 81 } 82 83 std::optional<std::span<const uint8_t>> 84 DictionaryManager::getAnnotationDictionary() 85 { 86 return getDictionary(annotationResourceId); 87 } 88 89 uint32_t DictionaryManager::getDictionaryCount() 90 { 91 return validDictionaryCount; 92 } 93 94 void DictionaryManager::invalidateDictionaries() 95 { 96 // We won't flush the existing data. The data will be flushed if a new entry 97 // is added for an existing resource ID. 98 for (const auto& element : dictionaries) 99 { 100 element.second->valid = false; 101 } 102 validDictionaryCount = 0; 103 } 104 105 void DictionaryManager::invalidateDictionaryEntry(DictionaryEntry& entry) 106 { 107 // If this is a valid entry, reduce the valid dictionary count. 108 if (entry.valid) 109 { 110 --validDictionaryCount; 111 } 112 entry.valid = false; 113 } 114 115 void DictionaryManager::validateDictionaryEntry(DictionaryEntry& entry) 116 { 117 if (!entry.valid) 118 { 119 ++validDictionaryCount; 120 } 121 entry.valid = true; 122 } 123 124 } // namespace rde 125 } // namespace bios_bmc_smm_error_logger 126