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