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