blob: a71114ca7b83e69cd93487b08979521728a1aaa0 [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
10DictionaryManager::DictionaryManager() : validDictionaryCount(0)
11{}
12
13void 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
35bool 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
47bool 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
63std::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
83std::optional<std::span<const uint8_t>>
84 DictionaryManager::getAnnotationDictionary()
85{
86 return getDictionary(annotationResourceId);
87}
88
89uint32_t DictionaryManager::getDictionaryCount()
90{
91 return validDictionaryCount;
92}
93
94void 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
105void 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
115void 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