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