/* auto-generated, do not modify */
#include "config.h"

#include "fu-edid-struct.h"
#include "fu-byte-array.h"
#include "fu-mem-private.h"
#include "fu-string.h"

#ifdef G_LOG_DOMAIN
  #undef G_LOG_DOMAIN
#endif
#define G_LOG_DOMAIN "FuStruct"

static const gchar *
fu_edid_descriptor_tag_to_string(FuEdidDescriptorTag val)
{
    if (val == FU_EDID_DESCRIPTOR_TAG_DISPLAY_PRODUCT_SERIAL_NUMBER)
        return "display-product-serial-number";
    if (val == FU_EDID_DESCRIPTOR_TAG_ALPHANUMERIC_DATA_STRING)
        return "alphanumeric-data-string";
    if (val == FU_EDID_DESCRIPTOR_TAG_DISPLAY_RANGE_LIMITS)
        return "display-range-limits";
    if (val == FU_EDID_DESCRIPTOR_TAG_DISPLAY_PRODUCT_NAME)
        return "display-product-name";
    if (val == FU_EDID_DESCRIPTOR_TAG_COLOR_POINT_DATA)
        return "color-point-data";
    if (val == FU_EDID_DESCRIPTOR_TAG_STANDARD_TIMING_IDENTIFICATIONS)
        return "standard-timing-identifications";
    if (val == FU_EDID_DESCRIPTOR_TAG_DISPLAY_COLOR_MANAGEMENT_DATA)
        return "display-color-management-data";
    if (val == FU_EDID_DESCRIPTOR_TAG_CVT_TIMING_CODES)
        return "cvt-timing-codes";
    if (val == FU_EDID_DESCRIPTOR_TAG_ESTABLISHED_TIMINGS)
        return "established-timings";
    if (val == FU_EDID_DESCRIPTOR_TAG_DUMMY_DESCRIPTOR)
        return "dummy-descriptor";
    return NULL;
}
/* getters */
/**
 * fu_struct_edid_descriptor_get_kind: (skip):
 **/
guint16
fu_struct_edid_descriptor_get_kind(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return fu_memread_uint16(st->data + 0, G_LITTLE_ENDIAN);
}
/**
 * fu_struct_edid_descriptor_get_subkind: (skip):
 **/
guint8
fu_struct_edid_descriptor_get_subkind(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return st->data[2];
}
/**
 * fu_struct_edid_descriptor_get_tag: (skip):
 **/
FuEdidDescriptorTag
fu_struct_edid_descriptor_get_tag(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return st->data[3];
}
/**
 * fu_struct_edid_descriptor_get_data: (skip):
 **/
const guint8 *
fu_struct_edid_descriptor_get_data(const GByteArray *st, gsize *bufsz)
{
    g_return_val_if_fail(st != NULL, NULL);
    if (bufsz != NULL)
        *bufsz = 13;
    return st->data + 5;
}

/* setters */
/**
 * fu_struct_edid_descriptor_set_kind: (skip):
 **/
void
fu_struct_edid_descriptor_set_kind(GByteArray *st, guint16 value)
{
    g_return_if_fail(st != NULL);
    fu_memwrite_uint16(st->data + 0, value, G_LITTLE_ENDIAN);
}
/**
 * fu_struct_edid_descriptor_set_subkind: (skip):
 **/
void
fu_struct_edid_descriptor_set_subkind(GByteArray *st, guint8 value)
{
    g_return_if_fail(st != NULL);
    st->data[2] = value;
}
/**
 * fu_struct_edid_descriptor_set_tag: (skip):
 **/
void
fu_struct_edid_descriptor_set_tag(GByteArray *st, FuEdidDescriptorTag value)
{
    g_return_if_fail(st != NULL);
    st->data[3] = value;
}
/**
 * fu_struct_edid_descriptor_set_data: (skip):
 **/
gboolean
fu_struct_edid_descriptor_set_data(GByteArray *st, const guint8 *buf, gsize bufsz, GError **error)
{
    g_return_val_if_fail(st != NULL, FALSE);
    g_return_val_if_fail(buf != NULL, FALSE);
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
    return fu_memcpy_safe(st->data, st->len, 5, buf, bufsz, 0x0, bufsz, error);
}
/**
 * fu_struct_edid_descriptor_new: (skip):
 **/
