xref: /openbmc/pldm/common/bios_utils.hpp (revision 06b443ec)
1 #pragma once
2 
3 #include <libpldm/bios_table.h>
4 
5 #include <cstring>
6 #include <memory>
7 #include <type_traits>
8 #include <vector>
9 
10 namespace pldm
11 {
12 namespace bios
13 {
14 namespace utils
15 {
16 
17 using Table = std::vector<uint8_t>;
18 
19 /** @class BIOSTableIter
20  *  @brief Const Iterator of a BIOS Table
21  */
22 template <pldm_bios_table_types tableType>
23 class BIOSTableIter
24 {
25   public:
26     /** @struct EndSentinel
27      *  @brief Auxiliary struct to delimit a range
28      */
29     struct EndSentinel
30     {};
31 
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          */
54         explicit iterator(const void* data, size_t length) :
55             iter(pldm_bios_table_iter_create(data, length, tableType),
56                  pldm_bios_table_iter_free)
57         {
58             if (!iter)
59             {
60                 throw std::runtime_error(
61                     "Unable to create bios table iterator");
62             }
63         }
64 
65         /** @brief Get the entry pointed by the iterator
66          *
67          *  @return Pointer 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)
116     {}
117 
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
144