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
DictionaryManager()12 DictionaryManager::DictionaryManager() : validDictionaryCount(0) {}
13
startDictionaryEntry(uint32_t resourceId,const std::span<const uint8_t> data)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
markDataComplete(uint32_t resourceId)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
addDictionaryData(uint32_t resourceId,const std::span<const uint8_t> data)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>>
getDictionary(uint32_t resourceId)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>>
getAnnotationDictionary()85 DictionaryManager::getAnnotationDictionary()
86 {
87 return getDictionary(annotationResourceId);
88 }
89
getDictionaryCount()90 uint32_t DictionaryManager::getDictionaryCount()
91 {
92 return validDictionaryCount;
93 }
94
invalidateDictionaries()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
invalidateDictionaryEntry(DictionaryEntry & entry)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
validateDictionaryEntry(DictionaryEntry & entry)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