blob: c3567fb57b3363d336470a4a75baba2eeb632f86 [file] [log] [blame]
kasunatha1a69f12022-05-27 14:31:38 -07001#include "rde/rde_dictionary_manager.hpp"
2
3#include <fmt/format.h>
4
5namespace bios_bmc_smm_error_logger
6{
7namespace rde
8{
9
Patrick Williamsb8125762023-05-10 07:51:26 -050010DictionaryManager::DictionaryManager() : validDictionaryCount(0) {}
kasunatha1a69f12022-05-27 14:31:38 -070011
12void 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 {
Patrick Williamsb8125762023-05-10 07:51:26 -050019 dictionaries[resourceId] = std::make_unique<DictionaryEntry>(false,
20 data);
kasunatha1a69f12022-05-27 14:31:38 -070021 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
34bool 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
46bool 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
62std::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
82std::optional<std::span<const uint8_t>>
83 DictionaryManager::getAnnotationDictionary()
84{
85 return getDictionary(annotationResourceId);
86}
87
88uint32_t DictionaryManager::getDictionaryCount()
89{
90 return validDictionaryCount;
91}
92
93void 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
104void 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
114void 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