Add PCIe/memory CPER-JSON parsing.
diff --git a/sections/cper-section-memory.c b/sections/cper-section-memory.c
index 296425c..089a7bb 100644
--- a/sections/cper-section-memory.c
+++ b/sections/cper-section-memory.c
@@ -134,4 +134,117 @@
     json_object_object_add(section_ir, "moduleSmbiosHandle", json_object_new_uint64(memory_error->ModuleHandle));
     
     return section_ir;
+}
+
+//Converts a single Memory Error IR section into CPER binary, outputting to the provided stream.
+void ir_section_memory_to_cper(json_object* section, FILE* out)
+{
+    EFI_PLATFORM_MEMORY_ERROR_DATA* section_cper = 
+        (EFI_PLATFORM_MEMORY_ERROR_DATA*)calloc(1, sizeof(EFI_PLATFORM_MEMORY_ERROR_DATA));
+
+    //Validation bits.
+    section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"), 
+        22, MEMORY_ERROR_VALID_BITFIELD_NAMES);
+
+    //Error status.
+    ir_generic_error_status_to_cper(json_object_object_get(section, "errorStatus"), &section_cper->ErrorStatus);
+
+    //Bank.
+    json_object* bank = json_object_object_get(section, "bank");
+    if ((section_cper->ValidFields >> 5) & 0x1)
+    {
+        //Bank just uses simple address.
+        section_cper->Bank = (UINT16)json_object_get_uint64(json_object_object_get(bank, "value"));
+    }
+    else
+    {
+        //Bank uses address/group style address.
+        UINT16 address = (UINT8)json_object_get_uint64(json_object_object_get(bank, "address"));
+        UINT16 group = (UINT8)json_object_get_uint64(json_object_object_get(bank, "group"));
+        section_cper->Bank = address + (group << 8);
+    }
+
+    //"Extended" field.
+    json_object* extended = json_object_object_get(section, "extended");
+    section_cper->Extended = 0;
+    section_cper->Extended |= json_object_get_boolean(json_object_object_get(extended, "rowBit16"));
+    section_cper->Extended |= json_object_get_boolean(json_object_object_get(extended, "rowBit17")) << 1;
+    section_cper->Extended |= json_object_get_int(json_object_object_get(extended, "chipIdentification")) << 5;
+
+    //Miscellaneous value fields.
+    section_cper->ErrorType = readable_pair_to_integer(json_object_object_get(section, "memoryErrorType"));
+    section_cper->PhysicalAddress = json_object_get_uint64(json_object_object_get(section, "physicalAddress"));
+    section_cper->PhysicalAddressMask = json_object_get_uint64(json_object_object_get(section, "physicalAddressMask"));
+    section_cper->Node = (UINT16)json_object_get_uint64(json_object_object_get(section, "node"));
+    section_cper->Card = (UINT16)json_object_get_uint64(json_object_object_get(section, "card"));
+    section_cper->ModuleRank = (UINT16)json_object_get_uint64(json_object_object_get(section, "moduleRank"));
+    section_cper->Device = (UINT16)json_object_get_uint64(json_object_object_get(section, "device"));
+    section_cper->Row = (UINT16)json_object_get_uint64(json_object_object_get(section, "row"));
+    section_cper->Column = (UINT16)json_object_get_uint64(json_object_object_get(section, "column"));
+    section_cper->BitPosition = (UINT16)json_object_get_uint64(json_object_object_get(section, "bitPosition"));
+    section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID"));
+    section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID"));
+    section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID"));
+    section_cper->RankNum = (UINT16)json_object_get_uint64(json_object_object_get(section, "rankNumber"));
+    section_cper->CardHandle = (UINT16)json_object_get_uint64(json_object_object_get(section, "cardSmbiosHandle"));
+    section_cper->ModuleHandle = (UINT16)json_object_get_uint64(json_object_object_get(section, "moduleSmbiosHandle"));
+
+    //Write to stream, free up resources.
+    fwrite(&section_cper, sizeof(section_cper), 1, out);
+    fflush(out);
+    free(section_cper);
+}
+
+//Converts a single Memory Error 2 IR section into CPER binary, outputting to the provided stream.
+void ir_section_memory2_to_cper(json_object* section, FILE* out)
+{
+    EFI_PLATFORM_MEMORY2_ERROR_DATA* section_cper = 
+        (EFI_PLATFORM_MEMORY2_ERROR_DATA*)calloc(1, sizeof(EFI_PLATFORM_MEMORY2_ERROR_DATA));
+
+    //Validation bits.
+    section_cper->ValidFields = ir_to_bitfield(json_object_object_get(section, "validationBits"), 
+        22, MEMORY_ERROR_2_VALID_BITFIELD_NAMES);
+
+    //Error status.
+    ir_generic_error_status_to_cper(json_object_object_get(section, "errorStatus"), &section_cper->ErrorStatus);
+
+    //Bank.
+    json_object* bank = json_object_object_get(section, "bank");
+    if ((section_cper->ValidFields >> 5) & 0x1)
+    {
+        //Bank just uses simple address.
+        section_cper->Bank = (UINT16)json_object_get_uint64(json_object_object_get(bank, "value"));
+    }
+    else
+    {
+        //Bank uses address/group style address.
+        UINT16 address = (UINT8)json_object_get_uint64(json_object_object_get(bank, "address"));
+        UINT16 group = (UINT8)json_object_get_uint64(json_object_object_get(bank, "group"));
+        section_cper->Bank = address + (group << 8);
+    }
+
+    //Miscellaneous value fields.
+    section_cper->MemErrorType = readable_pair_to_integer(json_object_object_get(section, "memoryErrorType"));
+    section_cper->Status = (UINT8)readable_pair_to_integer(json_object_object_get(section, "status"));
+    section_cper->PhysicalAddress = json_object_get_uint64(json_object_object_get(section, "physicalAddress"));
+    section_cper->PhysicalAddressMask = json_object_get_uint64(json_object_object_get(section, "physicalAddressMask"));
+    section_cper->Node = (UINT16)json_object_get_uint64(json_object_object_get(section, "node"));
+    section_cper->Card = (UINT16)json_object_get_uint64(json_object_object_get(section, "card"));
+    section_cper->Module = (UINT32)json_object_get_uint64(json_object_object_get(section, "module"));
+    section_cper->Device = (UINT32)json_object_get_uint64(json_object_object_get(section, "device"));
+    section_cper->Row = (UINT32)json_object_get_uint64(json_object_object_get(section, "row"));
+    section_cper->Column = (UINT32)json_object_get_uint64(json_object_object_get(section, "column"));
+    section_cper->Rank = (UINT32)json_object_get_uint64(json_object_object_get(section, "rank"));
+    section_cper->BitPosition = (UINT32)json_object_get_uint64(json_object_object_get(section, "bitPosition"));
+    section_cper->ChipId = (UINT8)json_object_get_uint64(json_object_object_get(section, "chipID"));
+    section_cper->RequestorId = json_object_get_uint64(json_object_object_get(section, "requestorID"));
+    section_cper->ResponderId = json_object_get_uint64(json_object_object_get(section, "responderID"));
+    section_cper->TargetId = json_object_get_uint64(json_object_object_get(section, "targetID"));
+    section_cper->CardHandle = (UINT32)json_object_get_uint64(json_object_object_get(section, "cardSmbiosHandle"));
+    section_cper->ModuleHandle = (UINT32)json_object_get_uint64(json_object_object_get(section, "moduleSmbiosHandle"));
+
+    //Write to stream, free up resources.
+    fwrite(&section_cper, sizeof(section_cper), 1, out);
+    fflush(out);
+    free(section_cper);
 }
\ No newline at end of file