GByteArray *
fu_struct_edid_descriptor_new(void)
{
    GByteArray *st = g_byte_array_sized_new(18);
    fu_byte_array_set_size(st, 18, 0x0);
    return st;
}
/**
 * fu_struct_edid_descriptor_to_string: (skip):
 **/
static gchar *
fu_struct_edid_descriptor_to_string(const GByteArray *st)
{
    g_autoptr(GString) str = g_string_new("EdidDescriptor:\n");
    g_return_val_if_fail(st != NULL, NULL);
    g_string_append_printf(str, "  kind: 0x%x\n",
                           (guint) fu_struct_edid_descriptor_get_kind(st));
    g_string_append_printf(str, "  subkind: 0x%x\n",
                           (guint) fu_struct_edid_descriptor_get_subkind(st));
    {
        const gchar *tmp = fu_edid_descriptor_tag_to_string(fu_struct_edid_descriptor_get_tag(st));
        if (tmp != NULL) {
            g_string_append_printf(str, "  tag: 0x%x [%s]\n", (guint) fu_struct_edid_descriptor_get_tag(st), tmp);
        } else {
            g_string_append_printf(str, "  tag: 0x%x\n", (guint) fu_struct_edid_descriptor_get_tag(st));
        }
    }
    {
        gsize bufsz = 0;
        const guint8 *buf = fu_struct_edid_descriptor_get_data(st, &bufsz);
        g_autoptr(GString) tmp = g_string_new(NULL);
        for (gsize i = 0; i < bufsz; i++)
            g_string_append_printf(tmp, "%02X", buf[i]);
        g_string_append_printf(str, "  data: 0x%s\n", tmp->str);
    }
    if (str->len > 0)
        g_string_set_size(str, str->len - 1);
    return g_string_free(g_steal_pointer(&str), FALSE);
}
/**
 * fu_struct_edid_descriptor_parse: (skip):
 **/
static GByteArray *
fu_struct_edid_descriptor_parse(const guint8 *buf, gsize bufsz, gsize offset, GError **error)
{
    g_autoptr(GByteArray) st = g_byte_array_new();
    g_autofree gchar *str = NULL;
    g_return_val_if_fail(buf != NULL, NULL);
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
    if (!fu_memchk_read(bufsz, offset, 18, error)) {
        g_prefix_error(error, "invalid struct EdidDescriptor: ");
        return NULL;
    }
    g_byte_array_append(st, buf + offset, 18);
    str = fu_struct_edid_descriptor_to_string(st);
    g_debug("%s", str);
    return g_steal_pointer(&st);
}
/**
 * fu_struct_edid_descriptor_parse_bytes: (skip):
 **/
GByteArray *
fu_struct_edid_descriptor_parse_bytes(GBytes *blob, gsize offset, GError **error)
{
    gsize bufsz = 0;
    const guint8 *buf = g_bytes_get_data(blob, &bufsz);
    return fu_struct_edid_descriptor_parse(buf, bufsz, offset, error);
}
/* getters */
/**
 * fu_struct_edid_get_manufacturer_name: (skip):
 **/
const guint8 *
fu_struct_edid_get_manufacturer_name(const GByteArray *st, gsize *bufsz)
{
    g_return_val_if_fail(st != NULL, NULL);
    if (bufsz != NULL)
        *bufsz = 2;
    return st->data + 8;
}
/**
 * fu_struct_edid_get_product_code: (skip):
 **/
guint16
fu_struct_edid_get_product_code(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return fu_memread_uint16(st->data + 10, G_LITTLE_ENDIAN);
}
/**
 * fu_struct_edid_get_serial_number: (skip):
 **/
guint32
fu_struct_edid_get_serial_number(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return fu_memread_uint32(st->data + 12, G_LITTLE_ENDIAN);
}
/**
 * fu_struct_edid_get_week_of_manufacture: (skip):
 **/
guint8
fu_struct_edid_get_week_of_manufacture(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return st->data[16];
}
/**
 * fu_struct_edid_get_year_of_manufacture: (skip):
 **/
guint8
fu_struct_edid_get_year_of_manufacture(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return st->data[17];
}
/**
 * fu_struct_edid_get_edid_version_number: (skip):
 **/
