parser : parse keyword data section
For keywords contained in an OpenPOWER VPD record, read the keyword
data. The data may be raw or encoded in ascii. Return the
resultant data as a string.
Some keywords, such as B1 (MAC address) need to be decoded specially.
Change-Id: I64c16c60dc94e173586b20fb6a92809fbb0ac89e
Signed-off-by: Deepak Kodihalli <dkodihal@in.ibm.com>
diff --git a/impl.cpp b/impl.cpp
index 834cc6c..de1896f 100644
--- a/impl.cpp
+++ b/impl.cpp
@@ -1,6 +1,11 @@
+#include <sstream>
#include <exception>
#include <iostream>
#include <iterator>
+#include <iomanip>
+#include <tuple>
+#include <algorithm>
+#include "defines.hpp"
#include "impl.hpp"
namespace openpower
@@ -17,6 +22,22 @@
{"OSYS", Record::OSYS}
};
+static constexpr auto MAC_ADDRESS_LEN_BYTES = 6;
+
+static const std::unordered_map<std::string,
+ internal::KeywordInfo> supportedKeywords =
+{
+ {"DR", std::make_tuple(record::Keyword::DR, keyword::Encoding::ASCII)},
+ {"PN", std::make_tuple(record::Keyword::PN, keyword::Encoding::ASCII)},
+ {"SN", std::make_tuple(record::Keyword::SN, keyword::Encoding::ASCII)},
+ {"CC", std::make_tuple(record::Keyword::CC, keyword::Encoding::ASCII)},
+ {"HW", std::make_tuple(record::Keyword::HW, keyword::Encoding::RAW)},
+ {"B1", std::make_tuple(record::Keyword::B1, keyword::Encoding::B1)},
+ {"VN", std::make_tuple(record::Keyword::VN, keyword::Encoding::ASCII)},
+ {"MB", std::make_tuple(record::Keyword::MB, keyword::Encoding::RAW)},
+ {"MM", std::make_tuple(record::Keyword::MM, keyword::Encoding::ASCII)}
+};
+
namespace
{
@@ -29,6 +50,12 @@
using ECCOffset = uint16_t;
using ECCLength = uint16_t;
+constexpr auto toHex(size_t c)
+{
+ constexpr auto map = "0123456789abcdef";
+ return map[c];
+}
+
}
namespace offsets
@@ -175,6 +202,60 @@
}
}
+std::string Impl::readKwData(const internal::KeywordInfo& keyword,
+ std::size_t dataLength,
+ Binary::const_iterator iterator)
+{
+ switch (std::get<keyword::Encoding>(keyword))
+ {
+ case keyword::Encoding::ASCII:
+ {
+ auto stop = std::next(iterator, dataLength);
+ return std::string(iterator, stop);
+ }
+
+ case keyword::Encoding::RAW:
+ {
+ auto stop = std::next(iterator, dataLength);
+ std::string data(iterator, stop);
+ std::string result {};
+ std::for_each(data.cbegin(), data.cend(),
+ [&result](size_t c)
+ {
+ result += toHex(c >> 4);
+ result += toHex(c & 0x0F);
+ });
+ return result;
+ }
+
+ case keyword::Encoding::B1:
+ {
+ //B1 is MAC address, represent as AA:BB:CC:DD:EE:FF
+ auto stop = std::next(iterator, MAC_ADDRESS_LEN_BYTES);
+ std::string data(iterator, stop);
+ std::string result {};
+ auto strItr = data.cbegin();
+ size_t firstDigit = *strItr;
+ result += toHex(firstDigit >> 4);
+ result += toHex(firstDigit & 0x0F);
+ std::advance(strItr, 1);
+ std::for_each(strItr, data.cend(),
+ [&result](size_t c)
+ {
+ result += ":";
+ result += toHex(c >> 4);
+ result += toHex(c & 0x0F);
+ });
+ return result;
+ }
+
+ default:
+ break;
+ }
+
+ return {};
+}
+
} // namespace parser
} // namespace vpd
} // namespace openpower