PEL: Add UserHeader class

The second section in a PEL is always the 'User Header' section.  This
commit adds a class to represent that.  Right now, the only constructor
available is filling in its data fields from a PEL stream.

Several of the fields in this section have predefined values that are
defined by the PEL specification.  Defining any constants or enums for
those will be left to future commits where they will actually be used.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I8b5f856a4284d44c31b04e98a664f20cd8fa0cb6
diff --git a/extensions/openpower-pels/user_header.cpp b/extensions/openpower-pels/user_header.cpp
new file mode 100644
index 0000000..16d6212
--- /dev/null
+++ b/extensions/openpower-pels/user_header.cpp
@@ -0,0 +1,67 @@
+#include "user_header.hpp"
+
+#include <phosphor-logging/log.hpp>
+
+namespace openpower
+{
+namespace pels
+{
+
+using namespace phosphor::logging;
+
+Stream& operator>>(Stream& s, UserHeader& uh)
+{
+    s >> uh._header >> uh._eventSubsystem >> uh._eventScope >>
+        uh._eventSeverity >> uh._eventType >> uh._reserved4Byte1 >>
+        uh._problemDomain >> uh._problemVector >> uh._actionFlags >>
+        uh._reserved4Byte2;
+    return s;
+}
+
+Stream& operator<<(Stream& s, UserHeader& uh)
+{
+    s << uh._header << uh._eventSubsystem << uh._eventScope << uh._eventSeverity
+      << uh._eventType << uh._reserved4Byte1 << uh._problemDomain
+      << uh._problemVector << uh._actionFlags << uh._reserved4Byte2;
+    return s;
+}
+
+UserHeader::UserHeader(Stream& pel)
+{
+    try
+    {
+        pel >> *this;
+        validate();
+    }
+    catch (const std::exception& e)
+    {
+        log<level::ERR>("Cannot unflatten user header",
+                        entry("ERROR=%s", e.what()));
+        _valid = false;
+    }
+}
+
+void UserHeader::validate()
+{
+    bool failed = false;
+    if (header().id != userHeaderSectionID)
+    {
+        log<level::ERR>("Invalid user header section ID",
+                        entry("ID=0x%X", header().id));
+        failed = true;
+        return;
+    }
+
+    if (header().version != userHeaderVersion)
+    {
+        log<level::ERR>("Invalid user header version",
+                        entry("VERSION=0x%X", header().version));
+        failed = true;
+        return;
+    }
+
+    _valid = (failed) ? false : true;
+}
+
+} // namespace pels
+} // namespace openpower