static guint8
fu_struct_edid_get_edid_version_number(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return st->data[18];
}
/**
 * fu_struct_edid_get_revision_number: (skip):
 **/
guint8
fu_struct_edid_get_revision_number(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return st->data[19];
}
/**
 * fu_struct_edid_get_data_blocks: (skip):
 **/
const guint8 *
fu_struct_edid_get_data_blocks(const GByteArray *st, gsize *bufsz)
{
    g_return_val_if_fail(st != NULL, NULL);
    if (bufsz != NULL)
        *bufsz = 72;
    return st->data + 54;
}
/**
 * fu_struct_edid_get_extension_block_count: (skip):
 **/
guint8
fu_struct_edid_get_extension_block_count(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return st->data[126];
}
/**
 * fu_struct_edid_get_checksum: (skip):
 **/
guint8
fu_struct_edid_get_checksum(const GByteArray *st)
{
    g_return_val_if_fail(st != NULL, 0x0);
    return st->data[127];
}

/* setters */
/**
 * fu_struct_edid_set_manufacturer_name: (skip):
 **/
gboolean
fu_struct_edid_set_manufacturer_name(GByteArray *st, const guint8 *buf, gsize bufsz, GError **error)
{
    g_return_val_if_fail(st != NULL, FALSE);
    g_return_val_if_fail(buf != NULL, FALSE);
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
    return fu_memcpy_safe(st->data, st->len, 8, buf, bufsz, 0x0, bufsz, error);
}
/**
 * fu_struct_edid_set_product_code: (skip):
 **/
void
fu_struct_edid_set_product_code(GByteArray *st, guint16 value)
{
    g_return_if_fail(st != NULL);
    fu_memwrite_uint16(st->data + 10, value, G_LITTLE_ENDIAN);
}
/**
 * fu_struct_edid_set_serial_number: (skip):
 **/
void
fu_struct_edid_set_serial_number(GByteArray *st, guint32 value)
{
    g_return_if_fail(st != NULL);
    fu_memwrite_uint32(st->data + 12, value, G_LITTLE_ENDIAN);
}
/**
 * fu_struct_edid_set_week_of_manufacture: (skip):
 **/
void
fu_struct_edid_set_week_of_manufacture(GByteArray *st, guint8 value)
{
    g_return_if_fail(st != NULL);
    st->data[16] = value;
}
/**
 * fu_struct_edid_set_year_of_manufacture: (skip):
 **/
void
fu_struct_edid_set_year_of_manufacture(GByteArray *st, guint8 value)
{
    g_return_if_fail(st != NULL);
    st->data[17] = value;
}
/**
 * fu_struct_edid_set_edid_version_number: (skip):
 **/
static void
fu_struct_edid_set_edid_version_number(GByteArray *st, guint8 value)
{
    g_return_if_fail(st != NULL);
    st->data[18] = value;
}
/**
 * fu_struct_edid_set_revision_number: (skip):
 **/
void
fu_struct_edid_set_revision_number(GByteArray *st, guint8 value)
{
    g_return_if_fail(st != NULL);
    st->data[19] = value;
}
/**
 * fu_struct_edid_set_data_blocks: (skip):
 **/
gboolean
fu_struct_edid_set_data_blocks(GByteArray *st, const guint8 *buf, gsize bufsz, GError **error)
{
    g_return_val_if_fail(st != NULL, FALSE);
    g_return_val_if_fail(buf != NULL, FALSE);
    g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
    return fu_memcpy_safe(st->data, st->len, 54, buf, bufsz, 0x0, bufsz, error);
}
/**
 * fu_struct_edid_set_extension_block_count: (skip):
 **/
void
fu_struct_edid_set_extension_block_count(GByteArray *st, guint8 value)
{
    g_return_if_fail(st != NULL);
    st->data[126] = value;
}
/**
 * fu_struct_edid_set_checksum: (skip):
 **/
void
fu_struct_edid_set_checksum(GByteArray *st, guint8 value)
{
    g_return_if_fail(st != NULL);
    st->data[127] = value;
}
/**
 * fu_struct_edid_new: (skip):
 **/
