blob: e1a98d36d928dd571be4df593ca4688241b268cf [file] [log] [blame]
John Wangb754eee2020-02-15 16:10:25 +08001#pragma once
2
George Liuc453e162022-12-21 17:16:23 +08003#include <libpldm/bios_table.h>
George Liu6492f522020-06-16 10:34:05 +08004
John Wangb754eee2020-02-15 16:10:25 +08005#include <cstring>
6#include <memory>
7#include <type_traits>
8#include <vector>
9
John Wangb754eee2020-02-15 16:10:25 +080010namespace pldm
11{
12namespace bios
13{
14namespace utils
15{
16
17using Table = std::vector<uint8_t>;
18
19/** @class BIOSTableIter
20 * @brief Const Iterator of a BIOS Table
21 */
22template <pldm_bios_table_types tableType>
23class BIOSTableIter
24{
25 public:
26 /** @struct EndSentinel
27 * @brief Auxiliary struct to delimit a range
28 */
29 struct EndSentinel
George Liu6492f522020-06-16 10:34:05 +080030 {};
John Wangb754eee2020-02-15 16:10:25 +080031
32 /** @struct iterator
33 * @brief iterator owns the BIOS table
34 */
35 class iterator
36 {
37 public:
38 /** @brief Get entry type by specifying \p tableType
39 */
40 using T = typename std::conditional<
41 tableType == PLDM_BIOS_STRING_TABLE, pldm_bios_string_table_entry,
42 typename std::conditional<
43 tableType == PLDM_BIOS_ATTR_TABLE, pldm_bios_attr_table_entry,
44 typename std::conditional<tableType == PLDM_BIOS_ATTR_VAL_TABLE,
45 pldm_bios_attr_val_table_entry,
46 void>::type>::type>::type;
47 static_assert(!std::is_void<T>::value);
48
49 /** @brief Constructors iterator
50 *
51 * @param[in] data - Pointer to a table
52 * @param[in] length - The length of the table
53 */
Andrew Jeffery47266d62023-06-28 11:54:30 +093054 explicit iterator(const void* data, size_t length) :
John Wangb754eee2020-02-15 16:10:25 +080055 iter(pldm_bios_table_iter_create(data, length, tableType),
56 pldm_bios_table_iter_free)
Andrew Jeffery47266d62023-06-28 11:54:30 +093057 {
58 if (!iter)
59 {
60 throw std::runtime_error(
61 "Unable to create bios table iterator");
62 }
63 }
John Wangb754eee2020-02-15 16:10:25 +080064
65 /** @brief Get the entry pointed by the iterator
66 *
67 * @return Poiner to the entry
68 */
69 const T* operator*() const
70 {
71 return reinterpret_cast<const T*>(
72 pldm_bios_table_iter_value(iter.get()));
73 }
74
75 /** @brief Make the iterator point to the next entry
76 *
77 * @return The iterator itself
78 */
79 iterator& operator++()
80 {
81 pldm_bios_table_iter_next(iter.get());
82 return *this;
83 }
84
85 /** @brief Check if the iterator ends
86 *
87 * @return True if the iterator ends
88 */
89 bool operator==(const EndSentinel&) const
90 {
91 return pldm_bios_table_iter_is_end(iter.get());
92 }
93
94 /** @brief Check if the iterator ends
95 *
96 * @return False if the iterator ends
97 */
98 bool operator!=(const EndSentinel& endSentinel) const
99 {
100 return !operator==(endSentinel);
101 }
102
103 private:
104 std::unique_ptr<pldm_bios_table_iter,
105 decltype(&pldm_bios_table_iter_free)>
106 iter;
107 };
108
109 /** @brief Constructors BIOSTableIterator
110 *
111 * @param[in] data - Pointer to a table
112 * @param[in] length - The length of the table
113 */
114 BIOSTableIter(const void* data, size_t length) noexcept :
115 tableData(data), tableSize(length)
George Liu6492f522020-06-16 10:34:05 +0800116 {}
John Wangb754eee2020-02-15 16:10:25 +0800117
118 /** @brief Get the iterator to the beginning
119 *
120 * @return An iterator to the beginning
121 */
122 iterator begin()
123 {
124 return iterator(tableData, tableSize);
125 }
126
127 /** @brief Get the iterator to the end
128 *
129 * @return An iterator to the end
130 */
131 EndSentinel end()
132 {
133 return {};
134 }
135
136 private:
137 const void* tableData;
138 size_t tableSize;
139};
140
141} // namespace utils
142} // namespace bios
143} // namespace pldm