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