xref: /openbmc/pldm/common/bios_utils.hpp (revision 579a34a3)
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) noexcept :
55             iter(pldm_bios_table_iter_create(data, length, tableType),
56                  pldm_bios_table_iter_free)
57         {}
58 
59         /** @brief Get the entry pointed by the iterator
60          *
61          *  @return Poiner to the entry
62          */
63         const T* operator*() const
64         {
65             return reinterpret_cast<const T*>(
66                 pldm_bios_table_iter_value(iter.get()));
67         }
68 
69         /** @brief Make the iterator point to the next entry
70          *
71          *  @return The iterator itself
72          */
73         iterator& operator++()
74         {
75             pldm_bios_table_iter_next(iter.get());
76             return *this;
77         }
78 
79         /** @brief Check if the iterator ends
80          *
81          *  @return True if the iterator ends
82          */
83         bool operator==(const EndSentinel&) const
84         {
85             return pldm_bios_table_iter_is_end(iter.get());
86         }
87 
88         /** @brief Check if the iterator ends
89          *
90          *  @return False if the iterator ends
91          */
92         bool operator!=(const EndSentinel& endSentinel) const
93         {
94             return !operator==(endSentinel);
95         }
96 
97       private:
98         std::unique_ptr<pldm_bios_table_iter,
99                         decltype(&pldm_bios_table_iter_free)>
100             iter;
101     };
102 
103     /** @brief Constructors BIOSTableIterator
104      *
105      *  @param[in] data - Pointer to a table
106      *  @param[in] length - The length of the table
107      */
108     BIOSTableIter(const void* data, size_t length) noexcept :
109         tableData(data), tableSize(length)
110     {}
111 
112     /** @brief Get the iterator to the beginning
113      *
114      *  @return An iterator to the beginning
115      */
116     iterator begin()
117     {
118         return iterator(tableData, tableSize);
119     }
120 
121     /** @brief Get the iterator to the end
122      *
123      *  @return An iterator to the end
124      */
125     EndSentinel end()
126     {
127         return {};
128     }
129 
130   private:
131     const void* tableData;
132     size_t tableSize;
133 };
134 
135 } // namespace utils
136 } // namespace bios
137 } // namespace pldm
138