Add IR header conversion.
diff --git a/ir-parse.c b/ir-parse.c
index fa2a326..8eb75db 100644
--- a/ir-parse.c
+++ b/ir-parse.c
@@ -6,10 +6,89 @@
#include <stdio.h>
#include "json.h"
+#include "edk/Cper.h"
#include "cper-parse.h"
+#include "cper-utils.h"
+
+//Private pre-declarations.
+void ir_header_to_cper(json_object* header_ir, EFI_COMMON_ERROR_RECORD_HEADER* header);
//Converts the given JSON IR CPER representation into CPER binary format, piped to the provided file stream.
+//This function performs no validation of the IR against the CPER-JSON specification. For this, call
+//validate_schema() from json-schema.h before attempting to call this function.
void ir_to_cper(json_object* ir, FILE* out)
{
+ //Create the CPER header.
+ EFI_COMMON_ERROR_RECORD_HEADER* header = (EFI_COMMON_ERROR_RECORD_HEADER*)calloc(1, sizeof(EFI_COMMON_ERROR_RECORD_HEADER));
+ ir_header_to_cper(json_object_object_get(ir, "header"), header);
+ fwrite(header, sizeof(EFI_COMMON_ERROR_RECORD_HEADER), 1, out);
+
//...
+
+ //Free all resources.
+ fflush(out);
+ free(header);
+}
+
+//Converts a CPER-JSON IR header to a CPER header structure.
+void ir_header_to_cper(json_object* header_ir, EFI_COMMON_ERROR_RECORD_HEADER* header)
+{
+ header->SignatureStart = 0x52455043; //CPER
+ printf("beginning write.\n");
+
+ //Revision.
+ json_object* revision = json_object_object_get(header_ir, "revision");
+ int minor = json_object_get_int(json_object_object_get(revision, "minor"));
+ int major = json_object_get_int(json_object_object_get(revision, "major"));
+ header->Revision = minor + (major << 8);
+
+ header->SignatureEnd = 0xFFFFFFFF;
+
+ //Section count.
+ int section_count = json_object_get_int(json_object_object_get(header_ir, "sectionCount"));
+ header->SectionCount = (UINT16)section_count;
+
+ //Error severity.
+ json_object* severity = json_object_object_get(header_ir, "severity");
+ header->ErrorSeverity = (UINT32)json_object_get_uint64(json_object_object_get(severity, "code"));
+
+ //Validation bits.
+ header->ValidationBits = ir_to_bitfield(json_object_object_get(header_ir, "validationBits"),
+ 3, CPER_HEADER_VALID_BITFIELD_NAMES);
+
+ //Record length.
+ header->RecordLength = (UINT32)json_object_get_uint64(json_object_object_get(header_ir, "recordLength"));
+
+ //Timestamp, if present.
+ printf("timestamp write.\n");
+ json_object* timestamp = json_object_object_get(header_ir, "timestamp");
+ if (timestamp != NULL)
+ {
+ string_to_timestamp(&header->TimeStamp, json_object_get_string(timestamp));
+ header->TimeStamp.Flag = json_object_get_boolean(json_object_object_get(header_ir, "timestampIsPrecise"));
+ }
+
+ //Various GUIDs.
+ printf("guid write.\n");
+ json_object* platform_id = json_object_object_get(header_ir, "platformID");
+ json_object* partition_id = json_object_object_get(header_ir, "partitionID");
+ if (platform_id != NULL)
+ string_to_guid(&header->PlatformID, json_object_get_string(platform_id));
+ if (partition_id != NULL)
+ string_to_guid(&header->PartitionID, json_object_get_string(partition_id));
+ string_to_guid(&header->CreatorID, json_object_get_string(json_object_object_get(header_ir, "creatorID")));
+
+ //Notification type.
+ printf("notif type write.\n");
+ json_object* notification_type = json_object_object_get(header_ir, "notificationType");
+ string_to_guid(&header->NotificationType, json_object_get_string(json_object_object_get(notification_type, "guid")));
+
+ //Record ID, persistence info.
+ header->RecordID = json_object_get_uint64(json_object_object_get(header_ir, "recordID"));
+ header->PersistenceInfo = json_object_get_uint64(json_object_object_get(header_ir, "persistenceInfo"));
+
+ //Flags.
+ printf("flag write.\n");
+ json_object* flags = json_object_object_get(header_ir, "flags");
+ header->Flags = (UINT32)json_object_get_uint64(json_object_object_get(flags, "value"));
}
\ No newline at end of file