PEL: Create object for every section

When unflattening a PEL, create objects for every PEL section in the
log.  It will use a factory method to choose which object type to create
based on the section ID in the section header.  All of these object will
go into a vector of Section objects, which is the base class for every
PEL section class.

The factory will default to creating a Generic object when it doesn't
have any other type to create.

Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: Ief0e4df5c586a46cea66ca47b4479e3444815309
diff --git a/extensions/openpower-pels/section_factory.cpp b/extensions/openpower-pels/section_factory.cpp
new file mode 100644
index 0000000..69274c0
--- /dev/null
+++ b/extensions/openpower-pels/section_factory.cpp
@@ -0,0 +1,52 @@
+#include "section_factory.hpp"
+
+#include "failing_mtms.hpp"
+#include "generic.hpp"
+#include "pel_types.hpp"
+#include "private_header.hpp"
+#include "user_header.hpp"
+
+namespace openpower
+{
+namespace pels
+{
+namespace section_factory
+{
+std::unique_ptr<Section> create(Stream& pelData)
+{
+    std::unique_ptr<Section> section;
+
+    // Peek the section ID to create the appriopriate object.
+    // If not enough data remains to do so, an invalid
+    // Generic object will be created in the default case.
+    uint16_t sectionID = 0;
+
+    if (pelData.remaining() >= 2)
+    {
+        pelData >> sectionID;
+        pelData.offset(pelData.offset() - 2);
+    }
+
+    switch (sectionID)
+    {
+        case static_cast<uint16_t>(SectionID::privateHeader):
+            section = std::make_unique<PrivateHeader>(pelData);
+            break;
+        case static_cast<uint16_t>(SectionID::userHeader):
+            section = std::make_unique<UserHeader>(pelData);
+            break;
+        case static_cast<uint16_t>(SectionID::failingMTMS):
+            section = std::make_unique<FailingMTMS>(pelData);
+            break;
+        default:
+            // A generic object, but at least an object.
+            section = std::make_unique<Generic>(pelData);
+            break;
+    }
+
+    return section;
+}
+
+} // namespace section_factory
+} // namespace pels
+} // namespace openpower