blob: d8af32d1a106faef733e1daea8fe58f867838b2f [file] [log] [blame]
#pragma once
#include <cstddef>
#include "store.hpp"
namespace openpower
{
namespace vpd
{
namespace parser
{
namespace keyword
{
/** @brief Encoding scheme of a VPD keyword's data */
enum class Encoding
{
ASCII, /**< data encoded in ascii */
RAW, /**< raw data */
// Keywords needing custom decoding
B1 /**< The keyword B1 needs to be decoded specially */
};
} // namespace keyword
namespace internal
{
using KeywordInfo = std::tuple<record::Keyword, keyword::Encoding>;
using OffsetList = std::vector<uint32_t>;
using KeywordMap = Parsed::mapped_type;
}
/** @class Impl
* @brief Implements parser for OpenPOWER VPD
*
* An Impl object must be constructed by passing in OpenPOWER VPD in
* binary format. To parse the VPD, call the run() method. The run()
* method returns an openpower::vpd::Store object, which contains
* parsed VPD, and provides access methods for the VPD.
*
* Following is the algorithm used to parse OpenPOWER VPD:
* 1) Validate that the first record is VHDR, the header record.
* 2) From the VHDR record, get the offset of the VTOC record,
* which is the table of contents record.
* 3) Process the VTOC record - note offsets of supported records.
* 4) For each supported record :
* 4.1) Jump to record via offset. Add record name to parser output.
* 4.2) Process record - for each contained and supported keyword:
* 4.2.1) Note keyword name and value, associate this information to
* to the record noted in step 4.1).
*/
class Impl
{
public:
Impl() = delete;
Impl(const Impl&) = delete;
Impl& operator=(const Impl&) = delete;
Impl(Impl&&) = delete;
Impl& operator=(Impl&&) = delete;
~Impl() = default;
/** @brief Construct an Impl
*
* @param[in] vpdBuffer - Binary OpenPOWER VPD
*/
explicit Impl(Binary&& vpdBuffer)
: vpd(std::move(vpdBuffer)),
out{}
{}
/** @brief Run the parser on binary OpenPOWER VPD
*
* @returns openpower::vpd::Store object
*/
Store run();
private:
/** @brief Process the table of contents record, VHDR
*
* @returns List of offsets to records in VPD
*/
internal::OffsetList readTOC() const;
/** @brief Read the PT keyword contained in the VHDR record,
* to obtain offsets to other records in the VPD.
*
* @param[in] iterator - iterator to buffer containing VPD
* @param[in] ptLength - Length of PT keyword data
*
* @returns List of offsets to records in VPD
*/
internal::OffsetList readPT(Binary::const_iterator iterator,
std::size_t ptLen) const;
/** @brief Read VPD information contained within a record
*
* @param[in] recordOffset - offset to a record location
* within the binary OpenPOWER VPD
*/
void processRecord(std::size_t recordOffset);
/** @brief Read keyword data
*
* @param[in] keyword - OpenPOWER VPD keyword
* @param[in] dataLength - Length of data to be read
* @param[in] iterator - iterator pointing to a Keyword's data in
* the VPD
*
* @returns keyword data as a string
*/
std::string readKwData(const internal::KeywordInfo& keyword,
std::size_t dataLength,
Binary::const_iterator iterator);
/** @brief While we're pointing at the keyword section of
* a record in the VPD, this will read all contained
* keywords and their values.
*
* @param[in] iterator - iterator pointing to a Keyword in the VPD
*
* @returns map of keyword:data
*/
internal::KeywordMap readKeywords(Binary::const_iterator iterator);
/** @brief Checks if the VHDR record is present in the VPD */
void checkHeader() const;
/** @brief OpenPOWER VPD in binary format */
Binary vpd;
/** @brief parser output */
Parsed out;
};
} // namespace parser
} // namespace vpd
} // namespace openpower