GByteArray *
fu_struct_edid_new(void)
{
    GByteArray *st = g_byte_array_sized_new(128);
    fu_byte_array_set_size(st, 128, 0x0);
    memcpy(st->data + 0x0, "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", 8);
    fu_struct_edid_set_edid_version_number(st, 0x1);
    fu_struct_edid_set_revision_number(st, 0x3);
    return st;
}
/**
 * fu_struct_edid_to_string: (skip):
 **/
static gchar *
fu_struct_edid_to_string(const GByteArray *st)
{
    g_autoptr(GString) str = g_string_new("Edid:\n");
    g_return_val_if_fail(st != NULL, NULL);
    {
        gsize bufsz = 0;
        const guint8 *buf = fu_struct_edid_get_manufacturer_name(st, &bufsz);
        g_autoptr(GString) tmp = g_string_new(NULL);
        for (gsize i = 0; i < bufsz; i++)
            g_string_append_printf(tmp, "%02X", buf[i]);
        g_string_append_printf(str, "  manufacturer_name: 0x%s\n", tmp->str);
    }
    g_string_append_printf(str, "  product_code: 0x%x\n",
                           (guint) fu_struct_edid_get_product_code(st));
    g_string_append_printf(str, "  serial_number: 0x%x\n",
                           (guint) fu_struct_edid_get_serial_number(st));
    g_string_append_printf(str, "  week_of_manufacture: 0x%x\n",
                           (guint) fu_struct_edid_get_week_of_manufacture(st));
    g_string_append_printf(str, "  year_of_manufacture: 0x%x\n",
                           (guint) fu_struct_edid_get_year_of_manufacture(st));
    g_string_append_printf(str, "  revision_number: 0x%x\n",
                           (guint) fu_struct_edid_get_revision_number(st));
    {
        gsize bufsz = 0;
        const guint8 *buf = fu_struct_edid_get_data_blocks(st, &bufsz);
        g_autoptr(GString) tmp = g_string_new(NULL);
        for (gsize i = 0; i < bufsz; i++)
            g_string_append_printf(tmp, "%02X", buf[i]);
        g_string_append_printf(str, "  data_blocks: 0x%s\n", tmp->str);
    }
    g_string_append_printf(str, "  extension_block_count: 0x%x\n",
                           (guint) fu_struct_edid_get_extension_block_count(st));
    g_string_append_printf(str, "  checksum: 0x%x\n",
                           (guint) fu_struct_edid_get_checksum(st));
    if (str->len > 0)
        g_string_set_size(str, str->len - 1);
    return g_string_free(g_steal_pointer(&str), FALSE);
}
/**
 * fu_struct_edid_parse: (skip):
 **/
static GByteArray *
fu_struct_edid_parse(const guint8 *buf, gsize bufsz, gsize offset, GError **error)
{
    g_autoptr(GByteArray) st = g_byte_array_new();
    g_autofree gchar *str = NULL;
    g_return_val_if_fail(buf != NULL, NULL);
    g_return_val_if_fail(error == NULL || *error == NULL, NULL);
    if (!fu_memchk_read(bufsz, offset, 128, error)) {
        g_prefix_error(error, "invalid struct Edid: ");
        return NULL;
    }
    g_byte_array_append(st, buf + offset, 128);
    if (memcmp(st->data + 0, "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", 8) != 0) {
        g_set_error_literal(error,
                            G_IO_ERROR,
                            G_IO_ERROR_INVALID_DATA,
                            "constant Edid.header was not valid, expected \x00\xFF\xFF\xFF\xFF\xFF\xFF\x00");
        return NULL;
    }
    if (fu_struct_edid_get_edid_version_number(st) != 0x1) {
        g_set_error_literal(error,
                            G_IO_ERROR,
                            G_IO_ERROR_INVALID_DATA,
                            "constant Edid.edid_version_number was not valid, expected 0x1");
        return NULL;
    }
    str = fu_struct_edid_to_string(st);
    g_debug("%s", str);
    return g_steal_pointer(&st);
}
/**
 * fu_struct_edid_parse_bytes: (skip):
 **/
GByteArray *
fu_struct_edid_parse_bytes(GBytes *blob, gsize offset, GError **error)
{
    gsize bufsz = 0;
    const guint8 *buf = g_bytes_get_data(blob, &bufsz);
    return fu_struct_edid_parse(buf, bufsz, offset, error);
}
