PEL: Create PEL from parameters

Add a constructor to the PEL class so it can be built from the message
registry entry for that error along with the event log properties.

When support for new sections are added, they will be created here as
well along with the PrivateHeader and UserHeader section classes.

Eventually, this constructor will be called from the Manager class after
it is told a new event log has been created and after it looks up that
error's PEL message registry entry.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I2d8ca550736aab45a30ac3db9861723b33e6cd32
diff --git a/extensions/openpower-pels/pel.cpp b/extensions/openpower-pels/pel.cpp
index 1eac869..6a56e15 100644
--- a/extensions/openpower-pels/pel.cpp
+++ b/extensions/openpower-pels/pel.cpp
@@ -8,6 +8,19 @@
 {
 namespace pels
 {
+namespace message = openpower::pels::message;
+
+PEL::PEL(const message::Entry& entry, uint32_t obmcLogID, uint64_t timestamp,
+         phosphor::logging::Entry::Level severity)
+{
+    _ph = std::make_unique<PrivateHeader>(entry.componentID, obmcLogID,
+                                          timestamp);
+    _uh = std::make_unique<UserHeader>(entry, severity);
+
+    // Add future sections here and update the count
+
+    _ph->sectionCount() = 2;
+}
 
 PEL::PEL(const std::vector<uint8_t>& data) : PEL(data, 0)
 {
@@ -15,6 +28,7 @@
 
 PEL::PEL(const std::vector<uint8_t>& data, uint32_t obmcLogID) : _rawPEL(data)
 {
+    _fromStream = true;
     populateFromRawData(obmcLogID);
 }
 
@@ -56,26 +70,26 @@
 void PEL::flatten(std::vector<uint8_t>& pelBuffer)
 {
     Stream pelData{pelBuffer};
-    if (_ph->valid())
-    {
-        _ph->flatten(pelData);
-    }
-    else
+
+    _ph->flatten(pelData);
+
+    // If constructed from a PEL stream originally, don't flatten the
+    // rest of the objects until we support every PEL section type.
+    // Still need the PrivateHeader, as we updated fields in it.
+    if (_fromStream)
     {
         return;
     }
 
-    if (_uh->valid())
-    {
-        _uh->flatten(pelData);
-    }
+    _uh->flatten(pelData);
 }
 
 std::vector<uint8_t> PEL::data()
 {
     // Until we can recreate a complete PEL from objects, need to just flatten
     // on top of the original PEL data which we need to keep around for this
-    // reason.
+    // reason.  If creating a PEL from scratch, _rawPEL will get filled in with
+    // what we do have.
 
     flatten(_rawPEL);
     return _rawPEL;