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